# Verified compose for Kopia backup benchmark, tested 2026-10-19 by the SelfHostBench lab (3 runs; the figures are the median). # Lab host: INTEL(R) XEON(R) PLATINUM 8573C, 2 vCPU, 7.8 GiB RAM, x86_64, Docker 28.0.4. # Floating image tags below were replaced by the version resolved at test time; # the registry digest is in the comment on each image line. # Measurements: backup-kopia.json (schema 3). # Companion env file: backup-kopia.env (save it as .env next to this file). # Secrets are not published: the lab's values are public. In backup-kopia.env: # KOPIA_PASSWORD is commented out. Uncomment it and set your own value (the comment above it explains how). # Kopia 0.23.1: a backup program with a command line and a web interface. This is the container the SelfHostBench backup benchmark runs Kopia in, with a local repository on a Docker volume. # The benchmark uses the command line (`kopia snapshot create`), not `kopia server`. The container only stays up (sleep) so that you can run `docker exec kopia kopia ...`, or point a cron job or a # systemd timer at it. Kopia can also run its own scheduler (`kopia server start`, see kopia.io/docs/installation/#docker-images); that is not what is measured here. # # Follows the official image's documentation (kopia.io/docs/installation/#docker-images): the image, the three directories /app/config, /app/cache and /app/logs, KOPIA_PASSWORD. Differences, # all marked below: a pinned tag, the entrypoint replaced by `sleep infinity`, named volumes instead of ./paths, the password from .env. # # Quick start (after putting a long random KOPIA_PASSWORD in .env): # docker compose up -d # docker compose exec kopia kopia repository create filesystem --path /repo # once; AES256-GCM-HMAC-SHA256, no compression unless you set a policy # docker compose exec kopia kopia snapshot create /data/src # then again whenever you like: only changes are stored # docker compose exec kopia kopia snapshot list /data/src --manifest-id # the manifest id is what you give to restore # docker compose exec kopia kopia snapshot restore /restore # Local repository only. A repository on the same disk as your data is not a backup: use another disk, another machine (sftp, webdav, rclone) or object storage (s3, b2, gcs, azure). name: kopia services: kopia: image: kopia/kopia:0.23.1 # sha256:89fd95ee2942880ca00eae964266958a394421ddbdf69bca62e38afc55f5900e (version 0.23.1, from exec) # The image's entrypoint is `kopia` itself. Replaced here so the container stays up; remove this line to run `docker run --rm kopia/kopia ...` one command at a time. entrypoint: ["sleep", "infinity"] # Kopia identifies a snapshot source as user@host:/path. A fixed host name keeps the history of a source together when the container is recreated. hostname: backup-host restart: unless-stopped environment: # Encrypts the repository. Set in .env. If you lose it the backups cannot be opened: store it somewhere that is NOT the backed-up machine (a password manager). KOPIA_PASSWORD: "${KOPIA_PASSWORD:?set KOPIA_PASSWORD in .env}" # The image already sets KOPIA_CONFIG_PATH=/app/config/repository.config, KOPIA_CACHE_DIRECTORY=/app/cache, KOPIA_LOG_DIR=/app/logs and KOPIA_CHECK_FOR_UPDATES=false. volumes: # What to back up. In real use mount your own data read-only instead, for example `- /srv/photos:/data/photos:ro`. (The lab test changes files in this volume to simulate a second day.) - data:/data # The repository. In real use this should be on another disk or machine. - repo:/repo # Where `kopia snapshot restore` writes. - restore:/restore # The connection to the repository (which repository, and the settings), the local cache and the logs, as in the official documentation. - kopia-config:/app/config - kopia-cache:/app/cache - kopia-logs:/app/logs healthcheck: # Kopia is a command, not a service, so this only checks that the binary is there; the container is "healthy" a few seconds after the start. test: ["CMD", "test", "-x", "/bin/kopia"] interval: 5s timeout: 3s start_period: 2s retries: 3 volumes: data: repo: restore: kopia-config: kopia-cache: kopia-logs: