# Kvitt development stack on the owner's Mac (SPEC §10 "Development first", D-001). # Not the Pi stack: that is infra/pi/compose.yaml (D-103). # # No Caddy and no TLS here: debug builds accept http:// to private LAN addresses (AC-2.8), so the # server publishes its own port on the Mac. Release builds never talk to this stack. # # Use the scripts next to this file (see infra/README.md): # infra/dev/build.sh build kvitt-server:dev (from server/Dockerfile) and kvitt-backup:dev # infra/dev/up.sh start the server, wait for /health, print the LAN URL # infra/dev/logs.sh follow the logs # infra/dev/backup.sh run the backup job once (local snapshot, no Drive upload) # Relative paths below resolve against this directory (infra/dev/). name: kvitt-dev x-logging: &logging driver: json-file options: max-size: "10m" max-file: "3" services: server: image: ${KVITT_SERVER_IMAGE:-kvitt-server:dev} command: ["serve"] restart: unless-stopped user: "10001:10001" read_only: true cap_drop: [ALL] security_opt: - no-new-privileges:true mem_limit: 160m ports: # The only published port of the dev stack; reachable from the phone on the home Wi-Fi. - "${KVITT_DEV_PORT:-8080}:8080" environment: TZ: Europe/Stockholm KVITT_DATA_DIR: /data KVITT_BIND: 0.0.0.0:8080 # Invite links and the landing page point here; up.sh fills it from the Mac's LAN address when empty. KVITT_PUBLIC_URL: ${KVITT_PUBLIC_URL:-http://localhost:8080} KVITT_FCM_CREDENTIALS: /secrets/fcm-service-account.json KVITT_FCM_PROJECT_ID: ${KVITT_FCM_PROJECT_ID:-kvitt-1337} RUST_LOG: ${RUST_LOG:-info} volumes: # SQLite database, pictures and APKs: a bind-mounted folder on the Mac (git-ignored). - ${KVITT_DEV_DATA_DIR:-./data}:/data # The secrets folder, read-only, so the server finds /secrets/fcm-service-account.json (git-ignored). # The folder is mounted rather than the file: a missing source file would make Docker create a directory # in its place, while a missing key must simply leave push disabled with a start-up warning (§10.4). - ${KVITT_SECRETS_DIR:-../secrets}:/secrets:ro healthcheck: test: ["CMD", "kvitt-server", "healthcheck"] interval: 30s timeout: 5s retries: 3 start_period: 10s logging: *logging networks: [kvitt] backup: image: ${KVITT_BACKUP_IMAGE:-kvitt-backup:dev} # On demand only: `docker compose run --rm backup /backup.sh` (infra/dev/backup.sh). `up` skips it. profiles: [backup] command: ["/backup.sh"] restart: "no" # Same uid as the server, so it can open the WAL database files the server owns. user: "10001:10001" cap_drop: [ALL] security_opt: - no-new-privileges:true mem_limit: 96m environment: TZ: Europe/Stockholm # Empty on the dev stack: the Drive upload is skipped and the local files are kept (§10.9, D-001), so # backup.sh reads no other rclone setting here. RCLONE_FOLDER_ID: "" volumes: - ${KVITT_DEV_DATA_DIR:-./data}:/data - ${KVITT_DEV_BACKUP_DIR:-./backups}:/backups logging: *logging networks: [kvitt] networks: kvitt: driver: bridge