Deployment¶
This page covers running beetkeeper under Docker for real use. It mirrors the setup in the repo's
deploy/ directory, which includes an
example config.yaml (with container paths). beetkeeper reads its settings from that file's optional
top-level beetkeeper section; the rest is an ordinary beets config — see Configuration.
For a throwaway try-it-out run, start with the Quick Start Demo instead.
First-time setup¶
1. Get the image¶
Pull the published image (or build it locally with pants package //:beetkeeper-server-image):
2. Run the server¶
beetkeeper creates its database schema automatically at startup, into the persistent named volume
(beetkeeper-data) — no separate migration step is needed.
services:
beetkeeper:
image: ghcr.io/zach-overflow/beetkeeper:latest
restart: unless-stopped
stop_grace_period: 30s
ports:
- "8337:8337"
environment:
BEETSDIR: /config
volumes:
- /host/path/to/beetsdir:/beets:ro
- /host/path/to/music/downloads:/downloads
- /host/path/to/music/library:/music
- beetkeeper-data:/data
volumes:
beetkeeper-data:
DEPLOY="$(pwd)/deploy"
docker run -d --name beetkeeper \
-e BEETSDIR=/config \
-v /host/path/to/beetsdir:/beets:ro" \
-v /host/path/to/music/downloads:/downloads \
-v /host/path/to/music/library:/music \
-p 8337:8337 \
--stop-timeout 30 \
ghcr.io/zach-overflow/beetkeeper:latest # default CMD is `run`
3. Verify¶
docker logs -f beetkeeper # watch startup
curl -s -o /dev/null -w '%{http_code}\n' localhost:8337/home # 200
Upgrading an existing install¶
When moving to a newer beetkeeper version, pull the new image and restart the server against the same volume:
docker pull ghcr.io/zach-overflow/beetkeeper:latest
docker rm -f beetkeeper # or: docker compose down
docker compose up -d # or the `docker run` command from first-time setup step 2
Any schema migrations the new version brings are applied automatically at startup. Before migrating,
beetkeeper backs up the db file alongside itself (e.g. beetkeeper.db.pre-<revision>.bak on the
beetkeeper-data volume), so you can roll back if an upgrade doesn't go as planned. To manage migrations
manually instead, set database.auto_upgrade: false and use beetkeeper db upgrade — see
Configuration.
Never downgrade the app against a newer database
If the database was written by a newer beetkeeper version, the server refuses to start rather than
downgrade the schema. Restore the matching .bak file (or upgrade beetkeeper) to recover.
Teardown¶
Notes¶
- Config: beetkeeper's settings live under the
beetkeepersection ofconfig.yaml; the same file is the beets config (directory,library, …).BEETSDIRpoints at the directory holding it (beets' own convention), and the file inside must be namedconfig.yaml. - Volumes: mount the config read-only (
:ro); the DB lives on the read-writebeetkeeper-datavolume so it persists across restarts (and holds the automatic pre-migration.bakbackups). - Workers / SQLite: beetkeeper always runs a single server worker process — SQLite is effectively
single-writer, so this is enforced rather than configurable (the old
server.server_workerssetting is ignored, with a warning, if still present). - Local disk only: beetkeeper's database runs in SQLite's WAL mode,
which does not work over network filesystems — keep the data volume holding
database.sqlite_pathon local disk (expect-wal/-shmcompanion files next to the db file).