Installing Redmine with MySQL Thin and Redmine on Debian Squeeze

Posted by kevinoid on Fri 9 Dec 2011 at 08:54

Redmine is a web-based project management system, often called a forge, built using the Ruby on Rails framework. It provides bug/issue tracking, time tracking, wiki pages, gantt charting and calendar, multiple project support, and role-based access control for users to name a few. This article will cover the process of installing Redmine on Debian Squeeze using MySQL for data storage, Thin for serving Ruby, and nginx as the outward-facing server.

A Note on Notation

This article will show shell commands which can be run as a normal (limited) user using the $ prompt and shell commands which must be run as root (super user) using the # prompt. It is recommended to run these commands using sudo or a similar program.

Setup Process

Install MySQL

# aptitude install mysql-server

(Optional) Configure MySQL to Use UTF-8 by Default

Although not required, it is often convenient to set the default character set used by MySQL to be UTF-8, particularly when using a UTF-8 locale outside of MySQL. To configure MySQL to use UTF-8 by default, add the following to /etc/mysql/my.cnf:

[client]
default-character-set	= utf8

[mysql]
default-character-set	= utf8

[mysqld]
default-character-set	= utf8
default-collation	= utf8_unicode_ci
character-set-server	= utf8
collation-server	= utf8_unicode_ci

Create a Redmine Database in MySQL

Regardless of whether MySQL is configured to use UTF-8 by default, the Redmine database must be created with UTF-8. Redmine stores data in the UTF-8 encoding, regardless of the encoding configured in the database, and allowing any other encoding to be specified in MySQL will only cause confusion and subsequent encoding issues. Unfortunately, Redmine is unable to use dbconfig-common to create the database with UTF-8 in Squeeze (See bugs 599140 and 599374). To work around this issue, create the databases before installing Redmine using the following commands:

$ mysql -u root -p
mysql> CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'newpassword';
mysql> CREATE DATABASE redmine_default CHARACTER SET = 'utf8';
mysql> GRANT ALL PRIVILEGES ON redmine_default.* TO 'redmine'@'localhost';

Note that it is possible to use a different username and/or database name. To use a different name, modify the above commands and make sure the debconf priority is set to low (permanently or temporarily by setting the environment variable DEBIAN_PRIORITY=low) when the redmine package is installed.

Install Redmine, Thin, and nginx

# aptitude install redmine redmine-mysql+M thin nginx ssl-cert

In the command above, "+M" is appended to redmine-mysql to mark the package as automatically installed such that if the redmine package is later removed, redmine-mysql will be automatically removed. Also note that the ssl-cert package is optional. It provides an SSL certificate (named ssl-cert-snakeoil.pem) which can be used for HTTPS.

When prompted during the installation, choose yes to use dbconfig-common, choose mysql as the database, and supply the root username and redmine MySQL user passwords when prompted. dbconfig-common will notice that the database already exists and populate it without changing the character set, which will result in all tables having the UTF-8 character set.

Configure Thin

To configure Thin, first create a directory in which to store the log files created by Thin:

# mkdir /var/log/thin
# chmod 755 /var/log/thin

If access to the Thin logs need to be further restricted on the server, this directory may be owned by root:adm and set to mode 2750 to restrict access to users in the adm group.

Next, create the Thin configuration using the following commands:

$ thin config --config /tmp/redmine.yml --chdir /usr/share/redmine \
    --environment production --socket /var/run/redmine/sockets/thin.sock \
    --daemonize --log /var/log/thin/redmine.log --pid /var/run/thin/redmine.pid \
    --user www-data --group www-data --servers 1 --prefix /redmine
# mv /tmp/redmine.yml /etc/thin/redmine.yml
# chown root:root /etc/thin/redmine.yml
# chmod 644 /etc/thin/redmine.yml

Note that --servers can be adjusted based on the expected load and other performance considerations. Also, the --prefix option can be adjusted or omitted to change the URL prefix used to access Redmine. Using /redmine will provide access to Redmine at http://host/redmine, omitting the prefix would provide access at the site root http://host/

Finally, add the Thin logs to the logrotate configuration to archive and compress old logs by creating /etc/logrotate.d/thin with the following content:

/var/log/thin/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                /etc/init.d/thin restart >/dev/null
        endscript
}

If access to the Thin logs is restricted (as noted above), change the create line to create 640 root adm. Also note that the above configuration will cause Thin to restart once daily in order to begin writing to the next log file. This sub-optimal, although it should not have a significant impact. Any suggestions for how to avoid the restart are welcome.

Configure nginx

First, optionally, create a configuration file for proxy options shared by all nginx proxies named /etc/nginx/proxy_opts with the following content:

# Shared options used by all proxies
proxy_set_header        Host $http_host;

# Following headers are not used by Redmine but may be useful for plugins and
# other web applications
proxy_set_header        X-Real-IP $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto $scheme;

# Any other options for all proxies here

Next, create the site configuration file named /etc/nginx/sites-available/redmine with the following content, or integrate the following content into an existing site:

upstream redmine_thin_servers {
	server unix:/var/run/redmine/sockets/thin.0.sock;
	# Add additional copies if using multiple Thin servers
	#server unix:/var/run/redmine/sockets/thin.1.sock;
}

server {

	listen   80; ## listen for ipv4
	listen   [::]:80 default ipv6only=on; ## listen for ipv6

	# Set appropriately for virtual hosting and to use server_name_in_redirect
	server_name  localhost;
	server_name_in_redirect off;

	access_log  /var/log/nginx/localhost.access.log;
	error_log  /var/log/nginx/localhost.error.log;

	# Note: Documentation says proxy_set_header should work in location
	#       block, but testing did not support this statement so it has
	#       been placed here in server block
	include /etc/nginx/proxy_opts;
	proxy_redirect off;

	# Note:  Must match the prefix used in Thin configuration for Redmine
	#        or / if no prefix configured
	location /redmine {
		root   /usr/share/redmine/public;

		error_page 404  404.html;
		error_page 500 502 503 504  500.html;

		# Send sensitive stuff via HTTPS
		# Remove if not using HTTPS
		# Note1:  Change $host to SSL CN if multiple host names used
		# Note2:  Adjust prefix, if different in Thin Redmine config
		rewrite ^/redmine/login(.*) https://$host$request_uri permanent;
		rewrite ^/redmine/my/account(.*) https://$host$request_uri permanent;
		rewrite ^/redmine/my/password(.*) https://$host$request_uri permanent;
		rewrite ^/redmine/admin(.*) https://$host$request_uri permanent;

		try_files $uri/index.html $uri.html $uri @redmine_thin_servers;
	}

	location @redmine_thin_servers {
		proxy_pass http://redmine_thin_servers;
	}
}

# HTTPS server (Should match HTTP server above with a few differences)
# Optional.  Remove rewrite directives above if not using.
server {

	listen   443; ## listen for ipv4
	listen   [::]:443 default ipv6only=on; ## listen for ipv6

	# Set appropriately for virtual hosting and to use server_name_in_redirect
	server_name  localhost;
	server_name_in_redirect off;

	access_log  /var/log/nginx/localhost-ssl.access.log;
	error_log  /var/log/nginx/localhost-ssl.error.log;

	# Note: Documentation says proxy_set_header should work in location
	#       block, but testing did not support this statement so it has
	#       been placed here in server block
	include /etc/nginx/proxy_opts;
	proxy_redirect off;

	# Note:  Adjust ssl_certificate{,_key} to custom SSL cert, if not
	#        using ssl-cert package
	ssl  on;
	ssl_certificate  /etc/ssl/certs/ssl-cert-snakeoil.pem;
	ssl_certificate_key  /etc/ssl/private/ssl-cert-snakeoil.key;

	# Note:  Must match the prefix used in thin configuration for redmine
	#        or / if no prefix configured
	location /redmine {
		root   /usr/share/redmine/public;

		error_page 404  404.html;
		error_page 500 502 503 504  500.html;

		try_files $uri/index.html $uri.html $uri @redmine_thin_servers;
	}

	location @redmine_thin_servers {
		proxy_pass http://redmine_thin_servers;
	}
}

If /etc/nginx/proxy_opts is not desired, simply replace include /etc/nginx/proxy_opts; with the desired options (at least proxy_set_header Host is recommended).

Then, if the above information was not merged into an existing site configuration file, disable the default site and enable the Redmine site using the following commands:

# rm /etc/nginx/sites-enabled/default
# ln -s ../sites-available/redmine /etc/nginx/sites-enabled/redmine

Additional Bugfixes

Currently there is a bug in Redmine (arguably in Ruby or libactionpack-ruby) in Squeeze which causes the user profile page to fail to load. For background see Debian bugs 628899, 629067, and 633305 and fix as you see fit. The fix recommended in this article is to make the changes suggested by Felix Geyer in a comment to bug 629067 by changing line 476 of /usr/lib/ruby/1.8/action_view/helpers/url_helper.rb as indicated.

Restart and Test

Finally, restart Thin and nginx to apply all of the above changes:

# /etc/init.d/thin restart
# /etc/init.d/nginx restart

Then browse to http://localhost/redmine (using the server hostname and prefix configured above). This should present the Redmine landing page. Click "Sign in" and use username admin with password admin to login. Then configure as desired using the Redmine Guide as a reference. Most importantly, set the "Host name and path" option to the URL which will be used by Redmine users because it is detected as the proxy address rather than the outward-facing hostname.

Troubleshooting

If the Redmine page does not appear, here are some troubleshooting suggestions:

  1. Check the nginx error log /var/log/nginx/error.log for relevant errors.
  2. Check the Thin log for errors, /var/log/thin/redmine.0.log.
  3. Add debug to the Redmine Thin configuration, restart, retry, and re-check the Thin log.
  4. Change the Redmine Thin configuration to use an address and port instead of a socket and connect directly to Thin from a web browser to determine if the problem is with Thin or nginx.

Best of luck in diagnosing and solving any problems, and don't hesitate to post them in the comments, or relevant bug trackers, to seek help and to inform others of the problem and any solution.

Enjoy

At this point Redmine should be ready for use. Inform users, get involved in the Redmine community, and enjoy!

Update: Translation Available

Nikita A Menkovich was kind enough to provide a translation of this article into Russian. His work is much appreciated!

 

 


Posted by Anonymous (178.126.xx.xx) on Sat 14 Apr 2012 at 23:54
Thank you for so clear guide. All pages loading well when I did everything as you wrote, but I have only one issue: After clicking "log in" button, after click save in preference, after making any POST request to server.. page is redirected to wrong url like redmine_thin_servers/redmine/settings/edit?tab=repositories. This is how url is looks like when redmine redirect browser after clicking save on settings page.

[ Parent | Reply to this comment ]

Posted by kevinoid (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Sun 15 Apr 2012 at 03:57
[ Send Message ]
Sounds like the Host header is not being passed to Redmine. So either proxy_set_header Host $http_host; is missing from /etc/nginx/proxy_opts or /etc/nginx/proxy_opts is not being included in both the http and https server declarations in the nginx site definition file (either because it is missing or due to a runtime error, such as incorrect permissions). Please double-check your configuration and the nginx logs.

[ Parent | Reply to this comment ]

Posted by Anonymous (178.126.xx.xx) on Sun 15 Apr 2012 at 06:59
yep. you were right. I missed inclusion of proxy params in https section. Thank you very much

[ Parent | Reply to this comment ]

Posted by Anonymous (78.8.xx.xx) on Tue 12 Jun 2012 at 07:36
Is thin better that passenger?

[ Parent | Reply to this comment ]

Posted by Anonymous (98.251.xx.xx) on Fri 7 Dec 2012 at 13:29
Hello,

I'm new to thin and nginx, but it looks like it might be possible to create multiple instances of Redmine using this method? If so, could I kindly request some guidance?

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

Which init system are you using in Debian?






( 1631 votes ~ 7 comments )