Skip to content

Upgrading

For whoever is running the desk.

One command

Terminal window
sixnix-deskctl upgrade

That is the whole thing. In order, it:

  1. Says which release this desk is on.
  2. Fetches the published compose file and Caddyfile and shows you any difference rather than writing over yours, because a compose file somebody has edited is a compose file somebody meant.
  3. Takes a backup, and stops if the backup fails.
  4. Pulls the image and brings the stack up.
  5. Says which release it is on now.

sixnix-deskctl upgrade --dry-run does the first two and nothing else, which is how to see what a release would change before committing an evening to it.

Why it fetches the compose file

It is the half of an upgrade people skip, and the consequences are quiet: a release that adds a volume gets no volume, so whatever was meant to be kept is written inside the container and destroyed by the very next upgrade. That is how a desk ends up with a nightly backup that has reported success every night into a directory that does not exist any more. The desk now refuses to write a backup to such a place, but it cannot refuse on behalf of everything.

Why it backs up first

Migrations change the shape of the database, and some of them convert data. The backup takes the database and the files, and proves the dump whole before it counts: test -s would pass a dump that died half way, because a truncated one still gzips to something perfectly valid.

The desk refuses destructive Artisan commands in production, so the one way to lose data is an unguarded migration on an unbacked database. This is why the upgrade command will not continue past a failed backup.

By hand

The same thing, if you would rather see every step:

Terminal window
sixnix-deskctl backup
curl -O https://registry.sixnix.net/install/docker-compose.yml
curl -o docker/Caddyfile https://registry.sixnix.net/install/Caddyfile
docker compose pull
docker compose up -d
docker compose logs -f web

The web container applies the migrations on start; the queue, scheduler and reverb containers wait for it to report healthy and then come up on the new image. Nothing is left running old code, and no cache needs clearing by hand.

Pinning

DESK_IMAGE=registry.sixnix.net/desk:1.4.0

With a pin, docker compose pull fetches exactly that version and an upgrade is a deliberate edit. With :latest, a pull upgrades you. Pin in production.

What to check afterwards

In the desk: Settings → Health (heartbeat green, queue depth sane), then open a ticket and send a reply. Most upgrade problems are a container that did not come back, not a broken page.

Anybody with the desk already open is told: a strip appears above the page saying a newer version is ready, with a Reload button. They do not have to notice it, a link that would have asked for a bundle the deploy replaced reloads onto the new one by itself.

Rolling back

Set DESK_IMAGE to the previous version and docker compose up -d.

Restore the database snapshot only if a migration ran and you need the old shape back:

Terminal window
zcat pre-upgrade-2026-09-14-0930.sql.gz | docker compose exec -T db mariadb -u root -p"$DB_ROOT_PASSWORD" support
docker compose restart

Restoring throws away everything that happened since the snapshot, which on a live desk means real tickets and real replies. Prefer fixing forward unless the migration itself is the problem.

The module

Each release also produces the Blesta module as a zip. Upload its contents to plugins/support/ on the Blesta install and press Upgrade in Settings → Plugins, an upload alone does not register new actions. Match the module to the desk when a release says to; see The Blesta module.

Release notes

They name anything that needs a decision: a new setting with a default you may want to change, a conversion that runs once, a module version to match. Read them before upgrading rather than after, particularly for anything touching email or the integration API, where a mismatch is visible to clients.

What an upgrade never touches

Checked by upgrading a desk with data in it and comparing both sides, rather than by reasoning about it:

.envbyte-identical. Nothing in the container writes it, it is read through env_file and never opened for writing
The databasedesk-db
Attachments, inbound originals, knowledge uploads, the application keydesk-storage
Queued work and sessionsdesk-cache
Certificatesdesk-tls
Backupsdesk-backups

Everything else in the container, the compiled caches, the nginx and PHP configuration, the public/storage link, is rebuilt on start and is meant to be replaced.

docker compose down -v removes the volumes. It is the one command in this document that destroys a desk, and it is one letter away from the one that does not.