Shotstash

Upgrading and rollback

Move to a new release with published images or from source, and go back when you need to.

Every upgrade is the same three steps: back up, get the new version, start it. Migrations run when the app starts, so there is no separate migrate command.

Before version 1.0.0

Until 1.0.0, databases are throwaway: a pre-release upgrade may ask you to start with an empty database and an empty ./data/media. The changelog says so in the release that needs it. Keep a backup of anything you care about.

The migration rule

Every database migration stays compatible with the previous release. After an upgrade the previous version still runs on the upgraded database, which is what makes rollback a matter of starting the older version. A change that cannot follow this rule is a breaking change and ships in a major release with migration notes.

With published images (the default)

Every release publishes ghcr.io/aldyernesto/shotstash and ghcr.io/aldyernesto/shotstash-worker for linux/amd64 and linux/arm64, tagged X.Y.Z, X.Y and latest. A fresh install uses them: docker/init.sh copies the line COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml from .env.example into .env, and the override file docker-compose.images.yml swaps the local builds for these images. Upgrade with:

git pull && docker compose pull && docker compose up -d

IMAGE_TAG in .env picks the release (default latest). Pin IMAGE_TAG=1.4 to get fixes but no new minor version, or IMAGE_TAG=1.4.2 to change nothing until you edit it. Image tags have no leading v: the git tag v0.3.0 is the image tag 0.3.0.

Release versus main

latest is the newest release. main, which git pull fetches, can be ahead of it, with compose files for changes no release has shipped yet; git pull does not keep the checkout in step with the images. For a stable install, run the checkout and the images at the same release:

git fetch --tags && git checkout v0.3.0
# in .env:
IMAGE_TAG=0.3.0
docker compose pull && docker compose up -d

To upgrade such an install later, check out the new tag, set IMAGE_TAG to the same version without the v, and pull again.

Installed before the images were the default?

docker/init.sh never touches an existing .env. Without a COMPOSE_FILE line, docker compose up -d keeps running the image you built earlier; only docker compose up -d --build rebuilds it from the new code. To switch to the published images, add both lines to your .env, then run the upgrade command above:

COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml
COMPOSE_PATH_SEPARATOR=:

Using a docker-compose.override.yml?

While COMPOSE_FILE is set, Compose no longer loads docker-compose.override.yml by itself. Append it to the list: COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml:docker-compose.override.yml. Entries are relative paths separated by :, with no Windows drive letters.

From source

With COMPOSE_FILE=docker-compose.yml in .env (see Build from source), compose builds both images from your checkout:

git pull
docker compose up -d --build

To move to a specific release instead of the latest commit, check out its tag first (git checkout v1.4.2).

Upgrade notes

Read the release notes before you upgrade. Notes that apply to existing installs:

  • Processing worker: before pulling a version that has the worker service, add WORKER_BOOTSTRAP_TOKEN to your .env (openssl rand -hex 32, its own value). Docker compose refuses to start without it.
  • Storage keys: from migration 0006_storage_keys_uploads on, files live under hierarchy-free keys and older bytes are not moved. Reset pre-1.0 development data after upgrading (an empty database and ./data/media).

Rollback

  1. Stop the app: docker compose stop app worker.
  2. Start the previous version:
    • with images, pin IMAGE_TAG to the previous release in .env, without the v (for example IMAGE_TAG=0.2.0 for git tag v0.2.0), check out that tag (git checkout v0.2.0), then docker compose up -d;
    • from source, git checkout v<previous> and docker compose up -d --build.
  3. Check docker compose ps and sign in.

Because of the migration rule, the previous release runs on the database as it is. If you skipped several releases and something is wrong, restore the backup you took before the upgrade instead (see Backup and restore).

Checking the running version

GET /api/health answers { ok, setupRequired, version }, and a super admin sees the version, storage, database, cache, live workers and queued jobs at /status.

How releases are cut and what gets published: Releasing.

On this page