# Vault container — canonical compose file for O1
#
# This is the source-of-truth for how vault.448.global is run. The
# original Portainer-managed compose file (stack 86, /data/compose/86/)
# was lost when Portainer's data volume was reset; this file is the
# reconstructed version, incident-tested 2026-05-06.
#
# Bind-mount source paths on O1 are /home/ubuntu/docker/vault/{...}
# which contain the Raft data, file storage, logs, and Vault config
# (vault.hcl). DO NOT change these paths or the data is orphaned.
#
# See infra/vault/README.md for rebuild procedure.
# See infra/incidents/2026-05-01-vault-container-down.md for the
# incident that produced this file.

services:
  vault:
    image: hashicorp/vault:1.18.5
    container_name: vault
    restart: always
    command: server
    cap_add:
      - IPC_LOCK
      - SETFCAP
    environment:
      # Required because the container runs as the non-root `vault` user
      # (set by the Dockerfile USER directive). A non-root user cannot
      # call setcap on /usr/bin/vault even when CAP_SETFCAP is in the
      # container's bounding set, because Docker doesn't grant ambient
      # capabilities to non-root users by default.
      #
      # Trade-off: with SKIP_SETCAP=true Vault cannot mlockall() to
      # prevent its memory pages being swapped to disk. On the Free A1
      # OCI host with low memory pressure this is unlikely to matter
      # in practice, but it is worth knowing.
      - SKIP_SETCAP=true
    expose:
      - "8200"
    volumes:
      - /home/ubuntu/docker/vault/config:/vault/config
      - /home/ubuntu/docker/vault/file:/vault/file
      - /home/ubuntu/docker/vault/logs:/vault/logs
      - /home/ubuntu/docker/vault/data:/vault/data
    networks:
      - caddy_default
    labels:
      # Opt out of Watchtower auto-updates — image upgrades on Vault
      # must be deliberate, with a snapshot before and a verification
      # after. Watchtower auto-pulling caused the 2026-05-01 incident.
      - com.centurylinklabs.watchtower.enable=false

networks:
  # External network created by the Caddy stack on the same host.
  # Caddy reaches Vault via the container hostname `vault` over this
  # network; no host port is published for Vault.
  caddy_default:
    external: true
