Infrastructure

Infrastructure

Owner: Engineering Last reviewed: 2026-Q2

This document describes environments, CI/CD, runtime hosting, and operational practices.

Environments

  • dev: active, default target for dev branch; permissive CORS; debugging enabled.
  • showcase: active, for demos/preview; near-prod config.
  • prod: pipeline config present but commented; enable when ready.

Environment selection and secrets are managed via Azure DevOps Variable Groups by branch in pipeline YAML.

CI/CD

  • System: Azure DevOps Pipelines (azuredevops/pipelines/*).
  • Detailed operational flow lives in cicd-runbook.md.
  • Build: Docker images per app (API/backend, frontend).
    • API: api.yaml uses templates/stages/docker-build.yaml → pushes workopti:dev-py-<commit> etc.
    • Frontend: frontend.yaml uses templates/stages/docker-frontend.yaml.
  • Deploy:
    • API: templates/stages/deploy-api.yaml deploys to Azure Web App for Containers by directory name (e.g., py).
    • Frontend: Web App for Containers; then Azure Front Door CDN purge.
  • Image tags include environment and commit hash for traceability and rollback.

Runtime

  • Compute: Azure Web App for Containers (single container per app).
  • Registry: Azure Container Registry (ACR) workopti.azurecr.io.
  • CDN: Azure Front Door/Static CDN in front of frontend; cache purge on deploy.
  • Storage: Azure Blob Storage for file uploads and documents.
  • Database: Azure-hosted PostgreSQL with TLS required (ssl in async engine; sslmode=require in sync URL).

Secrets and Configuration

  • Full variable catalog lives in environment-variables.md.
  • Backend .env template in backend/py/env.example documents required variables:
    • DB connection (DB_URL, DB_USER, DB_PASSWORD, DB_NAME).
    • Clerk (CLERK_FRONTEND_API, CLERK_SECRET_KEY).
    • Azure OpenAI, Vision, Document Intelligence, Storage, Service Principal.
  • Frontend env template in frontend/env.example (VITE_APP_API_URL, VITE_CLERK_PUBLISHABLE_KEY).
  • Recommendation: Keep secrets in Azure DevOps variable groups and/or Azure Key Vault; inject at deploy time. Never commit secrets.

Observability

  • Libraries: azure-monitor-opentelemetry, opentelemetry-* in backend requirements.
  • Emit request/response metrics, dependency spans (DB, Azure SDKs) and custom events (e.g., security events).
  • Health endpoints: /health/live, /health/ready, /health/status, /health/metrics. Wire readiness to DB and key dependencies when feasible.

Security

  • TLS enforced by platform; HSTS added for non-dev in main.py.
  • Security headers guard against clickjacking, MIME sniffing, basic XSS.
  • Strict upload validation: max sizes, MIME/extension allow-list in core/config.py.
  • Authentication: Clerk JWT verification via JWKS with caching; azp validation via CLERK_AUTHORIZED_PARTIES.
  • Authorization: DB-level checks enforce user ownership and explicit grants; avoid cross-user data leakage.

Local Development Infrastructure

  • Frontend runs with Vite on http://localhost:5173 by default.
  • Backend runs from backend/py with python main.py on http://localhost:8000.
  • Backend local setup needs PostgreSQL, Clerk settings, and the Azure values required by the feature being exercised.
  • Apply database migrations with Alembic from backend/py before testing schema-dependent code:
alembic upgrade head
  • Keep local cloud usage intentional. AI, OCR, embeddings, and storage calls can incur cost; prefer mocks in tests and use dev credentials only for manual integration checks.

Backups and Migrations

  • Database operating guidance lives in database-operations.md.
  • Database migrations via Alembic (backend/py/alembic/*).
  • Practice: run migrations in CI/CD before app start or as a controlled step.
  • Ensure regular DB backups and test restore procedures.

Disaster Recovery and Rollback

  • Rollback by redeploying the previous image tag for the environment.
  • Maintain a changelog of schema migrations; backward-compatible changes preferred.