Skip to content

Updates and backups

New server versions are listed on the releases page with their notes and image tag. Your server checks for them and shows what's new in the dashboard. The check sends only the version you're running.

One-click updates

With a small Watchtower sidecar, you can update from the dashboard with Update now. Watchtower runs in HTTP API mode: it never updates anything on its own, only when Budvo asks with a secret token, and only the container labeled for it.

First, create the token:

terminal
echo "WATCHTOWER_HTTP_API_TOKEN=$(openssl rand -hex 32)" >> .envdocker compose up -d

Then use this compose file:

docker-compose.yml
services:  budvo:    image: git.ronniie.com/nulldaily/budvo:latest    container_name: budvo    restart: unless-stopped    ports:      - "8484:8484"    volumes:      - ./data:/data    environment:      TZ: America/New_York      BUDVO_TRUST_PROXY: "false"      # One-click updates: Budvo asks the watchtower service below.      BUDVO_UPDATER_URL: http://watchtower:8080      BUDVO_UPDATER_TOKEN: ${WATCHTOWER_HTTP_API_TOKEN}    labels:      com.centurylinklabs.watchtower.enable: "true"  # Applies an update only when Budvo asks for one. It never polls on its  # own, and label-enable limits it to the budvo container.  watchtower:    image: nickfedor/watchtower:1.22.3@sha256:2f8f2a9bd21a195b3b650409532a20f6aada8ef5834f00d0d7a999dee0779a81    restart: unless-stopped    volumes:      - /var/run/docker.sock:/var/run/docker.sock    environment:      WATCHTOWER_HTTP_API_ENDPOINTS: update,health      WATCHTOWER_HTTP_API_TOKEN: ${WATCHTOWER_HTTP_API_TOKEN:?set it in .env}      WATCHTOWER_LABEL_ENABLE: "true"      WATCHTOWER_CLEANUP: "true"      TZ: America/New_York    labels:      com.centurylinklabs.watchtower.enable: "false"

Updating by hand

Without the sidecar, update the usual Docker way from the folder with your compose file:

terminal
docker compose pulldocker compose up -d

What happens during an update

  1. A backup first. Before every update, and again before any database migration, Budvo saves a copy of the encrypted database and its keyring to data/backups.
  2. The new image starts and applies any migrations.
  3. It comes back locked. Like any restart, unlock it with your database password in the dashboard. Reminders and syncs resume after that.

Releases marked Breaking need a manual step; read their notes before updating. Releases marked Important should be installed soon.

Backups

Everything Budvo knows lives in the data folder:

  • budvo.db: the encrypted database.
  • keyring.json: the database key, wrapped by your password and by your recovery key.
  • backups/: the automatic copies from before updates and migrations.

Back up the whole data folder with whatever you already use (Hyper Backup, Time Machine, restic, a nightly rsync). A backup is only useful together with keyring.json and your password or recovery key, and useless to anyone who has neither. For a perfectly consistent copy, stop the container first or use the newest file in data/backups.

To move to a new machine, copy data over, start the same compose file and unlock.

Rolling back

If an update misbehaves, go back to the previous version and the backup taken right before the update. Don't run an older version on a database a newer one has already migrated.

terminal
docker compose down# Put the pre-update copy back. Backups are named like# pre-update-0.4.0-to-0.5.0-20261001-140000.db, with a matching .keyring.json.cp data/backups/<backup>.db data/budvo.dbcp data/backups/<backup>.keyring.json data/keyring.jsonrm -f data/budvo.db-wal data/budvo.db-shm

Then pin the previous version in docker-compose.yml. Every release's exact tag is on the releases page:

docker-compose.yml (excerpt)
services:  budvo:    image: git.ronniie.com/nulldaily/budvo:0.4.0     # the version you were on before
terminal
docker compose up -d

Unlock the dashboard and you're back where you were. When a fixed release is out, switch the tag back to latest.