It’s good to be back. For a start, I thought that I would write an update to some of my previous posts, starting with the installation of Redmine.

We will be installing the latest version of Redmine (version 4.2.1) at the time of writing on Ubuntu Server 20.04, with Apache 2 and Phusion Passenger as the web server and application server respectively, and MariaDB (version 10.6) as the relational database.

We will install the above components step by step, then do a final integration at the end.


With the emergence of cloud computing, there has been a rise of several software project management solutions that are available to assist developers manage and keep track of their code changes. Many are offered as SaaS solutions such as Github, Gitlab, Bitbucket, Azure Devops and AWS CodeDeploy (just to name a few).

Even with all the above SaaS offerings, for individuals or companies that need a higher degree of control of their applications, or due to regulatory reasons need to have their servers operated in house, Redmine is still a good solution for managing code changes and hosting repositories. It has a minimalist interface, therefore easy enough for a typical software engineer to understand, and also quite customizable due to its open source nature.

For more details on the features of Redmine, check out the Redmine site here.

Step 1: Install Redmine pre-requisites

NB: Unless specified, run all the following commands on the bash prompt of your VPS/Dedicated Server.

(Optional) Update your Geographic Area

Redmine will use the local timezone as defined in your geographic area) and set the timezone on your server:

sudo dpkg-reconfigure tzdata

Substitute the values in square brackets with your own respective values:

Geographic Area: [Your Geographic Area e.g. Africa]

Time zone: [Your City e.g. Nairobi]

Install and Configure MariaDB

First off, we shall start by installing MariaDB server. There are a few ways we can do this, but in order to install the latest version (10.6) at the time of writing, we will have to add an external repository that is managed by the MariaDB team.

Add the MariaDB GPG Signing keys

sudo apt-key adv --fetch-keys ''

Add the Ubuntu repository for MariaDB 10.6

sudo add-apt-repository "deb [arch=amd64,arm64,ppc64el] $(lsb_release -cs) main"

Update the local repo cache

sudo apt update

Install MariaDB 10.6

sudo apt install -y mariadb-server

Secure MariaDB

It is strongly recommended securing MariaDB (or any other relational DBMS) post install, as the default settings have plenty of security holes. Conveniently, MariaDB comes with a custom command for enhancing its security which is as follows:

sudo mysql_secure_installation

Then answer the prompts as follows:

Enter current password for root (enter for none): (Press enter here so as to enter a strong password in the next prompt)

Switch to unix_socket authentication [Y/n] y

Change the root password? [Y/n] y (You will be prompted to enter and confirm your new MariaDB password. Remember to enter a strong password here)

Remove anonymous users? [Y/n] y

Disallow root login remotely? [Y/n] y

Remove test database and access to it? [Y/n] y

Reload privilege tables now? [Y/n] y

If all goes well you should see the following printed to your console:

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

Install Ruby, Apache and Phusion Passenger

Apache is arguably the world’s most popular web server. It is also quite commonly used to serve Redmine installations. Since Redmine is built in Ruby on Rails, we will also have to have ruby installed on the server. We will use the version provided by Brightbox, as I have found they have upto date ruby versions, plus they are more convenient to install. We will have to install at least ruby version 2.7.2, which is the minimum version required for Redmine 4.2.

Phusion Passenger is an application server built primarily to serve ruby on rails applications, and comes with runtimes that support both Apache and Nginx. In our case, we will be installing the runtime for Apache2. I have adapted these commmands from the Phusion Passenger docs available here.

Additional packages we will have to install include:

  • imagemagick - required for the correct display of gantt charts in redmine

  • libmysqlclient-dev - required for the compilation of the mysql2 ruby gem that redmine uses

  • build-essential - required for the compilation and building of some ruby gems used by redmine e.g racc, nokogiri, nio4r, websocket-driver 0.7.5. Bundler builds then installs them using native extensions, and displays a message such as the following:

Fetching websocket-driver 0.7.5
Installing websocket-driver 0.7.5 with native extensions

Add the Ruby Brightbox PPA

sudo add-apt-repository ppa:brightbox/ruby-ng

Add the Passenger GPG keys and repository

sudo apt-key adv --keyserver hkp:// --recv-keys 561F9B9CAC40B2F7

sudo sh -c "echo deb $(lsb_release -cs) main > /etc/apt/sources.list.d/passenger.list" 

Fetch the latest changes from the online repository

sudo apt-get update

Install apache, ruby, passenger and additional packages

sudo apt-get install -y ruby2.7 ruby2.7-dev ruby-switch libapache2-mod-passenger apache2 libmysqlclient-dev build-essential

This will take some time depending on the speed of your internet connection.

Validate the Ruby Version Installed

ruby --version

You should see printed to the console:

ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux-gnu]

Enable the passenger apache module

sudo a2enmod passenger

You should see printed to the console:

Module passenger already enabled

Validate the passenger installation

sudo /usr/bin/passenger-config validate-install

You should see the following printed to the console. When asked to choose what to validate, select Passenger itself.

What would you like to validate?
Use <space> to select.
If the menu doesn't display correctly, press '!'

 ‣ ⬢  Passenger itself
   ⬡  Apache


 * Checking whether this Passenger install is in PATH... ✓
 * Checking whether there are no other Passenger installations... ✓

Everything looks good. :-)

Validate the installation of apache

apachectl -v

You should see:

Server version: Apache/2.4.41 (Ubuntu)
Server built:   2021-10-14T16:24:43

Step 2: Create the MariaDB Redmine user

Login to the MariaDB console:

mysql -u root -p

You will then be prompted to enter the root password which you created earlier. On a successful login you should see printed to the console the following:

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 31
Server version: 10.6.4-MariaDB-1:10.6.4+maria~focal binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

Once logged in, run the following SQL commands on the MariaDB console:

NB: Modify the values in square brackets with your preferred values. Please keep track of them as they will be essential later on in the installation process.

MariaDB [(none)]> create database redmine_production;
MariaDB [(none)]> create user 'redmine_user'@'localhost' identified by 'your_redmine_password';
MariaDB [(none)]> grant all privileges on redmine_production.* to 'redmine_user'@'localhost' identified by 'your_redmine_password';

Quit the MariaDB console:

MariaDB [(none)]> \q

Step 4: Install Redmine

First, we will download the Redmine source code to the /tmp directory, then install it in the /usr/share/redmine directory. I will install Redmine version 4.2.3, the latest at the time of writing.

Go to the /tmp directory

cd /tmp

Download the Redmine source code:

curl -O

Extract it:

tar -xvvf redmine-4.2.3.tar.gz

Move the extracted code to /usr/share/redmine directory

sudo mv -v redmine-4.2.3 /usr/share/redmine

Switch to the /usr/share/redmine directory:

cd /usr/share/redmine/

Install bundler (a ruby dependency manager). We will have to install it as a super user since the ruby gems directory is owned by root:

sudo gem install bundler

Create a database config file from the provided template:

cp -v config/database.yml.example  config/database.yml

I will be using vim as my preferred command line text editor. You can use any alternative command line text editor, such as nano or emacs.

vi config/database.yml

Set the production YAML block as follows:

  adapter: mysql2
  database: redmine_production
  host: localhost
  username: redmine_user
  password: "your_redmine_password"
  encoding: utf8

Save an close vim by entering :wq! on your terminal.

Install Redmine dependencies

First, configure bundler to omit installing any of the gems used in test and development environments. Also, bundler should skip installing unnecessary gems such as postgresql and sqlite, which we aren’t using in this tutorial.

bundle config set --local without 'development test postgresql sqlite'

Install the Redmine ruby gems:

bundle install --without development test postgresql sqlite

Create a secret token to secure the HTML forms in Redmine against CSRF attacks:

bundle exec rails generate_secret_token

Create the Redmine database tables:

bundle exec rails db:migrate RAILS_ENV=production

Seed the database with default data, and set the language to be used to English (you can change this if English isn’t your preferred language).

bundle exec rails redmine:load_default_data RAILS_ENV=production REDMINE_LANG=en

Step 5: Integrate Redmine with Apache 2

As a security precaution, rename (or delete) the default Apache 2 index file before continuing:

sudo mv -v /var/www/html/index.html /var/www/html/index.html.bak

Remove the Apache 2 server signatures (that are usually listed on the default apache error pages). Edit the main Apache configuration file:

sudo vi /etc/apache2/apache2.conf

Add the following to the bottom of the file:

ServerTokens Prod
ServerSignature Off

Save the file and close vim then restart Apache:

sudo systemctl restart apache2

Create a Redmine Apache Virtual Host file (vhost):

sudo vi /etc/apache2/sites-available/redmine.conf

Add the following content to the vhost:

NB: Substitute your_domain with your own domain e.g.

<VirtualHost *:80>
    ServerName www.your_domain
    ServerAlias your_domain
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    RailsEnv  production

    Alias /redmine /usr/share/redmine/public
    <Location /redmine>
      PassengerBaseURI /redmine
      PassengerAppRoot /usr/share/redmine

    <Directory /usr/share/redmine/public>
      Allow from all
      Options -MultiViews
      Require all granted

    <Directory /var/www/html>
        Allow from all
        Options -Indexes -MultiViews
        Require all granted

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

Check if your configuration file’s syntax is sound:

sudo apachectl configtest

If all is well, you should see:

Syntax OK

Disable the default Apache vhost:

sudo a2dissite 000-default

Enable the newly created Redmine vhost:

sudo a2ensite redmine

Reload Apache:

sudo systemctl reload apache2

On a web browser go to your_domain/redmine.

Redmine Home

Click on the ‘Sign in’ link on the top-right.

Redmine Login

Use the credentials admin/admin to login.

NB: You will thereafter be prompted to enter a new password. Please enter a more secure/strong password for the admin user.