Files
aoc/DEPLOY.md
Tomas Kracmar fe95dfcfce
All checks were successful
Release / build-and-push (push) Successful in 21s
CI / lint-and-test (push) Successful in 25s
docs: update AGENTS.md, README.md, DEPLOY.md, ROADMAP.md for v1.7.14 security features
2026-04-27 16:52:35 +02:00

4.9 KiB

Production Deployment Guide

Overview

AOC runs as a set of Docker containers orchestrated by Docker Compose:

  • nginx — reverse proxy, TLS termination, static file serving
  • backend — FastAPI application (Gunicorn + Uvicorn workers)
  • mongo — MongoDB data store (not exposed externally)
  • valkey — Redis-compatible cache and async job queue (not exposed externally)

Prerequisites

  • Docker Engine 24+ and Docker Compose plugin
  • A server with ports 80/443 reachable from your users
  • TLS certificates (place in nginx/ssl/ or use Let's Encrypt)
  • A valid .env file at the repo root (see .env.example)

Quick start

  1. Clone / pull the latest release

    git checkout v1.7.14
    
  2. Copy and edit environment variables

    cp .env.example .env
    # Edit .env and fill in real credentials
    
  3. Set the release version

    export AOC_VERSION=v1.7.14
    
  4. Deploy

    docker compose -f docker-compose.prod.yml pull
    docker compose -f docker-compose.prod.yml up -d
    
  5. Verify

    curl http://localhost/health
    curl http://localhost/api/events
    

Updating to a new release

export AOC_VERSION=v1.7.14
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d

Enabling HTTPS

Option A: Use your own certificates

  1. Place cert.pem and key.pem in nginx/ssl/

  2. Uncomment the HTTPS server block in nginx/nginx.conf

  3. Uncomment the HTTP → HTTPS redirect server block

  4. Reload nginx:

    docker compose -f docker-compose.prod.yml exec nginx nginx -s reload
    

Option B: Let's Encrypt with Certbot

Replace the nginx service in docker-compose.prod.yml with a Certbot-friendly setup (e.g., use the nginx-proxy + acme-companion stack) or mount the Certbot certificates into nginx/ssl/.

Security Hardening

  • MongoDB is not exposed to the host — only the backend container can reach it.
  • Valkey/Redis is not exposed to the host — only the backend container can reach it.
  • The backend runs as a non-root (aoc) user inside the container.
  • nginx adds security headers (X-Frame-Options, X-Content-Type-Options, etc.).
  • Keep .env out of version control — it is listed in .gitignore.
  • Set AUTH_ENABLED=true and configure AUTH_ALLOWED_ROLES or AUTH_ALLOWED_GROUPS to restrict access to admin/security roles.
  • Set explicit CORS_ORIGINS — do not use * in production when auth is enabled.
  • Set DOCS_ENABLED=false to hide OpenAPI docs (/docs, /openapi.json).
  • Configure WEBHOOK_CLIENT_SECRET to validate Graph webhook notifications.
  • Set LLM_ALLOWED_DOMAINS if using AI features (e.g. api.openai.com,*.openai.azure.com).
  • Set SIEM_ALLOWED_DOMAINS if using SIEM forwarding.
  • Review METRICS_ALLOWED_IPS — defaults to private networks + loopback.

Azure Key Vault (Optional)

To eliminate long-lived secrets from .env:

  1. Create an Azure Key Vault and add these secrets:

    • aoc-client-secret — your Graph app CLIENT_SECRET
    • aoc-llm-api-key — your LLM_API_KEY (if using AI)
    • aoc-mongo-uri — your MONGO_URI
    • aoc-webhook-client-secret — your WEBHOOK_CLIENT_SECRET
  2. Uncomment azure-identity and azure-keyvault-secrets in backend/requirements.txt

  3. Set AZURE_KEY_VAULT_NAME=your-keyvault-name in .env

  4. Grant the container identity Get permission on secrets:

    • If using Azure Container Instances / AKS: assign a managed identity
    • If using VM: assign a managed identity or use a service principal
    • If using local Docker: authenticate via az login on the host
  5. Rebuild and redeploy:

    docker compose -f docker-compose.prod.yml up -d --build
    

Rollback

export AOC_VERSION=v1.7.13
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d

Monitoring

  • Prometheus metrics: http://your-host/metrics (IP-restricted by default)

  • Health check: http://your-host/health

  • Container logs:

    docker compose -f docker-compose.prod.yml logs -f backend
    docker compose -f docker-compose.prod.yml logs -f nginx
    docker compose -f docker-compose.prod.yml logs -f mongo
    docker compose -f docker-compose.prod.yml logs -f valkey
    

Troubleshooting

  • Auth warning in logs: "AUTH_ENABLED is true but no AUTH_ALLOWED_ROLES or AUTH_ALLOWED_GROUPS are configured" — set these to restrict access.
  • CORS issues: Set CORS_ORIGINS to your exact frontend origin(s). Wildcard with auth enabled disables credentials.
  • Rate limiting 429s: Check Redis/Valkey connectivity. The rate limiter fails closed (returns 429) when Redis is down.
  • LLM errors: Verify LLM_BASE_URL is in LLM_ALLOWED_DOMAINS if the allowlist is configured.
  • SIEM not forwarding: Verify SIEM_WEBHOOK_URL uses HTTPS and is in SIEM_ALLOWED_DOMAINS.