How to Install Redmine 6.0.6 on Ubuntu 24.04 with PostgreSQL, RVM Ruby, and HAProxy SSL

Redmine is a powerful, flexible, and open-source project management and issue tracking tool. Whether you’re managing software development, operations tasks, or internal projects, Redmine provides a clean and extensible interface to track issues, collaborate across teams, and visualize timelines.

In this guide, we’ll walk through installing Redmine 6.0.6 on Ubuntu 24.04, backed by PostgreSQL, Ruby 3.3.8 via RVM, and protected by SSL using HAProxy and Let’s Encrypt (Cloudflare DNS challenge).


Why Redmine?

Redmine offers a wide range of features out of the box:

  • Multi-project support
  • Role-based access control
  • Issue tracking with customizable workflows
  • Gantt charts and calendar
  • Time tracking
  • Wiki and forum modules
  • Plugin and theme support
  • Email notifications
  • Integrates with Git, SVN, Jenkins, and more

It’s a favorite among engineering and DevOps teams who want a self-hosted, open-source alternative to Jira.


Prerequisites

  • Ubuntu 24.04 server
  • A domain name (e.g. redmine.maksonlee.com)
  • A Cloudflare API Token (for DNS-01 SSL challenge)

Install required packages:

sudo apt update
sudo apt install -y certbot python3-certbot-dns-cloudflare
sudo add-apt-repository ppa:vbernat/haproxy-3.2 -y
sudo apt-get install haproxy=3.2.\*
sudo systemctl enable --now haproxy

  1. Install PostgreSQL
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install postgresql-14

Create the Redmine database:

sudo su - postgres
psql
CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'my_password' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;
\q

Exit redmine user:

exit

  1. Download and Configure Redmine
curl -OL https://www.redmine.org/releases/redmine-6.0.6.tar.gz
tar xzvf redmine-6.0.6.tar.gz
sudo mv redmine-6.0.6 /opt/

Create a Redmine system user:

sudo adduser --gecos 'Redmine' --disabled-password redmine
sudo chown -R redmine:redmine /opt/redmine-6.0.6

  1. Install Ruby 3.3.8 with RVM
sudo apt install libpq-dev
sudo apt install -y bzip2 g++ gcc autoconf automake bison libffi-dev libgdbm-dev libncurses5-dev libsqlite3-dev libtool libyaml-dev make pkg-config sqlite3 zlib1g-dev libgmp-dev libreadline-dev libssl-dev

Switch to the redmine user and install RVM:

sudo su - redmine
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -sSL https://get.rvm.io | bash -s stable
source /home/redmine/.rvm/scripts/rvm
rvm install 3.3.8 --disable-binary --autolibs=read-only

  1. Configure Database Connection
cd /opt/redmine-6.0.6/config/
cp database.yml.example database.yml
vi database.yml

Update the production: section:

vi database.yml
production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: "my_password"
  encoding: utf8
  schema_search_path: public


  1. Install Gems and Set Up Redmine

Create a Gemfile.local to add Puma:

cd /opt/redmine-6.0.6
vi Gemfile.local

Add:

group :production do
  gem 'puma'
end

Install Gems:

gem install bundler
bundle config set --local without 'development test' 
bundle install

Initialize Redmine:

bundle exec rake generate_secret_token
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production REDMINE_LANG=en bundle exec rake redmine:load_default_data

Exit redmine user:

exit

  1. Set Correct File Permissions
cd /opt/redmine-6.0.6
sudo mkdir -p tmp tmp/pdf public/assets
sudo chown -R redmine:redmine files log tmp public/assets
sudo chmod -R 755 files log tmp public/assets
sudo find files log tmp public/assets -type f -exec chmod -x {} +

  1. Run Redmine as a Systemd Service

Create /etc/systemd/system/redmine.service:

[Unit]
Description=Redmine 6.0.6 with Puma and RVM
After=network.target

[Service]
Type=simple
User=redmine
WorkingDirectory=/opt/redmine-6.0.6

ExecStart=/bin/bash -lc 'bundle exec rails server -e production'

Restart=on-failure
TimeoutSec=15

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable --now redmine

  1. Issue HTTPS Certificate via Cloudflare DNS

Create Cloudflare credentials:

mkdir -p ~/.secrets/certbot
vi ~/.secrets/certbot/cloudflare.ini

Add:

dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN

Secure the file:

chmod 600 ~/.secrets/certbot/cloudflare.ini

Request certificate:

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d redmine.maksonlee.com

  1. Bundle Certificate for HAProxy
sudo mkdir -p /etc/haproxy/certs/
sudo bash -c "cat /etc/letsencrypt/live/redmine.maksonlee.com/fullchain.pem \
  /etc/letsencrypt/live/redmine.maksonlee.com/privkey.pem \
  > /etc/haproxy/certs/redmine.maksonlee.com.pem"
sudo chmod 600 /etc/haproxy/certs/redmine.maksonlee.com.pem

  1. Configure HAProxy for SSL Termination

Edit /etc/haproxy/haproxy.cfg:

frontend https_in
    bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
    mode http
    default_backend redmine

backend redmine
    mode http
    option http-buffer-request
    option http-keep-alive
    option forwardfor
    http-request set-header X-Forwarded-Proto https

    server redmine1 127.0.0.1:3000

Restart HAProxy:

sudo systemctl restart haproxy

  1. Automate Certificate Renewal

Create deploy hook to reload HAProxy on renewal:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-haproxy.sh > /dev/null <<EOF
#!/bin/bash
cat /etc/letsencrypt/live/redmine.maksonlee.com/fullchain.pem \
    /etc/letsencrypt/live/redmine.maksonlee.com/privkey.pem \
    > /etc/haproxy/certs/redmine.maksonlee.com.pem
systemctl reload haproxy
EOF
  
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-haproxy.sh

Final Result

You can now access your Redmine instance securely at:

https://redmine.maksonlee.com

You’ll be greeted with the login screen. Default credentials are:

Login: admin
Password: admin

Change the password immediately after logging in!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top