# A deployment of the KeepOrg server, showing the thing that is easiest to # get wrong: where the master key comes from, and that it does not live in # the data volume. # # head -c 32 /dev/urandom | base64 > master.key # once; keep a copy safe # chmod 600 master.key # podman-compose up -d # or docker compose up -d # # The key is provisioned as a secret and named to the server with # KEEPORG_MASTER_KEY_FILE, so it is never in the process environment and # never on a disk the container can write. Without a key the server still # runs and still synchronizes; it only refuses to create or merge vaults. services: keeporgd: # `make docker` tags both the version from versions.mk and :latest. # Pin with KEEPORG_VERSION in production. image: keeporgd:${KEEPORG_VERSION:-latest} build: context: ../.. args: # Only used when compose builds the image itself; `make docker` # stamps the real version. VERSION: "${KEEPORG_VERSION:-dev}" restart: unless-stopped # Terminate TLS in front of this, and set external_url to the address a # browser sees: invite links, device approval and the OIDC redirect are # built from it. command: - "-addr=:8765" - "-data=/var/lib/keeporg" - "-url=https://keeporg.example.com" ports: - "127.0.0.1:8765:8765" secrets: - keeporg_master_key environment: KEEPORG_MASTER_KEY_FILE: /run/secrets/keeporg_master_key # The alternative, when the key comes from a store that injects # variables rather than files. One or the other, not both. # KEEPORG_MASTER_KEY: "${KEEPORG_MASTER_KEY:-}" # # Only read on the very first start, when no accounts exist yet. KEEPORG_ADMIN_PASSWORD: "${KEEPORG_ADMIN_PASSWORD:-}" volumes: - keeporg-data:/var/lib/keeporg # The server writes one directory and needs no privileges at all. read_only: true cap_drop: ["ALL"] security_opt: ["no-new-privileges:true"] user: "65532:65532" secrets: keeporg_master_key: file: ./master.key volumes: keeporg-data: