# Vaultwarden — the Bitwarden-compatible server behind Officer's vault sidecar.
#
# Every request reaches it through us: app → /api/vault → officer-vault → here. Nothing else should be
# able to, which is why the port below is loopback-only.
name: officer-vault

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: officer-vault
    restart: unless-stopped

    user: '${OFFICER_UID}:${OFFICER_GID}'

    environment:
      - TZ=${OFFICER_TZ}
      # Argon2 hash of a token setup.sh generated. The plaintext is printed once, to the installer, and
      # never written to disk here — a compose file is not a secret store, and this one sits in a
      # directory the user is encouraged to read.
      - ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN_HASH}
      # Closed by default. An open Vaultwarden on a machine the owner just handed a password manager to
      # is the wrong default at every scale, and the owner can open it from the admin page if they want.
      - SIGNUPS_ALLOWED=false
      # WebSocket notifications, so the Bitwarden clients get live sync rather than polling.
      - WEBSOCKET_ENABLED=true

    ports:
      # Loopback only, always. This is a password vault: the only thing that should reach it is the
      # sidecar on this host, and publishing it on all interfaces would put it on the network.
      - '127.0.0.1:${VAULTWARDEN_PORT}:80'

    volumes:
      # Holds the SQLite database, the attachments and the RSA keys. Bind-mounted rather than a named
      # volume so the owner can see — and back up — exactly where their passwords live.
      - ./data:/data
