# Docker Service Deployment Standard (IT Pro Partner) This reference documents the standard for deploying Docker services on ITP infrastructure. ## Directory Structure ``` ~/docker// ├── docker-compose.yml ← Pinned image tags (never :latest) ├── .env ← Secrets only (never in compose file) ├── data/ ← Persistent volumes on disk (backed up by S3) ├── CHANGELOG.md ← Every config change documented ``` ## Access: Tailscale-Only Standard 1. Deploy compose in `~/docker//` 2. Verify local: `curl -s http://localhost:/` 3. Open UFW: `ufw allow /tcp` 4. Enable Tailscale Serve for HTTPS: `tailscale serve --bg --https 443 --set-path / http://127.0.0.1:` 5. Set the service's base URL to `https://.tail.ts.net` 6. Test from a Tailscale-connected device 7. Close UFW port: `ufw delete allow /tcp` 8. Log: `bash ~/.hermes/scripts/changelog.sh "Networking" "Tailscale Serve for at https://..."` ## Vaultwarden-Specific Notes - DOMAIN env var must match the access URL exactly. Wrong protocol (http vs https) causes the web vault to hang on a spinner silently. - Registration is disabled by default (`SIGNUPS_ALLOWED=false`). Enable it temporarily for first-user setup, then lock it. - Admin panel at `/admin` uses the `ADMIN_TOKEN` from `.env`. - Tailscale hostname with `0` vs `O` confusables: the Bitwarden mobile app may silently corrupt zero characters in the URL during text input. Fix: rename the Tailscale node before deploying: `tailscale set --hostname vaultwarden`. Then re-create Tailscale Serve (turn off, re-enable — it picks up the new hostname). No zeros, no letter-O confusion. - Bitwarden app fails with "not a recognized Bitwarden server": always the DOMAIN/access-URL mismatch. Verify via `curl https:///api/config` — the `identity` field must match exactly what the app connects to. ## Backup - Compose files and .env are synced to S3 every 15 min via `hermes-live-sync` - For data directories: same sync includes `~/docker/*/data/*` - RPO: < 15 min for both config and data