Skip to Content
Updates & MaintenanceManual Update & Rollback

Manual Update & Rollback

SeqDesk does not keep a .update-backup/ directory. Every release lives in its own directory and the live application is whichever release the current/ symlink points at. Rolling back means pointing current/ at a previous release — there is no file restoration step.

The thing an operator actually needs to know before rolling back is what happens to the database. The short answer is nothing: a rollback moves a symlink. The long answer is below.

Release layout

A release-layout install is organised under a single root directory:

<root>/ current -> releases/1.1.125 # atomic symlink to the live release releases/ 1.1.124/ # previous release (kept for rollback) 1.1.125/ # active release settings.json # shared config, symlinked into each release data/ # shared, symlinked into each release pipelines/ # shared pipeline_runs/ # shared backups/ # pre-update pg_dump files start.sh # wrapper -> current/start.sh .update-state.json # phase, previous/target/active release .update-status.json # last reported progress .update-lock # present while an update is running .seqdesk-bind-host # persisted SEQDESK_BIND_HOST, mode 600

data/, pipelines/, pipeline_runs/ and settings.json live at the root and are symlinked into each release, so they are shared across versions and survive updates and rollbacks. Inside a release, settings.json is a relative symlink (../../settings.json).

Never replace releases/<version>/settings.json with a real file. The application writes configuration through that symlink, so a real file silently splits the live config in two and is discarded at the next update. Edit <root>/settings.json instead.

Installs that predate the canonical filename keep using seqdesk.config.json instead; the installer deliberately reuses whichever of the two names already exists, so an upgrade never ends up with both.

The root start.sh is a thin wrapper that cds into current/ and runs that release’s start.sh, which ends in exec node server.js. Because it resolves current/ at launch, restarting after a symlink swap is all that is needed to change versions.

Run seqdesk doctor to diagnose a broken install — it reports on the layout, the current/ symlink target, database connectivity, and the HTTP endpoint.

Rollback

From Settings → Info → Software Updates, use Roll back release. This calls POST /api/admin/updates/rollback, which re-points current/ at the release recorded as previousRelease in .update-state.json and restarts the application. The button appears whenever a previous release is recorded — in practice, after a failed update.

Rollback goes one step back, to the release that was active before the last update. It is not a version picker: .update-state.json records a single previous release, and each rollback overwrites it with the release you are leaving. To reach an older version than that, use the manual swap below.

The route refuses, with the reason shown in the panel, when:

MessageCause
Rollback is only available for release-layout installations.There is no current/ symlink — this is a flat install
No previous release is recorded for rollback (409).update-state.json has no previousRelease, usually because no update has ever run here
Previous release is missing: <path>The recorded directory was deleted
SeqDesk is already running the recorded previous release.Nothing to do
Update already in progress (409)The update lock is held

If the in-app action is unavailable — the app will not start, or you need to go back further than one release — re-point the symlink by hand.

Stop the server

# pm2 pm2 stop seqdesk # user systemd service systemctl --user stop seqdesk # system systemd service sudo systemctl stop seqdesk

From the install root, point current at the prior release directory:

cd /opt/seqdesk ls releases/ # e.g. 1.1.123 1.1.124 1.1.125 ln -sfn releases/1.1.124 current # atomic replace of the symlink

ln -sfn replaces the link atomically. Do not rm current first — that leaves a window in which the wrapper script has nothing to cd into.

Restart the server

./start.sh

Or via your process manager (pm2 restart seqdesk, systemctl --user restart seqdesk, or sudo systemctl restart seqdesk).

Confirm

readlink current npx -y seqdesk@latest doctor --dir /opt/seqdesk

What a rollback does to the database

Nothing. A rollback moves a symlink and restarts the process. It does not run migrations, does not drop tables, and does not restore data.

That is usually what you want, and occasionally exactly the problem:

  • Migrations run with prisma migrate deploy and are forward-only. If the release you are rolling away from applied new migrations, the schema is already migrated and stays migrated.
  • An older application version then runs against a newer schema. Prisma tolerates additive migrations (new tables, new nullable columns) well, and does not tolerate destructive ones (dropped or renamed columns the old client still selects) at all.
  • So: rolling back across an additive migration is normally safe. Rolling back across a destructive one requires restoring the database as well.

If you do not know which kind you crossed, compare the prisma/migrations/ directories of the two releases:

diff <(ls /opt/seqdesk/releases/1.1.124/prisma/migrations) \ <(ls /opt/seqdesk/releases/1.1.125/prisma/migrations)

Migrations present only in the newer release are the ones the older code has never seen.

Restoring the pre-update database dump

Before every migration — during both an update and a Retry update repair — the updater writes a best-effort custom-format dump:

<root>/backups/pre-update-<ISO-timestamp>.dump

To restore it, stop SeqDesk first so nothing writes during the restore:

pm2 stop seqdesk # or your service manager pg_restore \ --clean --if-exists \ --dbname "$DATABASE_URL" \ /opt/seqdesk/backups/pre-update-2026-07-27T09-14-02-118Z.dump pm2 start seqdesk

--clean --if-exists drops and recreates the objects in the dump, so the database returns to its pre-migration schema and contents. Everything written since the dump was taken is lost — that is the trade, and it is why the dump is a restore point rather than a backup strategy.

The dump is best-effort. If pg_dump was not available on the server, no dump was written and the update said so in its failure message. ls &lt;root&gt;/backups/ before you rely on one existing.

Manual update

To start an update, use Settings → Info → Software Updates: Check now, review the release, then Install update. That flow downloads, verifies, stages, activates and migrates the new release. It is the only supported update path — see Automatic Updates.

There is no seqdesk update command. Upgrading the npm launcher (npx seqdesk@latest) upgrades the launcher, not an already-installed application.

The following command is configuration-only and deliberately skips the release download:

npx seqdesk@latest -y --reconfigure --dir /opt/seqdesk

Use it to re-apply configuration to an existing install. It leaves the database alone unless you add --reseed-db, which runs prisma migrate deploy and then the seed.

Do not hand-extract tarballs over a live release, and do not use --overwrite-existing as an update substitute — it backs up the whole install directory and replaces it, which is a reinstall, not an upgrade. If the application cannot start, use the manual rollback above to restore the previous release, then retry the built-in update.

Disk usage over time

Old release directories are never pruned automatically. Each one is a full application tree with its own node_modules, so a long-lived install accumulates hundreds of megabytes per release, and the update itself needs 150 MB free before it will start.

Prune by hand, keeping at least the active release and the one before it:

cd /opt/seqdesk readlink current # confirm what is live, e.g. releases/1.1.125 cat .update-state.json # confirm previousRelease rm -rf releases/1.1.120 releases/1.1.121

Deleting the directory named in previousRelease disables one-click rollback: the route then fails with Previous release is missing.

Pre-update dumps in backups/ also accumulate, one per update and per repair. They are the only automatic restore point you have, so prune them on a schedule rather than opportunistically — keep the last few, and rely on your own backup system for anything older.

Backup strategy

The release directories cover application code only, and the pre-update dumps cover only the moment just before a migration. For real disaster recovery:

  • Database — back up PostgreSQL on your own schedule with pg_dump or a snapshot. This is the only copy of orders, samples, studies, users and settings.
  • Configuration — keep a sanitised copy of <root>/settings.json under version control, and the secrets in your secret manager. See Config File Reference.
  • Sequencing data — the shared data/ directory is not managed by SeqDesk; use your own backup system.
  • Pipeline outputs — back up pipeline_runs/ if the results matter; they can be large and are usually reproducible from the inputs.

The Software Updates panel states this plainly: database backups stay operator-managed. SeqDesk applies migrations; it does not own your backups.