How to install redmine on RHEL 8 / CentOS 8 Linux

Redmine is a popular open source project management web application. It supports mayor databases like MySQL and PostgreSQL as backend, and you can also change the frontend to Apache from the WEBrick (recommended for production use) webserver shipped with the installation. In this article we will install the latest Redmine on RHEL 8 / CentOS 8, using PostgreSQL as backend, but we will leave the default WEBrick as frontend, which will serve our tests perfectly.

Do not expect this process to be an easy one, nor error-free. Even following these steps to the letter, some errors will surely happen, the setup seem to handle sudo steps somewhat inconsistently – but the solutions are also included which will guide trough these errors.

In this tutorial you will learn:

  • How to install required operating system packages
  • How to setup the database
  • How to install the Redmine application
  • How to start and login to the application

Configuration page of Redmine.

Configuration page of Redmine on RHEL 8.

Software Requirements and Conventions Used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System RHEL 8 / CentOS 8
Software Redmine 4.0.3, PostgreSQL 10.5
Other Privileged access to your Linux system as root or via the sudo command.
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

How to install redmine on Redhat 8 step by step instructions

Redmine is a Ruby application. For the installation we’ll have to use rubygems and bundler, and compile a lot of dependencies, so it will take a while. We’ll use the Red Hat repositories available after enabling subscription management to solve the operating system dependencies. You can refer to the PostgreSQL installation guide on RHEL8 for the detailed setup of the database in general, in this article we’ll cover only the steps needed for Redmine. If the database setup is new, don’t forget to complete the initdb step in the mentioned guide, or the startup of the database will fail.

  1. We’ll create a user who will be the owner of the application, and we’ll give it temporary sudo access. We can revoke this access once the installation is complete.
    # useradd redmine

    We have to set a password for the new user, which we will use when using sudo:

    # passwd redmine

    On RHEL based distributions, there is a wheel user group, who is allowed to use sudo to run privileged commands. To check that this group is set up as sudoer, we can grep the /etc/sudoers file:

    # grep "%wheel" /etc/sudoers
    %wheel  ALL=(ALL)       ALL
    # %wheel        ALL=(ALL)       NOPASSWD: ALL

    The second line with the NOPASSWD option is commented out, which will suit our needs. With the above configuration in place, all we need to do is add the redmine user to the wheel group:

    # usermod -a -G wheel redmine
  2. To install the packages the operating system will provide, we’ll use dnf:
    # dnf install kernel-devel kernel-headers gcc postgresql-devel ruby ruby-devel rubygems

  3. To obtain the application, visit the the official download site (which is running on Redmine). From here we can download the compressed tarball with wget to the target system:
    # wget -O /opt/redmine-4.0.3.tar.gz

    As the above command suggests, we’ll install the application under the /opt directory. We’ll switch to this directory, and extract the archive:

    # cd /opt
    # tar -xzf redmine-4.0.3.tar.gz

    Optionally we can also create a symlink for easier access – this way we don’t need to remember the exact version:

    # ln -s /opt/redmine-4.0.3 /opt/redmine

    Now we can set the redmine user as the owner of the extracted directory hierarchy, recursively:

    # chown -R redmine:redmine /opt/redmine*
  4. To setup the database for the application’s connection, we have to start it up if it isn’t running already:
    # systemctl start postgresql
  5. We’ll need to create an empty database where the application will store it’s data. To do so, we’ll switch to the postgres operating system user created by default at database installation:
    # su - postgres

    We’ll login to psql as the superuser of the database:

    $ psql
    psql (10.5)
    Type "help" for help.

    We’ll create a role that will be used by the application (note down the username and password):


    We also create a new database with the owner created above:

    postgres=# CREATE DATABASE rmdb WITH ENCODING='UTF8' OWNER=redmine;

    We’ll need the username, password, encoding and database name in a later step.

  6. Now that the user is set up, we need to allow login for it on the database server. The redmine user will connect locally, so we add the following line to the pg_hba.conf file, located by default at /var/lib/pgsql/data by default on RHEL based distributions:
    host    rmdb        redmine             md5

    Check your configuration file for the following:

    # IPv4 local connections:
    host    all             all               ident

    If you have such line, comment it out, it will conflict with the login we plan to set up.

  7. With that in place, we need to restart the database for the settings to take effect:
    # systemctl restart postgresql
  8. Now we have all information needed to tell the application where and how will it find the database. There is an example of the database connection configuration file with all supported databases in the config subdirectory of the extracted archive. We can make a copy of this file (using the redmine user):
    $ cp config/database.yml.example config/database.yml

    We can delete or comment out all example settings besides the ones related to PostgreSQL, or just create an empty file with the needed configuration (less junk will remain in the file that way). At the end, the /opt/redmine/config/database.yml should contain the following:

    # PostgreSQL configuration
      adapter: postgresql
      database: rmdb
      username: redmine
      password: "R3DM1N3"

    Note that we used the database connection information we set up in the last two steps.

  9. To lower the number of possible problems, we’ll test that we can log in to the rmdb database with the credentials provided in the configuration file. It is easier to debug connection problems with PostgreSQL toolset than any other:
    $ psql -d rmdb -U redmine -W
    Password for user redmine: 
    psql (10.5)
    Type "help" for help.
  10. This is where the easy part ends. Now we’ll install various Ruby packages Redmine depends on. Some of them need root access, some will install in the name of the redmine user, and later some will probably need a repair. No kidding. First of all, we’ll need bundler:
    # gem install bundler
    Fetching: bundler-2.0.1.gem (100%)
    Successfully installed bundler-2.0.1
    1 gem installed

    We’ll use bundler with the redmine user, but we’ll also need root to install or repair Ruby gems, so I suggest to open another terminal, switch to redmine user, and navigate to the /opt/redmine directory, while also keeping the root console open.

  11. As redmine user, we start the installation in the /opt/redmine directory:
    $ bundle install --without development test rmagick

    Many dependencies will be installed, and for some the installer asks for the sudo password – which is the password of the redmine user. It seems that this sudo functionality is somehow broken a bit, and can handle some of the root privileged package installs, and can’t get on with others. The ones that fail can be installed on the root console, and the above bundle command can be executed on the redmine user’s console again. What was needed to be installed in my case with root are the following:

    # gem install nokogiri -v '1.10.2' --source ''
    # gem install pg -v '1.1.4' --source ''

    There are also some packages that may broke during install. These can be repaired on the root console also. As with the above failed package installation steps, the output of the bundler command will tell which package got problems, and how to solve it. In my case the following packages needed repair:

    # gem pristine nio4r --version 2.3.1
    # gem pristine redcarpet --version 3.4.0
    # gem pristine websocket-driver --version 0.7.0

    Please note that if you are installing another version of Redmine, the version numbers of the packages will likely differ. After fixing all broken and missing packages, the bundle command should complete without errors, with the following end of the output:

    Installing roadie-rails 1.3.0
    Fetching rouge 3.3.0
    Installing rouge 3.3.0
    Bundle complete! 26 Gemfile dependencies, 57 gems now installed.
    Gems in the groups development, test and rmagick were not installed.
    Use `bundle info [gemname]` to see where a bundled gem is installed.
  12. With the tricky part done, we need to generate a token that will be used to encode session cookies:
    $ bundle exec rake generate_secret_token
  13. Next we generate the database objects needed by the application:
    $ RAILS_ENV=production bundle exec rake db:migrate

    Apart from creating the needed database objects, this step will generate a lot of output by logging all steps to the console. We’ll see a lot of entries appear similar to the following:

    == 20180913072918 AddVerifyPeerToAuthSources: migrating =======================
    -- change_table(:auth_sources)
       -> 0.0082s
    == 20180913072918 AddVerifyPeerToAuthSources: migrated (0.0083s) ==============
    == 20180923082945 ChangeSqliteBooleansTo0And1: migrating ======================
    == 20180923082945 ChangeSqliteBooleansTo0And1: migrated (0.0000s) =============

    This process should complete in a few seconds.

  14. We can check the populated database with psql:
    rmdb=> \dt
                           List of relations
     Schema |                Name                 | Type  |  Owner  
     public | ar_internal_metadata                | table | redmine
     public | attachments                         | table | redmine
     public | auth_sources                        | table | redmine
     public | boards                              | table | redmine
     public | changes                             | table | redmine

  15. The last step of the installation is loading the default data into the database. By providing the REDMINE_LANG parameter we can save ourselves from any questions during the initial loading.
    $ RAILS_ENV=production REDMINE_LANG=en bundle exec rake redmine:load_default_data
    Default configuration data loaded.
  16. The installation is complete. We can start up the application:
    $ bundle exec rails server webrick -e production
    => Booting WEBrick
    => Rails application starting in production on
    => Run `rails server -h` for more startup options
    [2019-04-14 18:39:12] INFO  WEBrick 1.4.2
    [2019-04-14 18:39:12] INFO  ruby 2.5.1 (2018-03-29) [x86_64-linux]
    [2019-04-14 18:39:12] INFO  WEBrick::HTTPServer#start: pid=30062 port=3000
  17. The application is now running and can be accessed with a browser. From the above output we can guess that it is accessible on port 3000, so if we have a firewall running on the target machine, we need to open this port to access the service remotely:
    # firewall-cmd --zone=public --add-port=3000/tcp --permanent
    # firewall-cmd --reload
  18. By opening a browser and pointing it to the machine’s address and port 3000 ( on the below screenshot), we can access the web-based interface of our fresh new Redmine installation.
    Login page of Redmine.

    Login page of Redmine.

    The default credentials are admin for username, and also for password. On first login the well-behaving application will prompt for a password change for this privileged account. From there the service is ours to populate, configure, and enjoy.

  19. With the installation complete, we can remove the redmine user from the wheel group, eliminating the security hole needed during the process:
    # gpasswd -d redmine wheel
    Removing user redmine from group wheel
    # id redmine
    uid=1008(redmine) gid=1008(redmine) groups=1008(redmine)