Redmine recovery depends on both the application database and the uploaded files stored beside the Rails application. A database dump without the files directory can bring back projects and issues but leave attachments missing, while a file copy without the database cannot rebuild project history.
A PostgreSQL-backed Redmine installation can be backed up with pg_dump and restored with pg_restore into a staging database. Uploaded files, local configuration, and plugins are archived separately from the database so each part can be inspected before a restore drill.
Run the restore against a disposable staging instance before relying on the backup for a maintenance window or disaster recovery plan. The staging Redmine version should match production, and its /config/database.yml file should point at the drill database before the smoke test reads recovered project data.
Related: How to install Redmine on Ubuntu
Related: How to upgrade Redmine
Steps to back up and restore Redmine with PostgreSQL:
- Identify the Redmine root, database settings, and attachment path.
The database settings are usually in /opt/redmine/config/database.yml. Uploaded files default to /opt/redmine/files unless attachments_storage_path in /opt/redmine/config/configuration.yml points elsewhere.
- Create a dated backup directory.
$ sudo mkdir --parents /var/backups/redmine/2026-06-26
- Dump the PostgreSQL database in custom format.
$ pg_dump --username=redmine --host=localhost --format=custom --file=/var/backups/redmine/2026-06-26/redmine.dump redmine
Use the database name, host, and user from /opt/redmine/config/database.yml. pg_dump prompts for the password unless the database account uses peer authentication or a protected .pgpass file.
- Archive uploaded files, local configuration, and plugins.
$ sudo tar --create --gzip --file=/var/backups/redmine/2026-06-26/redmine-files-config.tar.gz --directory=/opt/redmine files config plugins
The archive contains /opt/redmine/config/database.yml, which may include database credentials. Store the backup where only Redmine administrators and backup operators can read it.
- List the database dump contents.
$ pg_restore --list /var/backups/redmine/2026-06-26/redmine.dump ; ; Archive created at 2026-06-26 12:20:00 UTC ; dbname: redmine ; TOC Entries: 482 ; Compression: gzip ; ##### snipped ##### 3357; 0 16768 TABLE DATA public projects redmine 3358; 0 16777 TABLE DATA public projects_trackers redmine 3359; 0 16782 TABLE DATA public roles redmine ##### snipped #####
- List the file archive contents.
$ tar --list --gzip --file=/var/backups/redmine/2026-06-26/redmine-files-config.tar.gz files/ files/20260626010101_field_service_status.txt config/ config/configuration.yml config/database.yml plugins/
- Create an empty drill database on the staging database server.
$ createdb --username=redmine --host=localhost --owner=redmine redmine_restore
Use a database administrator account for this step when the redmine database user cannot create databases.
- Restore the dump into the drill database.
$ pg_restore --username=redmine --host=localhost --dbname=redmine_restore --clean --if-exists /var/backups/redmine/2026-06-26/redmine.dump
- Extract the uploaded files into the staging Redmine root.
$ sudo tar --extract --gzip --file=/var/backups/redmine/2026-06-26/redmine-files-config.tar.gz --directory=/opt/redmine files
Extract configuration or plugin files separately only after checking that paths, database names, plugin versions, and secrets match the staging instance.
- Point the staging Redmine database configuration at the drill database.
- /opt/redmine/config/database.yml
production: adapter: postgresql database: redmine_restore host: localhost username: redmine password: "<redmine database password>"
- Start the staging Redmine application against the drill database.
Use the service, container, Passenger restart, or process manager command that runs the staging instance.
- Verify that Redmine can read a known restored project from the drill database.
$ RAILS_ENV=production bundle exec rails runner 'puts Project.find_by!(identifier: "field-service").name' Field Service Portal
- Check the restored login page over HTTP.
$ curl --head http://redmine-staging.example.net/login HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.