Appearance
Deployment Overview
GitHub Actions is the normal interface for infrastructure and application deployments. infra/deploy/env.deploy.yml defines application and infrastructure configuration; GitHub repository settings hold CI-only credentials and controls.
Current Topology
text
Cloudflare
├── Pages projects: development, QA, and production webapps and marketing sites
├── OpenNext Worker and static assets: marketing runtime
├── Pages: development documentation
├── DNS, proxying, TLS, and Access policies
└── R2: Terraform state only
DigitalOcean
├── shared dev/QA droplet
│ ├── Caddy
│ ├── separate dev and QA API containers
│ ├── separate dev and QA PostgreSQL containers
│ └── separate dev and QA Redis containers
└── production
├── dedicated droplet: Caddy, API, and Redis containers
└── managed PostgreSQL 16 with PgBouncerTerraform provisions each marketing Pages project, custom domain, and DNS record. The deployment workflow writes that environment's project name to wrangler.jsonc, then OpenNext deploys the generated Worker and static assets. Frontend applications do not run on the API droplets.
Deployment Paths
Applications
Pushes to develop, qa, and main trigger an application workflow when its relevant paths change. Manual dispatch is also available.
| Application | Workflow | Destination |
|---|---|---|
| Server | deploy-server.yml | GHCR image, then Ansible deployment to DigitalOcean |
| Webapp | deploy-web-app.yml | Cloudflare Pages |
| Marketing | deploy-marketing.yml | OpenNext Worker and assets, then hosted Sanity Studio |
| Documentation | deploy-docs.yml | Cloudflare Pages |
The application workflows do not apply Terraform. They generate the required environment files at run time and perform service-specific verification. There is no automatic rollback; recovery uses a forward fix or Git revert followed by an explicit deployment.
Infrastructure
.github/workflows/terraform-deploy.yml is manual-only. Operators select dev-qa or prod and request a plan or apply. An apply run creates and applies its own saved plan. Follow Terraform Setup for approval and state-safety requirements.
Server Configuration
The server workflow builds an image, generates environment files and inventory, and invokes Ansible. Ansible configures the host and recreates the selected Docker services. Generated secret files are staged in a server tmpfs and removed after containers capture their environment. See Server Configuration.
Configuration Flow
text
env.deploy.yml + GitHub secrets/variables
|
generate-env-files.js / extract-config.js
|
runtime env files, Terraform inputs, Ansible inventoryUse CI/CD Pipeline for workflow triggers, generated artifacts, Sanity Studio deployment, and notifications. Use Secrets Management for credential storage and response procedures.
Environment Boundaries
Development and QA share compute, but have separate API, PostgreSQL, Redis, credentials, and frontend deployments. Production uses dedicated backend compute and managed PostgreSQL. The API domains are not behind Cloudflare Access; application authentication and CORS apply there. See Environments for URLs, branch mapping, current sizing, costs, and access.
Recovery Summary
- Application failure: inspect the workflow and service logs, fix forward or revert, then redeploy.
- Terraform failure: treat partial changes as possible, inspect state, and create a fresh plan.
- Production data recovery: use an approved DigitalOcean managed-database recovery point.
- Dev/QA data recovery: use an exported dump if one exists; no scheduled database backup job is configured.
- Secret exposure: revoke first, rotate every copy and dependent credential, redeploy, and review logs. See Secrets Management.