20 April 2016

Redmine, Passenger, and Nginx on Ubuntu

Redmine with Passenger and Nginx on Ubuntu

Have to say this should be easier nowadays, but getting Redmine up and running can still be a maze of twisty little passages, all alike. 

Trying to decide what is a good option and what is not requires a solid knowledge of Linux AND some mad Google-Fu. Cobbled from multiple sources, here is a flexible instructions to get an up to date, robust, secure installation going.
  • Ubuntu 14.04 LTS - a mature Ubuntu version with long term support 
  • MySQL - the database 
  • Ruby - the technology on which Redmine runs, installed using RVM to manage the ruby version and have access to up to date components 
  • Phusion Passenger- the application server in which to run Redmine 
  • Nginx - the web server within which Redmine runs   

MySQL Configuration

Install MySQL. For this step, relying on the Ubuntu packages is fine.
sudo apt-get install -y mysql-server libmysqlclient-dev
For production systems, a separate data disk should be used rather that storing it on the same partition as the root system. This can be changed by modifying the data directory configuration in MySQL: 
/etc/mysql/my.cnf
#datadir = /var/lib/mysql #old location
datadir = /data/mysql # new location
If going down this path, set permissions correctly on your new location: 
chown mysql:mysql /data/mysql
chmod 700 /data/mysql
Update AppArmor, otherwise the mysql process won't start.
sudo vim /etc/apparmor.d/usr.sbin.mysqld 
Restart mysql. 
 service mysql start
Connect to the mysql service (mysql -p) and create the database and provide access to the redmine user:
mysql -p
CREATE DATABASE redmine CHARACTER SET utf8;
CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'yourpassword';
GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost';

Ruby Installation

Many methods exist to install Ruby. Unfortunately, the most convenient using apt-get will leave the system many versions behind, which means many plugins for redmine, and parts of redmine itself, will be unsupported. RVM is a tried and true method and provides clean management of ruby versions. 

For whatever reason, these steps seem to work best as root. 
sudo su - 
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s stable

exit 
Once setup, each user of rvm needs to be added to the rvm group. 
sudo usermod -a -G rvm username
Logout and log back in to complete the installation.
rvm requirements
Now choose a ruby version. As guidance, a 2.0 or higher is recommended. RVM has pre-compiled versions, which make installation seamless.
rvm install 2.2.3
rvm use 2.2.3 --default
Then confirm everything looks correct. 
ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]

Phusion Passenger Installation

Again, many options exist for application containers. Phusion has a Passenger-Nginx combo that is straight-forward to install and configure. It also installs an old version of ruby, but via configuration the package can be pointed to our more recent version.

Details of this installation can be found on the Phusion site.
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
sudo apt-get install nginx-extras passenger

Nginx Configuration 

Nginx has to be pointed to the correct ruby and the correct passenger installation. 

Ensure the passenger is installed correctly and confirm the correct location. This location will be needed for nginx. 
/usr/bin/passenger-config validate-install
passenger-config --root
The result will be something like this:
/usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini
Also, confirm the correct location of the correct ruby.
which passenger-config 
/usr/bin/passenger-config #use this result to perform the next command
/usr/bin/passenger-config --ruby-command
The result will be something like this:
/usr/local/rvm/gems/ruby-2.2.3/wrappers/ruby
Update nginx to point to the correct location. Don't forget semi-colons at the end!
sudo vim /etc/nginx/nginx.conf
# passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini; #old entry
# passenger_ruby /usr/bin/passenger_free_ruby; #old entry
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/local/rvm/gems/ruby-2.2.3/wrappers/ruby;
Restart nginx
sudo service nginx restart  
Enable the www directory. 
sudo mkdir /var/www
sudo chown -R www-data:www-data /var/www
Build out the site - assuming http for now. More configuration will be needed to SSL-ize the system and lock it down. But for now, this will get things correct and running
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.orig
vim /etc/nginx/sites-available/default
 Update the root location and add passenger configuration.
root /data/redmine/redmine/public/; #installation location
passenger_enabled on; #turn on application container
client_max_body_size 10m; # Max attachement size allowed
  
Then to prevent a mess of 404 errors, comment out the location entry. Missing this step results in a special level of redmine 404 hell.
#location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to displaying a 404.
    #try_files $uri $uri/ =404;
#}
The system is almost ready for redmine installation.
 

Create the redmine account

Before doing too much with ruby, create a redmine service account. Note: Ideally the home directory located where redmine is going to be installed - for production systems this should be on a separate partition. 
sudo adduser --system --shell /bin/bash --gecos 'Redmine Administrator' --group --disabled-password --home /data/redmine redminesudo usermod -a -G rvm redmine 
 Give the account sudo privileges (temporarily).
sudo visudo 
redmine    ALL=(ALL)      NOPASSWD:ALL

Welcome to dependency-o-rama 

The ruby add-on dependencies next depends (ha ha get it?) on various ruby pieces needed to install ruby components. A minimal list will look something like this: 
sudo apt-get install -y build-essential imagemagick libmagickwand-dev

Redmine, remember this was the main point of the article?

Whew. Like a hero that doesn't show up until reel 3, redmine is finally on the scene.

Install the latest

Switch to the redmine user and pull down the latest stable release.
sudo su - redmine # should result in being in the redmine installation directory
wget http://www.redmine.org/releases/redmine-3.2.1.tar.gz
tar xvfz redmine-3.2.1.tar.gz
ln -s redmine-3.2.1 redmine
rm redmine-3.2.1.tar.gz

Configure the mysql connection 

Update the production entry with the account connection information.
cd redmine 
cp -pR config/database.yml.example config/database.yml
vim config/database.yml

Adding gems - truly outrageous!

Configure the gems - and avoid doing this as root. As with everything in redmine administration, this should be as that fancy redmine service account:
gem install bundler
bundle install --without development test
If versions and such match these instructions, the bundle install should go clean:
Bundle complete! 30 Gemfile dependencies, 54 gems now installed.
Gems in the groups development and test were not installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.

If versions are different or new features are needed, some iteration may be needed to build and install the gems. This seems to be a "normal" task for ruby administrators. Apply google-fu and iterate. 

Rake magic

Next run the magic rake commands. All magic comes in three. 
bundle exec rake generate_secret_token
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake redmine:load_default_data
Now everything should be ready to start. This is done by restarting nginx. Monitor the following logs to ensure things start clean: 
tail -f /var/log/nginx/error.lo
tail -f  /data/redmine/redmine/log/production.log

Clean up

Congratulations, the redmine site should now be up and available. 

Remove sudo privileges from the redmine account. Move the site to SSL, ideally using the excellent Let's Encrypt service. If I am feeling especially upright, I will add these instructions as well. 


Links of interest 

Plenty of chatter and individual parts here to help troubleshoot and see where much of this has been culled. Enjoy. 

Ways to install ruby on Ubuntu 

http://stackoverflow.com/questions/26595620/how-to-install-ruby-2-1-4-on-ubuntu-14-04
https://gorails.com/setup/ubuntu/14.04
https://www.digitalocean.com/community/tutorials/how-to-install-rails-and-nginx-with-passenger-on-ubuntu
http://stackoverflow.com/questions/5201689/rmagick-gem-install-cant-find-magick-config

Ways to install Nginx and Passenger

https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-passenger-and-nginx-on-ubuntu-14-04
http://www.redmine.org/projects/redmine/wiki/HowTo_configure_Nginx_to_run_Redmine

Troubleshooting Passenger installations 

https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_root
https://www.phusionpassenger.com/library/admin/nginx/troubleshooting/ruby/

https://www.phusionpassenger.com/library/config/nginx/reference/#setting_correct_passenger_ruby_value

Ways to install Redmine 

http://www.redmine.org/projects/redmine/wiki/HowTos
http://www.redmine.org/projects/redmine/wiki/RedmineInstall#fn0
https://blog.rudeotter.com/install-redmine-with-nginx-puma-and-mariadbmysql-on-ubuntu-14-04/
http://www.redminecrm.com/boards/4/topics/448-installing-redmine-2-2-passenger-nginx-rvm-on-ubuntu-12-04
https://nidomiro.de/2015/03/installing-redmine-3-0-on-clean-ubuntu-14-04/

http://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_30x_on_Ubuntu_1404_with_Apache2_Phusion_Passenger_MySQL_Subversion_and_Git_%28Gitolite%29#Installing-Ruby