Deployment guide

Redmine 6.1.6

Overview

Redmine is an open source project management and issue tracking web application. Each project gets its own issue tracker with configurable trackers, statuses and workflows, plus time tracking, a Gantt chart, a calendar, a wiki, news, documents, files and forums, with roles and permissions per project. Teams use it as a bug tracker, a service desk queue or a general work tracker.

This guide covers the Redmine 6.1.6 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud help desk, IT service and project management listing on AWS Marketplace. You choose it as the software version when you launch.

What you get:

  • No default login. Upstream Redmine ships with the admin administrator and the published login admin/admin. On this image, first boot replaces that password with one generated for your instance, so admin/admin never works. Redmine's own check on Administration, Information shows "Default administrator account changed".
  • Sign-in required, self-registration off. Every page asks for a sign-in from the first page load, and nobody can create an account without an administrator.
  • Nothing baked into the image. The image ships an empty MySQL data directory, no secret key and no certificate. First boot creates this instance's database, runs Redmine's migrations and default data, and generates its secret key, certificate and administrator password.
  • No database password at all. Redmine runs as its own system user, redmine. MySQL accepts that user only over the local socket, from processes running as that user (auth_socket authentication). MySQL has no network listener.
  • HTTPS from the first boot. nginx serves Redmine on port 443 with a certificate generated on your instance. Port 80 redirects to HTTPS, and a request for a host name the instance does not serve gets no answer.
  • Puma behind nginx only. Redmine runs in Puma as the redmine user on a Unix socket that only nginx can reach. nginx serves the precompiled assets from disk and passes your real client address to Redmine, so its sign-in log and lockout cannot be fooled with an X-Forwarded-For header.
  • Rate-limited sign-in attempts. nginx limits sign-in attempts per client address.
  • Read-only code. The code under /opt/redmine and its configuration in /etc/redmine are owned by root. The redmine user can write only its attachments, temporary files and logs.
  • No ImageMagick or Ghostscript. Thumbnails and the Gantt PNG export are optional in Redmine. Leaving these components out removes the image converter attack surface.
  • No build toolchain. Redmine's gems are a fixed, reviewed set installed at build time. Compilers and development headers are removed before the image is captured.
  • Metadata access blocked. nginx, Puma, MySQL and first boot are blocked from the instance metadata service, and the AMI requires IMDSv2.
  • Fully patched base. Ubuntu 24.04 LTS is patched at build time, with unattended security upgrades switched on.

What is on the image: Redmine 6.1.6 (the upstream release redmine-6.1.6.tar.gz, checksum verified) with Rails 7.2, Puma 8, Ruby 3.2, nginx, MySQL 8.0, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair, and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 22 (SSH) from your admin network. It must also allow TCP 443 (Redmine) and TCP 80 (redirects to HTTPS) from the networks your users are on. Keep 80 and 443 as narrow as you can.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Redmine 6.1.6 on Ubuntu 24.04 as the software version, choose your Region, and select Launch through EC2.

Choose m5.large (or larger for many users), your key pair and a security group as described above.

To launch with the AWS CLI instead, replace the values in angle brackets:

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=redmine}]'

First boot builds the database. It takes about two minutes after the instance is running.

2

Connect to your instance

Connect over SSH as the ubuntu user, which is the default user for Redmine 6.1.6 on Ubuntu 24.04.

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

First boot creates the database, sets the password and generates the certificate. nginx and Redmine start only after it has finished. Check the services:

systemctl is-active nginx redmine mysql
sudo test -f /var/lib/sac/data/redmine-firstboot.done && echo FIRSTBOOT_DONE

All three services should be active, and the first-boot marker should be present:

active active active FIRSTBOOT_DONE

Only SSH and nginx listen on network ports. Puma and MySQL listen on local sockets only. Confirm it:

sudo ss -lntp | awk 'NR>1 && $4 !~ /^127\.0\.0\.5[34]/ {split($6, p, "\""); print $4, p[2]}' | sort
sudo ss -lxp | grep -oE '/run/redmine/puma.sock|/var/run/mysqld/mysqld.sock' | sort -u
0.0.0.0:22 sshd 0.0.0.0:443 nginx 0.0.0.0:80 nginx [::]:22 sshd [::]:443 nginx [::]:80 nginx /run/redmine/puma.sock /var/run/mysqld/mysqld.sock
4

Get your URL and password

Print the credentials file as root. It holds your Redmine URL and the administrator password generated for this instance:

sudo cat /root/redmine-credentials.txt

Only root can read the file:

# Redmine 6.1.6 - generated on first boot by redmine-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret. REDMINE_URL=https://ec2-203-0-113-10.compute-1.amazonaws.com/ REDMINE_ADMIN_USER=admin REDMINE_ADMIN_PASSWORD=<generated on your instance>
#
# Open REDMINE_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to # https) and sign in with the user and password above. Then change the password (My account > Change password), or add # your own administrators and lock admin. # Sign-in is required for every page and self-registration is off (Administration > Settings > Authentication). # E-mail: not configured; add your SMTP service to /etc/redmine/configuration.yml (see the guide). # MySQL: unix socket only (no TCP listener); Redmine signs in as the OS user redmine (auth_socket, no database # password). root signs in over the socket:
sudo mysql redmine
# Attachments: /var/lib/redmine/files Logs:
journalctl -u redmine
# Change the name it serves as:
sudo redmine-set-hostname <your-dns-name>
# User guide: https://secureanycloud.com/stacks/redmine-6-1-6/

REDMINE_URL uses the instance's public DNS name until you set your own in Step 8.

5

Sign in and change the password

Open REDMINE_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time. You can install your own certificate in Step 8. Sign in as admin with the password from Step 4.

Then make the account yours:

  • Open My account, then Change password, and set your own password.
  • Under Administration, Users, add an account for each person who uses Redmine instead of sharing one. Give at least one of them administrator rights. You can then lock the admin account.

Administration, Settings, Authentication shows the sign-in policy the image starts with: authentication required, self-registration disabled. Here you can also require two-factor authentication, for administrators or for everyone, and raise the minimum password length.

6

Create a project and track issues

A new instance has no projects. Choose Projects, then New project. Give the project a name and identifier, and pick the modules it uses (issue tracking, time tracking, wiki, documents and so on). Redmine's default trackers (Bug, Feature, Support), statuses, priorities and roles are already loaded.

Open the project's Issues tab and choose New issue. You can filter, sort and group the issue list, save it as a custom query, and export it as CSV, PDF or Atom.

Each issue records its status, priority, assignee, dates, progress, description, subtasks, related issues and watchers, plus its history of notes and changes.

Add members to each project with a role (Settings, Members in the project). Members then see the project and can work on its issues.

7

Email notifications

Redmine sends notification emails for new and updated issues once you give it an SMTP service. Email is not configured on a new instance.

Add your SMTP settings (Amazon SES or your own relay) to /etc/redmine/configuration.yml under production:. Keep the existing attachments_storage_path line:

production: attachments_storage_path: /var/lib/redmine/files email_delivery: delivery_method: :smtp smtp_settings: address: email-smtp.<region>.amazonaws.com port: 587 enable_starttls_auto: true authentication: :login user_name: "<smtp-user>" password: "<smtp-password>"

The file stays owned by root and readable only by Redmine. Restart Redmine to load the new settings:

sudo nano /etc/redmine/configuration.yml
sudo systemctl restart redmine

Then set the sender address under Administration, Settings, Email notifications. Use Send a test email on the same page to check delivery.

8

Your own DNS name and certificate

Point a DNS record at the instance. An Elastic IP keeps the address stable. Then set the name Redmine is served as.

The command below generates a new self-signed certificate for the name and points nginx at it. It also sets Redmine's host name setting (used in the links in its emails), updates /root/redmine-credentials.txt, and keeps the name across reboots:

sudo redmine-set-hostname <your-domain>

To use a certificate from a public or internal certificate authority instead, copy it over the generated pair and reload nginx. Running redmine-set-hostname again replaces it with a self-signed certificate:

sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/redmine.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/redmine.key
sudo nginx -t && sudo systemctl reload nginx
9

Security checks

nginx serves only Redmine's pages and its precompiled assets. The configuration, source code, logs, attachments and dotfiles answer 404. The REST and repository web services are off until you turn them on. Plain HTTP redirects to HTTPS, and a request for a name the instance does not serve gets no answer at all. Verify this behavior:

H=$(sudo grep '^REDMINE_URL=' /root/redmine-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/.*#\1#') for p in /login /projects /admin /config/database.yml /Gemfile.lock /log/production.log /files/ /.git/config /issues.json /sys/fetch_changesets; do curl -sk -o /dev/null -w "%{http_code} $p\n" --resolve "$H:443:127.0.0.1" "https://$H$p" done curl -s -o /dev/null -w 'http:// -> %{http_code}\n' --resolve "$H:80:127.0.0.1" "http://$H/" curl -sk -o /dev/null -w 'unknown host name -> %{http_code}\n' --resolve "other.example:443:127.0.0.1" "https://other.example/" || true
200 /login 302 /projects 302 /admin 404 /config/database.yml 404 /Gemfile.lock 404 /log/production.log 404 /files/ 404 /.git/config 403 /issues.json 403 /sys/fetch_changesets http:// -> 301 unknown host name -> 000

/projects and /admin redirect to the sign-in page. The credential check signs in through the real sign-in form with your password. It also confirms that a wrong password and admin/admin are refused:

sudo redmine-cred-roundtrip

Every service runs with the instance metadata service blocked. Confirm it:

for u in nginx redmine mysql redmine-firstboot; do echo "$u $(systemctl show -p IPAddressDeny --value $u)"; done
nginx 168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 redmine 168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 mysql 168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 redmine-firstboot 168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32

The code is owned by root, and the configuration is readable only by Redmine. Check the ownership and permissions:

stat -c '%U:%G %a %n' /opt/redmine /opt/redmine/app /opt/redmine/config/routes.rb
sudo stat -c '%U:%G %a %n' /etc/redmine /etc/redmine/database.yml /etc/redmine/configuration.yml
root:root 755 /opt/redmine root:root 755 /opt/redmine/app root:root 644 /opt/redmine/config/routes.rb root:redmine 750 /etc/redmine root:redmine 640 /etc/redmine/database.yml root:redmine 640 /etc/redmine/configuration.yml

Administration, Information confirms the version and shows Redmine's own checks. The ImageMagick lines are flagged because ImageMagick is deliberately not installed (thumbnails and the Gantt PNG export are optional). The queue adapter line is informational: Redmine sends its emails in the background inside Puma, which suits a single instance.

10

Backups and maintenance

Redmine stores everything in the MySQL database redmine (/var/lib/mysql) and in its attachments under /var/lib/redmine/files. Both are on the root volume, so the simplest backup is an EBS snapshot of that volume.

For a consistent copy you can keep elsewhere, run:

sudo mysqldump --single-transaction redmine | gzip > <backup-dir>/redmine-$(date +%F).sql.gz
sudo tar -C / -czf <backup-dir>/redmine-files-$(date +%F).tar.gz var/lib/redmine/files etc/redmine

Redmine's own tasks run as the redmine user, with the same metadata block as the service. For example, count projects and issues from the command line:

sudo systemd-run --quiet --pipe --wait --collect -p User=redmine -p Group=redmine -p WorkingDirectory=/opt/redmine \
  -p EnvironmentFile=/etc/redmine/secret.env -p "IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128" \
  -E RAILS_ENV=production -E HOME=/var/lib/redmine/home -E TMPDIR=/var/lib/redmine/tmp \
  /usr/local/bin/bundle exec rails runner 'puts "#{Project.count} projects, #{Issue.count} issues"'

Operating system security updates install automatically; run sudo apt-get update && sudo apt-get upgrade to apply everything else. nginx, Redmine and MySQL restart cleanly, and Redmine keeps all of its data.

New Redmine releases arrive as new versions of this listing, and support can help you move your data to one. Plugins and themes need gems and migrations matched to the release, so ask support before adding one.

Key locations on the instance:

  • Redmine code: /opt/redmine (owned by root, read-only to Redmine)
  • Configuration: /etc/redmine/database.yml, /etc/redmine/configuration.yml
  • Secret key: /etc/redmine/secret.env (root only, passed to Puma by systemd)
  • Database: MySQL database redmine (/var/lib/mysql)
  • Attachments: /var/lib/redmine/files
  • Logs: journalctl -u redmine, /var/log/nginx
  • Puma socket: /run/redmine/puma.sock (2 workers)
  • nginx site: /etc/nginx/sites-available/sac-redmine
  • Certificate and key: /etc/nginx/ssl/redmine.crt, /etc/nginx/ssl/redmine.key
  • Helpers: /usr/local/sbin/redmine-set-hostname, /usr/local/sbin/redmine-cred-roundtrip
  • Credentials: /root/redmine-credentials.txt (mode 0600)
  • Source and changes: /usr/share/doc/redmine-sac/SOURCE.txt
11

Security recommendations

  • Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your users are on.
  • Use your own DNS name and a certificate your browsers trust (Step 8).
  • Change the admin password as soon as you sign in. Give each person their own account, and consider requiring two-factor authentication for administrators (Step 5).
  • Turn on the REST API (Administration, Settings, API) only if you use it. Give each integration its own user and key.
  • Keep the operating system patched, and snapshot the root volume regularly.

Support and licensing

Redmine is open source under the GNU General Public License version 2 or later, by Jean-Philippe Lang and the Redmine contributors. There is no per-user licence fee.

The image ships the release exactly as published, with a fixed set of Ruby gems, minus the files listed in /usr/share/doc/redmine-sac/SOURCE.txt. That file also names the release and its checksum.

  • Email: sales@secureanycloud.com
  • Website: https://secureanycloud.com
  • Support: 24/7, with a 24-hour response SLA

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on AWS

Launch Redmine 6.1.6 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS