A RackHelm install is three things you cannot recreate: the database, the uploaded files under storage/, and the application encryption key in .env. Back up all three together, and understand why the key is the one that will catch you out.
Why APP_KEY is the critical item #
RackHelm encrypts credentials at rest using APP_KEY from .env. That covers:
- Payment gateway configuration — API keys and secrets
- Server integration connections — control-panel base URLs and admin API tokens
- Control-panel records and custom API integration credentials
- Notification channel configuration, including webhook URLs
- E-mail route passwords and OAuth client secrets used by e-mail-to-ticket
- Selected rows in the settings table, such as the SMTP password and CAPTCHA secret
Restore a database without its matching APP_KEY and every one of those becomes unreadable. The rows are still there, but nothing can decrypt them — you will be re-entering every gateway and integration credential by hand.
Warning: Never rotate
APP_KEYon a live install, and never let a restore run against a fresh.envwith a newly generated key.
What to back up #
| Item | Path | Why |
|---|---|---|
| Database | MySQL database named in DB_DATABASE |
Clients, orders, invoices, services, tickets, settings, schedules — everything. |
| Environment file | /var/www/rackhelm/.env |
APP_KEY, database credentials, licence key. |
| Private storage | /var/www/rackhelm/storage/app/private |
Generated invoice PDFs and ticket attachments. |
| Public storage | /var/www/rackhelm/storage/app/public |
Logos, page assets and other uploads served through the public/storage symlink. |
| Logs | /var/www/rackhelm/storage/logs |
Optional, but useful when investigating what happened before an incident. |
| Web-server configuration | /etc/nginx/sites-available/rackhelm.conf and the Let’s Encrypt files under /etc/letsencrypt |
Saves reissuing certificates and rewriting the site block. |
| Worker configuration | /etc/supervisor/conf.d/rackhelm-horizon.conf (or the RHEL .ini equivalent) and the scheduler crontab |
Without these the restored install has no queue worker and no scheduler. |
| Installer credentials | /root/.rackhelm-credentials |
Only exists if you chose a local database, and only until you delete it. |
The application source itself does not need backing up — you can re-extract it from the release archive — but vendor/ and public/build are faster to restore than to rebuild if you have them.
Taking a backup #
A workable nightly routine, run as root:
#!/bin/bash
set -e
STAMP=$(date +%F)
DEST=/var/backups/rackhelm/$STAMP
mkdir -p "$DEST"
# Read the credentials out of .env rather than duplicating them here.
cd /var/www/rackhelm
DB_NAME=$(grep '^DB_DATABASE=' .env | cut -d= -f2-)
DB_USER=$(grep '^DB_USERNAME=' .env | cut -d= -f2-)
DB_PASS=$(grep '^DB_PASSWORD=' .env | cut -d= -f2-)
mysqldump --single-transaction --routines --triggers
-u "$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$DEST/database.sql.gz"
cp .env "$DEST/env"
tar -czf "$DEST/storage.tar.gz" -C /var/www/rackhelm storage/app
chmod -R 600 "$DEST"
--single-transaction keeps the dump consistent without locking the tables, so the portal stays usable while it runs.
Warning: The dump and the copied
.envcontain database passwords, the encryption key and your licence key. Store them with the same care as the server itself — restricted permissions, encrypted off-site copy, and never in a world-readable directory.
Tip: Copy the backup off the server. A backup that lives only on the machine it protects is not a backup.
Restoring #
Restoring onto a rebuilt server, in order:
- Build a matching platform. Same OS family, same PHP version with the ionCube Loader active, Redis, nginx. The quickest route is to run the installer with the local-database option so all the packages, the nginx site and the Supervisor program are created for you.
- Stop the worker so it cannot process jobs against a half-restored database:
sudo supervisorctl stop rackhelm-horizon - Restore the database. Create an empty database, then load the dump:
gunzip -c database.sql.gz | mysql -u root -p rackhelm - Restore
.env. Copy the backed-up file into place, then correctDB_PASSWORDif the rebuilt server generated a new one, andAPP_URLif the hostname changed. Do not changeAPP_KEY.chown root:www-data /var/www/rackhelm/.env chmod 640 /var/www/rackhelm/.env - Restore storage. Unpack
storage.tar.gzover/var/www/rackhelm, then fix ownership:chown -R www-data:www-data /var/www/rackhelm/storage chmod -R u=rwX,g=rX,o= /var/www/rackhelm/storage sudo -u www-data php artisan storage:link - Bring the schema up to date if the backup came from an older release:
sudo -u www-data php artisan migrate --force - Re-add the scheduler cron entry and restart the worker:
sudo supervisorctl start rackhelm-horizon
After a restore #
- Sign in to the admin area and open a payment gateway and a server integration. If the credentials display correctly,
APP_KEYis right. - Check Schedules — the last-run times will be stale until cron fires; confirm they start moving.
- Check the licence. A new server means a new hardware fingerprint, so arrange rebinding with support if the check fails. See Licensing and activation.
- If the portal’s hostname changed, update
APP_URL, the Company URL setting, the nginxserver_nameand the certificate.
Troubleshooting #
| Symptom | Cause and fix |
|---|---|
| Gateway or integration credentials look like random text, or fail to decrypt | APP_KEY does not match the one in force when they were saved. Restore the original key from the backed-up .env. |
| Invoices and ticket attachments 404 after a restore | storage/app/private was not restored, or ownership was not reset to the web-server user. |
| Logos and page images 404 | The public/storage symlink was lost. Re-run php artisan storage:link. |
| Nothing recurring runs on the restored server | The crontab was not restored — it is not part of the application tree. Re-add the schedule:run entry. |
| Jobs from before the outage never resume | Queued jobs live in Redis, not the database, and are not covered by this backup. Anything in flight when the server died is gone; re-drive it from the admin retry actions. |
| Licence rejected on the restored box | New IP address or hostname. The fingerprint changed — contact support. |