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.
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.
# aptitude install mysql-server
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
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.
# 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.
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.
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
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.
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.
If the Redmine page does not appear, here are some troubleshooting suggestions:
/var/log/nginx/error.log for relevant errors./var/log/thin/redmine.0.log.debug to the Redmine Thin configuration, restart, retry, and re-check the Thin log.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.
At this point Redmine should be ready for use. Inform users, get involved in the Redmine community, and enjoy!
Nikita A Menkovich was kind enough to provide a translation of this article into Russian. His work is much appreciated!
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 ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]