---
title: Updating RackHelm
description: "A RackHelm update replaces the application files, brings the database schema up to date, rebuilds the front-end assets and restarts the background worker. There is no self-updater — you run the steps yourself, in a fixed order, and the order…"
url: "https://rackhelm.com/documentation/updating-rackhelm/"
updated: "2026-09-24"
category: "Installation & Server Setup"
---

# Updating RackHelm

A RackHelm update replaces the application files, brings the database schema up to date, rebuilds the front-end assets and restarts the background worker. There is no self-updater — you run the steps yourself, in a fixed order, and the order matters.

## Before you start

- Take a full backup. See [Backing up and restoring](/docs/backup-and-restore/). Migrations change the schema and are not always reversible.
- Read the release notes for the version you are moving to. A major version number change signals a breaking change to the installer or to an integration contract, or a migration that cannot be rolled back cleanly.
- Pick a quiet window. Provisioning, payments and invoicing all stop while the worker is down.

> **Warning:** Do not update straight onto a production box you have not backed up. If a migration fails halfway you are left with a partially applied schema, which is far harder to recover from than a restore.

## The update, in order

### 1. Put the site into maintenance mode

```bash
cd /var/www/rackhelm
sudo -u www-data php artisan down
```

Customers see a maintenance page instead of a half-migrated portal.

### 2. Back up

```bash
mysqldump --single-transaction --routines --triggers rackhelm > /root/rackhelm-pre-update.sql
tar -czf /root/rackhelm-pre-update.tar.gz -C /var/www rackhelm
```

### 3. Replace the application files

Extract the new release over the existing tree, keeping `.env`, `storage/` and the `public/storage` symlink:

```bash
tar -xzf rackhelm-1.1.0.tar.gz -C /var/www/rackhelm --strip-components=1
```

Then clear the compiled caches that may have travelled inside the archive or been left by the previous build:

```bash
rm -f bootstrap/cache/packages.php bootstrap/cache/services.php bootstrap/cache/config.php
```

> **Note:** Skipping this step is the usual cause of `Class LaravelPailPailServiceProvider not found` immediately after an update — a manifest generated when development dependencies were present, loaded by a build that no longer has them.

### 4. Update the PHP dependencies

```bash
composer install --no-dev --optimize-autoloader
```

### 5. Rebuild the front end

```bash
npm install
npm run build
```

Skipping this leaves the browser loading asset files the new templates no longer reference, which usually shows up as an unstyled page or a dead button rather than an error.

### 6. Run the migrations

```bash
sudo -u www-data php artisan migrate --force
```

`--force` is required because the application is in the `production` environment.

### 7. Rebuild the view cache

```bash
sudo -u www-data php artisan view:clear
sudo -u www-data php artisan view:cache
```

> **Warning:** Never run `php artisan optimize`, `route:cache` or `config:cache` on RackHelm. Route caching serialises closure-based routes, and closure serialisation needs PHP source that the ionCube encoder removes — the cached routes then fail at runtime with `Call to a member function bindTo() on null`. Config caching freezes the licence key, which is read from `.env` at runtime. View caching is the only one that is safe, because Blade templates ship as plain text.

### 8. Re-apply permissions

Extracting an archive as root leaves new files root-owned. Restore the ownership model (use `nginx` on RHEL):

```bash
chown -R root:www-data /var/www/rackhelm
chmod -R u=rwX,g=rX,o= /var/www/rackhelm
chown -R www-data:www-data storage bootstrap/cache
chmod -R u=rwX,g=rX,o= storage bootstrap/cache
chown root:www-data .env
chmod 640 .env
```

### 9. Restart the background worker

```bash
sudo -u www-data php artisan horizon:terminate
```

Horizon holds the code it started with, so without this the queue keeps running the previous build. Supervisor restarts it automatically. Confirm with `supervisorctl status rackhelm-horizon`.

### 10. Reload PHP-FPM

```bash
sudo systemctl reload php8.5-fpm
```

OPcache holds compiled files in memory keyed by path and modification time. A reload guarantees the new code is picked up rather than relying on OPcache noticing.

### 11. Bring the site back

```bash
sudo -u www-data php artisan up
```

## After the update

1. Load the portal front page and sign in to the admin area.
2. Check the version in the admin sidebar footer matches the release you installed.
3. Open the Horizon dashboard and confirm workers are running and no jobs are failing.
4. Skim `storage/logs/laravel.log` for new errors.
5. Place a small test order end to end if the release touched checkout or provisioning.

## If something goes wrong

The safe rollback is a restore, not a partial undo — a database that has been migrated forward will not work with the previous code. Restore the database dump and the file tree from step 2 together, then restart the worker and PHP-FPM. If the failure happened before the migrations ran, restoring the files alone is enough.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| `Class LaravelPailPailServiceProvider not found` | Stale `bootstrap/cache/packages.php`. Delete the three cache files and re-run `composer install --no-dev`. |
| `Call to a member function bindTo() on null` | Someone ran `route:cache` or `optimize`. Run `php artisan route:clear` and never run those commands again on this platform. |
| Licence key appears empty after an update | `config:cache` was run and froze the value. Run `php artisan config:clear`. |
| Pages render unstyled | `npm run build` was skipped, or `public/build` is root-owned and unreadable by the web-server user. |
| Background jobs still show old behaviour | Horizon was not restarted. Run `php artisan horizon:terminate`. |
| Permission-denied errors writing logs or uploads | Step 8 was skipped. `storage` and `bootstrap/cache` must be owned by the web-server user. |
| Migration fails partway through | Stop. Restore the database dump rather than re-running — a partially applied batch is what makes recovery hard. |
