View Categories

Backing Up and Restoring

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_KEY on a live install, and never let a restore run against a fresh .env with 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 .env contain 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:

  1. 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.
  2. Stop the worker so it cannot process jobs against a half-restored database:
    sudo supervisorctl stop rackhelm-horizon
  3. Restore the database. Create an empty database, then load the dump:
    gunzip -c database.sql.gz | mysql -u root -p rackhelm
  4. Restore .env. Copy the backed-up file into place, then correct DB_PASSWORD if the rebuilt server generated a new one, and APP_URL if the hostname changed. Do not change APP_KEY.
    chown root:www-data /var/www/rackhelm/.env
    chmod 640 /var/www/rackhelm/.env
  5. Restore storage. Unpack storage.tar.gz over /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
  6. Bring the schema up to date if the backup came from an older release:
    sudo -u www-data php artisan migrate --force
  7. Re-add the scheduler cron entry and restart the worker:
    sudo supervisorctl start rackhelm-horizon

After a restore #

  1. Sign in to the admin area and open a payment gateway and a server integration. If the credentials display correctly, APP_KEY is right.
  2. Check Schedules — the last-run times will be stale until cron fires; confirm they start moving.
  3. Check the licence. A new server means a new hardware fingerprint, so arrange rebinding with support if the check fails. See Licensing and activation.
  4. If the portal’s hostname changed, update APP_URL, the Company URL setting, the nginx server_name and 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.