--- title: "How to Install Redmine on Ubuntu 24.04 with Nginx and Puma" description: "Install Redmine 6 on Ubuntu 24.04 with Ruby 3.2, MySQL 8, Puma as a systemd service and Nginx with Let's Encrypt, then set up email and nightly backups." category: "Web Applications Hosting" language: en source: https://cubepath.com/docs/web-applications-hosting/redmine-project-management-installation updated: 2026-09-25 --- # How to Install Redmine on Ubuntu 24.04 with Nginx and Puma Redmine is an open source project management and issue tracking application built on Ruby on Rails, with per-project trackers, wikis, time tracking and Gantt charts. In this tutorial you will install Redmine 6 on Ubuntu 24.04 using the distribution's Ruby 3.2 and MySQL 8, run it under Puma as a systemd service, publish it through Nginx with a Let's Encrypt certificate, and configure email and backups. ## Prerequisites To follow this guide you need: - A server running Ubuntu 24.04 LTS, for example a CubePath VPS, with at least 2 GB of RAM (4 GB if the same server runs other applications). - A non-root user with `sudo` privileges. - A domain or subdomain (this guide uses `your_domain`) with a DNS `A` record pointing to `your_server_ip`. - Ports 80 and 443 open to the internet. ## Step 1 - Installing Ruby, MySQL and build dependencies Redmine 6.0 supports Ruby 3.1 to 3.3, and Ubuntu 24.04 ships Ruby 3.2, so there is no need for a version manager such as RVM. Install Ruby with its development headers, the compiler toolchain needed to build native gems, the MySQL server and client library, ImageMagick for thumbnails, and Nginx: ```bash sudo apt update sudo apt install ruby-full build-essential libyaml-dev zlib1g-dev libmysqlclient-dev mysql-server imagemagick nginx ``` Install a current Bundler from RubyGems, since Redmine 6 expects a newer version than the one packaged by Ubuntu: ```bash sudo gem install bundler ``` Verify the versions: ```bash ruby -v bundle -v ``` ```output ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [x86_64-linux-gnu] Bundler version 2.x.x ``` Open the firewall for SSH and web traffic: ```bash sudo ufw allow OpenSSH sudo ufw allow 'Nginx Full' sudo ufw enable ``` ## Step 2 - Creating the database On Ubuntu, the MySQL `root` account authenticates through the Unix socket, so `sudo mysql` opens a shell without a password. Run the hardening script first to remove anonymous users and the test database: ```bash sudo mysql_secure_installation ``` Then open the MySQL shell: ```bash sudo mysql ``` Create the database and a dedicated user. Replace `your_db_password` with a strong password: ```sql CREATE DATABASE redmine CHARACTER SET utf8mb4; CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'your_db_password'; GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost'; FLUSH PRIVILEGES; EXIT; ``` Check that the new account works: ```bash mysql -u redmine -p -e 'SHOW DATABASES;' ``` ```output +--------------------+ | Database | +--------------------+ | information_schema | | performance_schema | | redmine | +--------------------+ ``` ## Step 3 - Downloading Redmine Redmine will run under its own unprivileged system user, with `/opt/redmine` as both its home and installation directory: ```bash sudo useradd --system --create-home --home-dir /opt/redmine --shell /usr/sbin/nologin redmine ``` Download the latest 6.0 release. Check the [Redmine download page](https://www.redmine.org/projects/redmine/wiki/Download) for the current version number and adjust the commands if a newer point release is available: ```bash cd /tmp wget https://www.redmine.org/releases/redmine-6.0.4.tar.gz ``` Extract it directly into `/opt/redmine` and hand ownership to the `redmine` user: ```bash sudo tar --no-same-owner -xzf redmine-6.0.4.tar.gz -C /opt/redmine --strip-components=1 sudo chown -R redmine:redmine /opt/redmine sudo chmod 755 /opt/redmine ``` The `chmod` lets your own user enter the directory to run the commands below; `useradd` creates home directories with mode `750` on Ubuntu 24.04. ## Step 4 - Configuring the database connection Redmine reads its database settings from `config/database.yml`. Create the file: ```bash sudo -u redmine nano /opt/redmine/config/database.yml ``` Add the production connection, using the password from Step 2: ```yaml production: adapter: mysql2 database: redmine host: localhost username: redmine password: "your_db_password" encoding: utf8mb4 variables: transaction_isolation: "READ-COMMITTED" ``` The `READ-COMMITTED` isolation level is the one Redmine recommends for MySQL to avoid deadlocks under concurrent use. Restrict the file, since it contains a password: ```bash sudo chmod 600 /opt/redmine/config/database.yml ``` ## Step 5 - Installing gems and initializing Redmine Puma, the application server you will use, is not part of Redmine's production dependencies. Add it through `Gemfile.local`, a file Redmine's `Gemfile` loads automatically: ```bash echo "gem 'puma'" | sudo -u redmine tee /opt/redmine/Gemfile.local ``` Tell Bundler to install gems inside the application directory and to skip development and test dependencies, then install them. This step compiles native extensions and can take a few minutes: ```bash cd /opt/redmine sudo -u redmine bundle config set --local path 'vendor/bundle' sudo -u redmine bundle config set --local without 'development test' sudo -u redmine bundle install ``` ```output ... Bundle complete! ... Gemfile dependencies, ... gems now installed. Gems in the groups 'development' and 'test' were not installed. ``` Generate the secret used to sign session cookies, create the database schema and load the default roles, trackers and statuses: ```bash sudo -u redmine bundle exec rake generate_secret_token sudo -u redmine bundle exec rake db:migrate RAILS_ENV=production sudo -u redmine bundle exec rake redmine:load_default_data RAILS_ENV=production REDMINE_LANG=en ``` Compile the stylesheets and JavaScript into `public/assets`: ```bash sudo -u redmine bundle exec rake assets:precompile RAILS_ENV=production ``` ## Step 6 - Running Redmine with Puma under systemd A systemd unit starts Redmine at boot and restarts it if it crashes. Create the unit file: ```bash sudo nano /etc/systemd/system/redmine.service ``` ```ini [Unit] Description=Redmine (Puma) After=network.target mysql.service Wants=mysql.service [Service] Type=simple User=redmine Group=redmine WorkingDirectory=/opt/redmine Environment=RAILS_ENV=production ExecStart=/usr/local/bin/bundle exec puma -e production -b tcp://127.0.0.1:3000 -w 2 -t 5:5 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` Puma listens only on `127.0.0.1:3000`, with two worker processes of five threads each; Nginx will be the only public entry point. Start the service: ```bash sudo systemctl daemon-reload sudo systemctl enable --now redmine sudo systemctl status redmine --no-pager ``` ```output ● redmine.service - Redmine (Puma) Loaded: loaded (/etc/systemd/system/redmine.service; enabled; preset: enabled) Active: active (running) since ... ``` Check that Redmine answers locally: ```bash curl -sI http://127.0.0.1:3000 | head -n 1 ``` ```output HTTP/1.1 200 OK ``` If the service fails, read its log with `sudo journalctl -u redmine -n 50`. ## Step 7 - Configuring Nginx and HTTPS Create an Nginx server block that proxies requests to Puma: ```bash sudo nano /etc/nginx/sites-available/redmine ``` ```nginx server { listen 80; listen [::]:80; server_name your_domain; client_max_body_size 50m; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` Enable it, remove the default site and test the configuration: ```bash sudo ln -s /etc/nginx/sites-available/redmine /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx ``` Request a certificate with Certbot. The Nginx plugin adds the HTTPS listener and an HTTP to HTTPS redirect to the server block: ```bash sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d your_domain ``` Confirm automatic renewal works: ```bash sudo certbot renew --dry-run ``` Open `https://your_domain` and sign in with the default account `admin` / `admin`. Set a strong password straight away (Redmine prompts you, or use **My account**). Then go to **Administration > Settings > General** and set **Host name and path** to `your_domain` and **Protocol** to `HTTPS`, so links in emails point to the right address. ## Step 8 - Configuring outgoing email Redmine sends notifications for new issues, updates and password resets. Create the configuration file from the shipped example: ```bash sudo -u redmine cp /opt/redmine/config/configuration.yml.example /opt/redmine/config/configuration.yml sudo -u redmine nano /opt/redmine/config/configuration.yml ``` Find the `production:` section at the end of the file (or add it) and set your SMTP provider's details: ```yaml production: email_delivery: delivery_method: :smtp smtp_settings: address: "smtp.your_provider.com" port: 587 domain: "your_domain" authentication: :login user_name: "your_smtp_user" password: "your_smtp_password" enable_starttls_auto: true ``` Protect the file and restart Redmine: ```bash sudo chmod 600 /opt/redmine/config/configuration.yml sudo systemctl restart redmine ``` In **Administration > Settings > Email notifications**, set the **Emission email address** and click **Send a test email**. The test message goes to the address of the logged-in administrator. ## Step 9 - Installing plugins Redmine plugins are Rails engines that live in `/opt/redmine/plugins/`. The procedure is the same for every plugin; always check that the plugin states support for Redmine 6.0 first: 1. Copy or clone the plugin into `/opt/redmine/plugins/` and run `sudo chown -R redmine:redmine /opt/redmine/plugins`. 2. Install any new gems with `cd /opt/redmine && sudo -u redmine bundle install`. 3. Run the plugin migrations: ```bash cd /opt/redmine sudo -u redmine bundle exec rake redmine:plugins:migrate RAILS_ENV=production sudo systemctl restart redmine ``` Installed plugins appear under **Administration > Plugins**. ## Step 10 - Scheduling backups The data you need to back up is the database, the uploaded files in `files/` and the two configuration files. Create a backup script: ```bash sudo nano /usr/local/sbin/redmine-backup ``` ```bash #!/usr/bin/env bash set -euo pipefail umask 077 BACKUP_DIR=/var/backups/redmine APP_DIR=/opt/redmine STAMP=$(date +%F-%H%M) mkdir -p "$BACKUP_DIR" # Runs as root, so MySQL authenticates through the Unix socket mysqldump --single-transaction redmine | gzip > "$BACKUP_DIR/redmine-db-$STAMP.sql.gz" tar -czf "$BACKUP_DIR/redmine-files-$STAMP.tar.gz" -C "$APP_DIR" \ files config/database.yml config/configuration.yml find "$BACKUP_DIR" -type f -mtime +14 -delete ``` Make it executable, run it once and check the result: ```bash sudo chmod 700 /usr/local/sbin/redmine-backup sudo /usr/local/sbin/redmine-backup sudo ls -lh /var/backups/redmine ``` ```output -rw------- 1 root root 180K Sep 25 10:40 redmine-db-2026-09-25-1040.sql.gz -rw------- 1 root root 12K Sep 25 10:40 redmine-files-2026-09-25-1040.tar.gz ``` Schedule it nightly: ```bash echo '15 2 * * * root /usr/local/sbin/redmine-backup' | sudo tee /etc/cron.d/redmine-backup ``` Copy the backups off the server regularly, for example with `rsync` to another host. ## Troubleshooting - **`bundle install` fails building `mysql2`**: the MySQL client headers are missing. Install `libmysqlclient-dev` and run `bundle install` again. - **Nginx returns 502 Bad Gateway**: Puma is not running. Check `sudo systemctl status redmine` and `sudo journalctl -u redmine -n 50`; a typo in `database.yml` is the usual cause. - **Links in notification emails use `localhost:3000`**: set **Host name and path** and **Protocol** under **Administration > Settings > General**. - **Uploads larger than a few MB are rejected**: raise **Maximum attachment size** under **Administration > Settings > Files** and keep `client_max_body_size` in Nginx at least as large. ## Conclusion Redmine 6 is now running on Ubuntu 24.04 under Puma and systemd, behind Nginx with HTTPS, with email notifications and nightly backups. Next, create your first project and adjust roles and trackers under **Administration**, enable the REST API if you want to integrate other tools, and when a new release comes out, upgrade by extracting it into a new directory, copying over `config/database.yml`, `config/configuration.yml`, `files/` and `plugins/`, and running the database migrations.