Upgrading
Take a backup, pull the new image and start a new container from it. Migrations run forwards and refuse to open a database from the future.
With docker compose:
docker compose exec trckable trckabled backup # a copy to go back to, just in case
docker compose pull
docker compose up -dWith plain docker run, the container is replaced (the volume keeps everything):
docker exec trckable trckabled backup # a copy to go back to, just in case
docker pull ghcr.io/trckable/trckable:latest
docker stop trckable && docker rm trckable
docker run -d --name trckable -p 8080:8080 -v trckable-data:/data \
-e TRCKABLE_BASE_URL=https://stats.example.com --restart unless-stopped \
ghcr.io/trckable/trckable:latestdocker restart alone is not an upgrade: a container keeps the image it was
created from. On Railway, redeploy the service.
Every release is free, for good: every fix and every feature reaches self-hosters. What changed in each one is in the changelog.
What happens
- The old process gets SIGTERM. It answers new events with 503 and a
Retry-After— the tracker keeps them and sends them on a later page (not in cookieless mode, which keeps nothing) — then drains, flushes and checkpoints. Give it 30 seconds. - The new process opens the control database and runs any migrations.
- The listener comes up before the analytics database has finished migrating, so events and webhooks are being accepted while that happens. The dashboard says "warming up" for those few seconds.
No event the server accepted is lost in any of this. It is the same path as the crash tests CI runs on every change: 20,000 events through a kill -9 and 20,000 through a graceful restart, 0 lost and 0 duplicated.
Downgrading
Migrations are forward-only, and an older binary refuses to open a newer database rather than damaging it. To go back, restore the backup you took before the upgrade (see backups).
Between versions
- The browser script is cached for an hour, so visitors pick up a new tracker within the hour. Nothing breaks in the meantime; events from an older script are still valid.
- The dashboard is served by the same binary, so it can never be out of step with the API.
Checking the result
Settings → Health shows the running version, and so does every response, in
the X-Trckable-Version header. Compare it with the latest release in the
changelog.