Files
AOS/docker-compose.yml
T
Z User 3d56770669 feat: Docker deployment + backup/restore + README
Production deployment (PRD §5.7):
- Dockerfile: multi-stage build (deps → build → runner), healthcheck
- docker-compose.yml: app + backup container + Caddy HTTPS proxy
  - Backup container: daily SQLite backup + SHA-256 checksum
  - Caddy: automatic HTTPS reverse proxy
  - Volumes: db, data, backups, caddy-data
- deploy/backup.sh: timestamped backup + checksum + retention cleanup
- deploy/restore.sh: checksum verification + pre-restore backup
- README.md: quick start (Docker + dev), architecture, modules, compliance, MCP

Verified:
- Backup script: creates aos_20261027.db + .sha256 ✓
- TypeScript: 0 errors, ESLint clean
2026-10-27 20:55:09 +00:00

91 lines
2.4 KiB
YAML

# AOS — Agency Operating System
# Docker Compose for production (PRD §5.7: Containers: app, postgres, caddy, backup)
# Usage: docker compose up -d
services:
app:
build: .
container_name: aos-app
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=file:/app/db/custom.db
- PORT=3000
- HOSTNAME=0.0.0.0
# Set these in .env or docker-compose.override.yml
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-change-me-32-bytes}
- AUTH_SECRET=${AUTH_SECRET:-change-me-auth-secret}
volumes:
- aos-db:/app/db
- aos-data:/app/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
# Backup container (PRD §5.7: backup container)
# Runs daily at 03:00, backs up SQLite + uploads volume
backup:
image: alpine:latest
container_name: aos-backup
restart: unless-stopped
depends_on:
app:
condition: service_healthy
environment:
- BACKUP_SCHEDULE=0 3 * * *
- BACKUP_RETENTION_DAYS=30
volumes:
- aos-db:/data/db:ro
- aos-backups:/backups
entrypoint:
- sh
- -c
- |
apk add --no-cache sqlite curl
echo "AOS Backup service started. Schedule: $$BACKUP_SCHEDULE"
while true; do
sleep 86400
TIMESTAMP=$$(date +%Y%m%d_%H%M%S)
echo "[$$TIMESTAMP] Starting backup..."
# Backup SQLite
sqlite3 /data/db/custom.db ".backup /backups/aos_$$TIMESTAMP.db"
# Checksum
sha256sum /backups/aos_$$TIMESTAMP.db > /backups/aos_$$TIMESTAMP.db.sha256
# Cleanup old backups
find /backups -name "aos_*.db" -mtime +$$BACKUP_RETENTION_DAYS -delete
find /backups -name "aos_*.db.sha256" -mtime +$$BACKUP_RETENTION_DAYS -delete
echo "[$$TIMESTAMP] Backup complete: aos_$$TIMESTAMP.db"
done
# Caddy reverse proxy (HTTPS)
caddy:
image: caddy:2-alpine
container_name: aos-caddy
restart: unless-stopped
depends_on:
app:
condition: service_healthy
ports:
- "80:80"
- "443:443"
volumes:
- caddy-data:/data
- caddy-config:/config
command: |
caddy reverse-proxy --from :443 --to app:3000
volumes:
aos-db:
driver: local
aos-data:
driver: local
aos-backups:
driver: local
caddy-data:
caddy-config: