The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Self-hosting Redmine on a Linux VPS means matching a released Redmine package to its supported Ruby and database versions, running the application under a dedicated account, placing it behind an HTTPS-capable web server, and protecting both the database and uploaded files with tested backups. The Redmine project lists Redmine 6.0.11 as released on August 26, 2026. The procedure below uses that release as the concrete example; verify the compatibility matrix again if you install Redmine 6.1, 7.0, or another package.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
What you are building
A production Redmine installation has four separable parts:
As an Amazon Associate I earn from qualifying purchases.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- A Linux VPS that runs Ruby and the Redmine application.
- A production database owned by a separate database account.
- Persistent application data, especially uploaded attachments in the
filesdirectory. - A web server or reverse proxy that terminates TLS and forwards requests to Redmine’s Rails/Puma process.
The official Redmine installation guide says that Redmine should run on most Unix, Linux, macOS, and Windows systems as long as Ruby is available on the platform. A VPS is therefore an operational choice rather than a special Redmine requirement: you are responsible for patching the host, limiting network exposure, operating the database, renewing certificates, and recovering from backups.
Pin the Redmine release and supported stack first
Do not install Ruby or a database merely because it is the newest package in your distribution. Select the Redmine release, then use the versions listed for that release. For Redmine 6.0, the official compatibility table lists the following combinations:
#1 Best Overall
| Component | Redmine 6.0 compatibility |
|---|---|
| Ruby | 3.1, 3.2, or 3.3 |
| Rails | 7.2 |
| PostgreSQL | 14 |
| MySQL | 8.0–8.1 |
| Microsoft SQL Server | Newer than 2012 |
| SQLite | SQLite 3 |
The same official table contains different combinations for Redmine 6.1 and 7.0. Treat the table as release-specific: a Ruby or database upgrade that is valid for one Redmine branch is not automatically valid for another. The download page identifies Redmine 6.0.11 and is dated 2026-08-26, so record that exact package version in your deployment notes.
Why this check prevents failed deployments
Redmine uses Bundler to resolve Ruby gems, and the database adapter is selected from config/database.yml. If the Ruby interpreter, Rails dependency set, adapter gem, and server database do not line up, installation can fail before the application starts or after an upgrade. Write down the chosen Redmine version, Ruby version, database engine, and database version before provisioning the VPS. Recheck all four whenever you plan an upgrade.
Prepare the Linux VPS
Use a dedicated service account
Create a non-root operating-system account for Redmine and run the application as that account. Use an administrator account with sudo only for host administration, package installation, directory ownership, and service management. Keeping the Rails process away from root limits the damage from a vulnerable plugin, a malicious attachment, or an application mistake.
Plan storage and network access
Allocate storage for the operating system, Ruby dependencies, logs, the database, and the growth of files. Attachments are application data, not disposable cache files. Expose only the ports required for administration and web traffic, restrict database access to the application host where practical, and keep the VPS and Ruby dependencies patched.
Choose the database deliberately
PostgreSQL and MySQL are the usual production choices in the supported matrix. Choose the engine your team can monitor, back up, restore, and troubleshoot confidently. SQLite 3 is listed as supported, but a single-file database changes the locking, concurrency, and backup design; it should not be selected simply because it is easy to create. Microsoft SQL Server is also listed for Redmine 6.0 when the server is newer than 2012.
Create an empty production database
Provision the database before running Bundler migrations. Use a database name and account dedicated to Redmine, and do not reuse an administrator login in the application configuration.
PostgreSQL example
sudo -u postgres createuser --pwprompt redmine
sudo -u postgres createdb -O redmine redmine_production
The commands create a login interactively and make that account the owner of an empty database. Apply your organisation’s password policy and host-based access rules; do not paste a real password into deployment notes or shell history.
Rank #2
MySQL example
CREATE DATABASE redmine_production CHARACTER SET utf8mb4;
CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'use-a-long-random-secret';
GRANT ALL PRIVILEGES ON redmine_production.* TO 'redmine'@'localhost';
FLUSH PRIVILEGES;
Run equivalent statements through an administrative MySQL session, then restrict the account to the host from which Redmine connects. If the database is on another machine, use a narrowly scoped network rule and an account host pattern that matches that design instead of opening the database to every address.
Download and unpack Redmine
- Obtain the released Redmine 6.0.11 archive from the Redmine project’s official download page and verify that the archive name and version are the one you selected.
- Extract it into a stable application path such as
/srv/redmine. Keep the release directory separate from backups and from any shared upload storage. - Assign ownership so the deployment administrator can update code while the service account can write only to the runtime and data directories that Redmine requires.
tar -xzf redmine-6.0.11.tar.gz
sudo mv redmine-6.0.11 /srv/redmine
cd /srv/redmine
The archive command assumes the downloaded file is in the current directory; use your actual package path. Do not make the entire application tree writable by the web process.
Configure database.yml
Redmine ships an example configuration. Copy it and edit the production section:
cp config/database.yml.example config/database.yml
Set the production adapter, database name, host, username, password, and any encoding or isolation settings required by the selected engine. For PostgreSQL, the adapter must match the PostgreSQL gem expected by the release; for MySQL, use the corresponding MySQL adapter. Keep the file readable by the Redmine service account but not broadly readable by unrelated users because it contains database credentials.
Check the YAML indentation before installing gems. A malformed file can cause Bundler or Rails to select the wrong adapter, connect to a development database, or fail with an unhelpful startup error. Never put development and production credentials in the same account.
Install production dependencies and initialize Rails
Run the following from the Redmine application directory as the deployment account:
- Exclude development and test gems.
bundle config set --local without 'development test'
bundle installRedmine determines which database adapter gems are needed from
config/database.yml. If Bundler reports an adapter or Ruby-version conflict, stop and return to the release matrix instead of forcing a different gem version.Recommended: PC Feels Slow? A Free Scan Shows What's Dragging Windows Down →Recommended: Crashes or Glitches? A Free Driver Scan Usually Finds the Culprit →Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy. - Generate the session secret.
bin/rails generate_secret_tokenThis creates the secret used to protect Rails session data. Treat the generated configuration as sensitive and preserve it during upgrades; generating a new secret can invalidate existing sessions.
- Run database migrations.
RAILS_ENV=production bundle exec rake db:migrateMigrations create and change the schema for the selected Redmine release. Run them only against the empty production database you created, never against a database that still contains another environment’s data.
- Load the default data.
RAILS_ENV=production bundle exec rake redmine:load_default_dataChoose the language when the task prompts for it. The task loads Redmine’s initial roles, trackers, workflows, and other defaults; it is not a substitute for your own projects, users, or permissions.
- Prepare runtime directories and assets.
mkdir -p tmp tmp/pdfCompile assets when automatic compilation is disabled or when the application is deployed under a relative URL root. A relative URL root is a common reason for apparently missing CSS and JavaScript after a successful migration.
Recommended Free Tools
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Set permissions without making restored files executable
The service account needs write access to the directories Redmine changes at runtime:
filesfor uploaded attachments.logfor application logs.tmpandtmp/pdffor temporary and PDF-generation work.public/assetswhen assets are generated or updated on the host.
Grant ownership or group write access to those paths, then verify the effective permissions as the service account. Avoid a blanket writable permission on the whole release tree. If you restore an attachment archive or other application files, remove executable bits from the restored files; an uploaded document must remain data, not a program that the web process can execute.
sudo chown -R redmine:redmine /srv/redmine/files /srv/redmine/log /srv/redmine/tmp /srv/redmine/public/assets
find /srv/redmine/files -type f -exec chmod a-x {} ;
Adjust the account and path to your layout. If a separate deployment user owns the code, change only the runtime directories rather than transferring ownership of the complete release.
Rank #4
Run a production smoke test
Before introducing a reverse proxy, start Redmine in the foreground and watch the log for database, secret-key, asset, and permission errors:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →cd /srv/redmine
RAILS_ENV=production bundle exec rails server -e production
Open the local test address from an administrative tunnel or from the VPS itself. Confirm that the login page loads, static assets render, a test project can be created, and a small attachment can be uploaded and downloaded. Stop the foreground process after the test. For normal operation, run the Rails/Puma process under your chosen service supervisor so it restarts after a failure and starts on boot.
Secure the initial administrator account
Log in with the initial administrator account supplied by the release documentation, change its password immediately, and review the application settings before inviting users. Remove or disable accounts you do not need, set the correct time zone and host name, and configure outbound SMTP before relying on password resets or notification mail.
Put Redmine behind a web server and HTTPS
The canonical Redmine installation documentation concentrates on application installation and leaves the web-server choice to the operator. Use a web server or reverse proxy that can terminate TLS and forward requests to the local Rails/Puma process.
- Bind the application process to a local interface or Unix socket that is not directly exposed to the Internet.
- Configure the proxy’s upstream to that interface or socket and preserve the original host and HTTPS scheme in forwarded headers so Redmine builds correct links.
- Install a certificate for the Redmine host name, redirect clear-text HTTP to HTTPS, and arrange renewal before expiration.
- Allow the proxy to pass request bodies large enough for your attachment policy; otherwise uploads can fail even though the Redmine permission is correct.
- Forward proxy and application logs to a location with rotation and restricted access. A log directory that fills the VPS can make an otherwise healthy Redmine instance unavailable.
- If you deploy under a relative URL root, configure that root consistently in the proxy and Redmine, then precompile assets as required.
Test both an ordinary page and an attachment upload through the HTTPS name. A page that works on the local Rails port but fails through the proxy usually indicates a forwarded-header, path-prefix, body-size, certificate, or file-permission problem.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Back up the database and uploaded files
A Redmine backup is incomplete if it contains only the database. The database stores configuration and records; the files directory stores uploaded attachments. Back up both on a schedule, keep copies off the VPS, and periodically perform a restore test on an isolated host.
Database dumps
For PostgreSQL, a logical dump can be produced with:
Best Value
pg_dump -Fc -d redmine_production > redmine_production.dump
For MySQL, use a transaction-consistent dump appropriate to your server configuration:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsmysqldump --single-transaction --routines --triggers redmine_production > redmine_production.sql
Protect dump files because they contain project and user data. Record the database engine and Redmine release alongside each backup so a restore operator knows which compatibility matrix to use.
Attachment backups
tar -czf redmine-files-$(date +%F).tar.gz -C /srv/redmine files
Preserve ownership and permissions when archiving and restoring. After a restore, remove executable bits from restored files, place the directory at the path configured for Redmine, and verify that the service account can read existing attachments and write a new one.
Prove that recovery works
- Restore a database dump into a disposable database using the same supported engine family.
- Restore the matching
filesarchive into a disposable Redmine release directory. - Point a test deployment at the restored database and files path.
- Log in, open an existing issue, download an old attachment, and upload a new test file.
- Record the elapsed recovery time and any manual steps, then update the production runbook.
Operate upgrades and plugins safely
Keep the released archive, Gemfile.lock, database dump, session-secret configuration, and attachment backup together for each deployment. Test an upgrade on a clone first: install the target Ruby version, run Bundler against the target release, execute migrations, load no default data unless the release instructions require it, and exercise login, issue creation, mail, attachments, and any source-control integration you use.
Review every plugin against the target Redmine and Ruby versions. A plugin can constrain Rails or adapter gems even when the core Redmine matrix is satisfied. Schedule a maintenance window, take fresh backups, and retain the previous application release so you can roll back code while restoring the database only according to the upgrade’s documented migration rules.
Free tools Windows power users keep installed
One-click scans. No signup required.
PostgreSQL or MySQL: a practical decision
Both engines are explicitly supported for Redmine 6.0, but they differ operationally. PostgreSQL 14 is the listed PostgreSQL target; MySQL 8.0–8.1 is the listed MySQL range. Choose PostgreSQL when your administrators already standardize on it and can operate its roles, authentication, dumps, and restores. Choose MySQL when its account model, monitoring, and backup tooling are already familiar to your team. The safer choice is the engine you can restore under pressure, not the one that is quickest to install.
Whichever engine you select, keep the database close to the application unless you have a deliberate network design, restrict inbound access, use a dedicated Redmine account, and test a restore before the first production project depends on the installation.
Quick Recap
Troubleshooting checklist
| Symptom | Likely check | Corrective action |
|---|---|---|
| Bundler refuses to resolve gems | Ruby version, Redmine release, and adapter selected in database.yml |
Return to the release matrix, install a supported Ruby version, and rerun Bundler without forcing arbitrary gem versions. |
| Migration cannot connect | Production database name, host, account, password, and adapter | Test the database login independently, correct the production section of config/database.yml, and rerun the migration against the intended database. |
| Uploads fail with permission errors | Write access to files, tmp, and tmp/pdf |
Fix ownership or group permissions for the service account and retry with a small test attachment. |
| CSS or JavaScript is missing | Asset compilation and relative URL-root configuration | Compile assets when automatic compilation is disabled and make the proxy path agree with Redmine’s URL-root setting. |
| Attachments download as programs or are rejected by policy | Restored file mode bits | Remove executable bits from restored files and verify that the web server serves them only through Redmine’s attachment path. |
| Works on the Rails port but not through HTTPS | Proxy upstream, forwarded scheme/host, certificate, and request-body limits | Correct the reverse-proxy configuration, renew or install the certificate, and test an upload through the public HTTPS name. |
| Redmine stops after a VPS reboot | Process supervision and boot-time service configuration | Run Puma/Rails under a service supervisor configured to start as the dedicated account and restart on failure. |
Final pre-launch checklist
- The installed package is a released Redmine version, and its Ruby, Rails, and database versions match the official matrix.
- The production database is empty at initialization, owned by a dedicated account, and not reachable from unnecessary hosts.
- Bundler installed only production dependencies, the session secret exists, migrations completed, and default data loaded successfully.
- The service account can write to
files,log,tmp,tmp/pdf, andpublic/assetswithout owning the complete code tree. - The initial administrator password and application settings were changed before users were invited.
- The reverse proxy serves HTTPS, passes the correct host and scheme, and handles the attachment size you permit.
- Database dumps and the
filesdirectory are copied off the VPS, protected, and proven restorable. - The upgrade and rollback runbook names the Redmine release, Ruby version, database engine, plugin set, and exact backup locations.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




