Upgrade and backup
Run everything here from the install directory (~/railhook by default) with the railhook helper the installer wrote.
Upgrade
Section titled “Upgrade”cd ~/railhook./railhook upgrade v2.16.6 # pin a release; with no version it keeps the tags already in .envupgrade runs these steps in order:
- Fetches the helper and the Caddyfile for the target release.
- Pins
API_IMAGE_TAG,WORKER_IMAGE_TAGandUI_IMAGE_TAGin.env. - Takes a database backup, and stops if that fails.
- Replaces
docker-compose.ymlwith the release’s copy and keeps yours asdocker-compose.yml.previous. - Pulls the images and restarts the database, cache and dashboard.
- Replaces the API containers one at a time. The new API runs the release’s migrations.
- Restarts the worker once the new API is serving.
A new worker does not start on an unmigrated schema. If it starts before the API has migrated (for example ./railhook start after a tag change), it waits up to 15 minutes and logs Waiting for the API to migrate the schema.
With one API container, clients see about twenty seconds of 502 during the swap. API_REPLICAS=2 in .env removes the gap.
Roll back
Section titled “Roll back”Rolling back returns the images, not the database schema. Migrations only run forward.
sed -i 's|^API_IMAGE_TAG=.*|API_IMAGE_TAG=2.16.5|' .env # and WORKER_IMAGE_TAG, UI_IMAGE_TAG./railhook startA code problem needs only the old images. A migration problem needs the backup the upgrade took.
Check an installation
Section titled “Check an installation”./railhook doctorRe-runs the installer’s machine and configuration checks against the files on disk, so a bad hand edit to .env shows up before an outage.
Back up
Section titled “Back up”./railhook backupWrites backup-<timestamp>.dump (PostgreSQL custom format) into the install directory. Installer-made installations also take scheduled dumps through the db-backup service:
| Variable | Default | Meaning |
|---|---|---|
DB_BACKUP_INTERVAL_SECONDS |
86400 |
How often a dump is taken |
BACKUP_RETENTION_DAYS |
30 |
How long dumps are kept |
BACKUP_DIR |
./backups |
Where they are written |
Restore
Section titled “Restore”-
Stop the API and the worker
Terminal window cd ~/railhookset -a; . ./.env; set +adocker compose stop api worker -
Restore the dump
Terminal window docker cp backup-20260913T020000Z.dump webhook-postgres:/tmp/restore.dumpdocker exec webhook-postgres pg_restore \-U "${POSTGRES_USER:-webhook_user}" -d "${POSTGRES_DB:-webhook_platform}" \--clean --if-exists --no-owner --no-privileges /tmp/restore.dumpdocker exec webhook-postgres rm -f /tmp/restore.dump -
Flush Redis
Redis holds only derived data that rebuilds itself. A stale cache is worse than an empty one.
Terminal window docker exec webhook-redis redis-cli -a "$REDIS_PASSWORD" FLUSHALL -
Start the stack
Terminal window ./railhook start
After a restore, pending deliveries are claimed on the worker’s next poll. Deliveries that were in progress when the dump was taken are claimed again once their claim times out (WEBHOOK_CLAIM_TIMEOUT_SECONDS, 300 by default), so an endpoint may receive such an attempt twice. Events accepted after the dump are lost.