Upgrading
For whoever is running the desk.
One command
sixnix-deskctl upgradeThat is the whole thing. In order, it:
- Says which release this desk is on.
- 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.
- Takes a backup, and stops if the backup fails.
- Pulls the image and brings the stack up.
- 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:
sixnix-deskctl backup
curl -O https://registry.sixnix.net/install/docker-compose.ymlcurl -o docker/Caddyfile https://registry.sixnix.net/install/Caddyfile
docker compose pulldocker compose up -ddocker compose logs -f webThe 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.0With 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:
zcat pre-upgrade-2026-09-14-0930.sql.gz | docker compose exec -T db mariadb -u root -p"$DB_ROOT_PASSWORD" supportdocker compose restartRestoring 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:
.env | byte-identical. Nothing in the container writes it, it is read through env_file and never opened for writing |
| The database | desk-db |
| Attachments, inbound originals, knowledge uploads, the application key | desk-storage |
| Queued work and sessions | desk-cache |
| Certificates | desk-tls |
| Backups | desk-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.