How to Install Redmine on Ubuntu 16.04 with Nginx & Unicorn
Redmine is a open source project management tool written in Ruby on Rails. It’s been around since 2006 and has a large community of users. If you’re unfamiliar with it, there’s an online demo available.
For users who have never used the Ruby on Rails framework, the installation of Redmine can be a bit confusing. So, I made this guide to simplify the installation process for people.
Guide requirements
- Ubuntu (with root access)
- Nginx
- MySQL or PostgreSQL
Install Ruby on Rails
Download the latest version of Ruby on Rails
curl -kLo ~/ruby-2.4.2.tar.gz http://ftp.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.tar.gz
tar -xzf ~/ruby-2.4.2.tar.gz
cd ~/ruby-2.4.2/
./configure
make
make install
ruby -v
Install dependencies
Before you can install Redmine, you’ll first to need to make sure that your system has the required dependencies.
apt-get install curl git libssl-dev libreadline-dev zlib1g-dev imagemagick libmagickwand-dev
Redmine uses a package manager for Ruby gems called Bundler
gem install bundler
If you’re using MySQL, make sure you have the MySQL client installed
apt-get install libmysqlclient-dev
Or if you’re using PostgreSQL, make sure that you have the PostgreSQL client installed
apt-get install postgresql-client
Create Redmine user
For security reasons, it’s recommended that you create a new user to run Redmine under.
adduser --disabled-login --gecos 'Redmine Project Management' redmine
su - redmine
Create the database
For MySQL:
CREATE DATABASE redmine CHARACTER SET utf8;
CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'my_password';
GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost';
For PostgreSQL:
CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'my_password' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;
Install Redmine
Clone the latest version of Redmine from its Git repository
mkdir ~/redmine
git clone git://github.com/redmine/redmine.git ~/redmine
Modify database config file
Copy config/database.yml.example to config/database.yml and edit it with your server’s settings
cp ~/redmine/config/database.yml.example ~/redmine/config/database.yml
nano ~/redmine/config/database.yml
If you’re using MySQL then edit
production:
adapter: mysql2
database: redmine
host: localhost
username: redmine
password: my_password
If you’re using PostgreSQL then edit
production:
adapter: postgresql
database: <your_database_name>
host: <postgres_host>
username: <postgres_user>
password: <postgres_user_password>
encoding: utf8
schema_search_path: <database_schema> (default - public)
Install gems for Redmine
As you’ll be using Unicorn as Redmine’s web server , you’ll need to add gem “unicorn” to Gemfile
echo "gem \"unicorn\"" >> ~/redmine/Gemfile
Now we can install the required gems
cd ~/redmine
bundle install --without development test
Generate secret token
Generate a secret token for Rails to encrypt cookies
bundle exec rake generate_secret_token
Prepare the database
Create database structure and populate it
RAILS_ENV=production bundle exec rake db:migrate
Set permissions
mkdir -p tmp/pids tmp/sockets public/plugin_assets
chmod -R 755 files log tmp public/plugin_assets
Configure Unicorn
Download Unicorn config file
curl -kLo ~/redmine/config/unicorn.rb https://raw.githubusercontent.com/defunkt/unicorn/master/examples/unicorn.conf.rb
Make the following changes to unicorn.rb
nano ~/redmine/config/unicorn.rb
- working directory: /home/redmine/redmine
- socket: /home/redmine/redmine/tmp/sockets/unicorn.sock
- pid: /home/redmine/redmine/tmp/pids/unicorn.pid
- log (change stderr_path and stdout_path) to have the path: /home/redmine/redmine/log
Configure Nginx
upstream unicorn_server {
# This is the socket we configured in unicorn.rb
server unix:/home/redmine/redmine/tmp/sockets/unicorn.sock
fail_timeout=0;
}
server {
listen 80;
server_name redmine.yoursite.com;
access_log /var/log/nginx/yoursite.access.log;
error_log /var/log/nginx/yoursite.error.log;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://unicorn_server;
break;
}
}
}
Reload Nginx’s config
service nginx reload
Test installation
At this point, you should be able to launch Unicorn and test your Redmine installation out.
unicorn_rails -E production -c /home/redmine/redmine/config/unicorn.rb
If there are no errors on your screen, go ahead and visit Redmine in your browser to confirm that your installation is working. You can hit Ctrl + C to kill Unicorn when you’re done.
Default login information:
- Login: admin
- Password: admin
Add Redmine as a service
Now create a file in /etc/init.d/ and paste the following script to it
nano /etc/init.d/redmine
#!/bin/bash
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
BUNDLE=/usr/local/bin/bundle
UNICORN=/usr/local/bin/unicorn_rails
KILL=/bin/kill
APP_ROOT=/home/redmine/redmine
PID=/home/redmine/redmine/tmp/pids/unicorn.pid
OLD_PID=/home/redmine/redmine/tmp/pids/unicorn.pid.oldbin
CONF=/home/redmine/redmine/config/unicorn.rb
USER=redmine
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
case "$1" in
start)
echo "Starting unicorn rails app ..."
su - $USER -c "cd $APP_ROOT; $BUNDLE exec unicorn_rails -D -E production -c $CONF" &&
echo "Unicorn rails app started!" ||
echo "Unicorn rails app failed"
;;
stop)
echo "Stoping unicorn rails app ..."
sig QUIT && exit 0
echo "Not running"
;;
restart)
if [ -f $PID ];
then
echo "Unicorn PID $PID exists"
/bin/kill -s USR2 `/bin/cat $PID`
sleep 30
echo "Old PID $OLD_PID"
/bin/kill -9 `/bin/cat $OLD_PID`
else
echo "Unicorn rails app is not running. Lets start it up!"
$0 start
fi
;;
status)
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
;;
esac
Set permissions and activate service on server startup
chmod 755 /etc/init.d/redmine
update-rc.d redmine defaults
Start Redmine service
service redmine start
Congratulations! You’ve successfully installed the Redmine project management tool. Did you have trouble during a certain step or a question that wasn’t addressed in this guide? Let us know in the comment section below!
Backups
You should create daily backups of your Redmine data. You’ll need to back the data up from two locations:
- data (stored in the Redmine MySQL or PostgreSQL database)
- file attachments (stored in the ~/redmine/files directory)
# Database
/usr/bin/mysqldump -u <username> -p<password> <redmine_database> | gzip > /path/to/backup/db/redmine_`date +%y_%m_%d`.gz
Troubleshooting
MySQL error during database migration
If you get an error about an invalid default value, this is because sql_mode is set incorrectly.
-- create_table(:email_addresses, {:id=>:integer})
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Invalid default value for 'updated_on': CREATE TABLE `email_addresses` (`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, `user_id` int NOT NULL, `address` varchar(255) NOT NULL, `is_default` tinyint(1) DEFAULT 0 NOT NULL, `notify` tinyint(1) DEFAULT 1 NOT NULL, `created_on` timestamp NOT NULL, `updated_on` timestamp NOT NULL) ENGINE=InnoDB
/home/redmine/redmine/db/migrate/20150113194759_create_email_addresses.rb:3:in `change'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
To view the current value of sql_mode, type:
SHOW VARIABLES LIKE 'sql_mode'
Neither NO_ZERO_IN_DATE or NO_ZERO_DATE should be returned.
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_...
If one of those values is in your sql_mode, then you need to modify your MySQL config file.
nano /etc/mysql/mysql.conf.d/mysqld.cnf
Add the line:
sql_mode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Restart MySQL
service mysql restart