Skip to main content
This guide describes the customer-controlled AWS deployment used for an Overlay pilot. Complete Docker On EC2 first when the goal is a quick connectivity and product sanity check.
Do not turn the EC2 sanity host or the disposable AWS rehearsal stack into production by changing its name. Production infrastructure must follow the customer’s networking, security, backup, observability, and change-control standards.

Reference architecture

Convex is the application backend. The self-hosted convex-backend service executes functions, realtime sync, scheduled jobs, and durable work; there are no separate worker or scheduler services. Postgres remains only as the Convex backend’s persistence engine and as Better Auth’s separate auth database — the app never runs SQL against application data. Deploy and operate the backend per Self-hosted Convex backend.

Required ownership

Before provisioning, name the owners for:
  • AWS account, Region, VPC, quotas, tags, and budget.
  • Source repository, protected branches, CI/CD, and release approval.
  • DNS, ACM certificates, ingress, WAF, and outbound egress.
  • RDS, Redis, S3, KMS, backups, restore tests, and retention.
  • Google Workspace or other OIDC application and pilot users.
  • Secrets Manager values and rotation.
  • CloudWatch alarms and the incident notification destination.
  • Model gateway and every optional external processor.
  • Pilot acceptance, rollback, and go-live.
Use a dedicated nonproduction account when possible. Human access should be federated, named, MFA-protected, time-limited, least-privilege, and audited by CloudTrail. CI should use GitHub Actions OIDC or CodeBuild roles, not static AWS access keys.

AWS resources

Secrets Manager

Create separate paths for staging and production. ECS injects application secrets as environment variables. For BYOK, the application makes narrowly scoped runtime calls to Secrets Manager using its ECS task role; each user API key is a separate opaque secret ARN stored in Convex, never a plaintext database value. Keep non-secret selectors and hostnames in task-definition environment variables. Enable AWS-backed BYOK in the customer runtime configuration:
Grant the web ECS task role only secretsmanager:CreateSecret, GetSecretValue, PutSecretValue, and DeleteSecret for that prefix, plus kms:Encrypt, kms:Decrypt, and kms:GenerateDataKey on the customer KMS key. Do not grant list, broad read, cross-environment, or wildcard customer secret permissions. At minimum, create entries for:
Add provider credentials only for approved, enabled features. On ECS or EC2, prefer a bucket-scoped task or instance role and omit S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY. For non-AWS S3-compatible storage, configure both keys, store them in Secrets Manager, and rotate them. Do not place any secret in a NEXT_PUBLIC_* variable, source file, task-definition plaintext environment value, build log, document, ticket, email, or chat.

Deployment procedure

1

Prepare the customer repository

Fork or mirror the public LayerNorm/overlay-web repository into the customer’s GitHub organization. Clone that customer-controlled repository, retain the public repository as upstream, and branch from an approved published release. The example defaults to the tested v0.1.0-rc.1 release.
Merge only through a reviewed pull request with required checks.
2

Establish customer-controlled CI access

Configure GitHub Actions OIDC or CodeBuild. Restrict the deployment role to the exact repository, branch/environment, ECR repository, ECS services, task roles, log groups, and approved infrastructure stacks. Restrict iam:PassRole to the named ECS execution and task roles.
3

Provision infrastructure as code

Use the customer’s approved Terraform, CloudFormation, CDK, or platform catalog. Keep environment values outside application source. Review the generated plan or change set before applying it.Required network flows are:
4

Build and push one immutable image

Build from the reviewed commit in CI, not on a production host:
Record the digest and use repository@sha256:... in every task definition. Do not rebuild the image between staging and production. NEXT_PUBLIC_* values are inlined at build time, so the baked NEXT_PUBLIC_CONVEX_URL must be the origin web tasks and browsers can both reach — the backend’s internal ALB hostname works when web tasks, operator browsers, and the backend share routable DNS; otherwise use the public backend origin.
5

Define the ECS roles

All task definitions use the same image digest and configuration family:Migration command:
Convex schema and function deployment is a separate npx convex deploy step against the self-hosted backend; see Self-hosted Convex backend.Configure health checks, log groups, CPU/memory, graceful stop time, read-only filesystem exceptions, database pool budgets, and secret ARN references per role.
6

Snapshot and run migrations once

Record the current image digest, task-definition revisions, schema version, a pre-deploy RDS snapshot, and a npx convex export of the Convex deployment.Run the Better Auth migration task in the private ECS subnets with the direct RDS writer endpoint. Wait for the task to stop, inspect its exit code, and retain its redacted logs. Do not deploy the services when the migration exit code is nonzero. Deploy the Convex revision per the self-hosted runbook and watch the backend logs for Executing Migration n/m.
7

Deploy the same digest to every service

Register new task-definition revisions containing the recorded digest, then update the convex-backend and web services. For web rolling deployments use:
Wait for every ECS service to become stable and every ALB target to become healthy. The convex-backend service must hold its persistence lease; a promoted standby acquiring the lease is expected HA behavior, not a split brain.
8

Configure DNS, TLS, and OIDC

Point the approved hostname to the ALB or approved edge. Register the exact production values with the OIDC owner:
Set BETTER_AUTH_URL, trusted origins, JWT issuer/audience, and JWKS URL to that same HTTPS origin. Store only the public client ID in plaintext config; the client secret remains in Secrets Manager.
9

Qualify staging

At minimum verify:
  1. /api/v1/capabilities, /api/auth/session, and the ALB health path.
  2. OIDC sign-in, refresh, new tab, sign-out, and account deletion.
  3. Chat create, stream, stop, refresh recovery, rename, and delete across two web tasks.
  4. Files, notes, projects, memory, knowledge, and citations when enabled.
  5. Convex cron execution and realtime subscriptions observed in backend logs.
  6. Redis fail-closed behavior and recovery.
  7. RDS failover and convex-backend lease recovery; automatic web recovery.
  8. S3 signed URL expiry, ownership checks, deletion, and reconciliation.
  9. Backup restore to a new database and application connection to the restore.
  10. CloudWatch alarms and delivery to the named operator.
  11. Convex connectivity: web tasks reach the backend on 3210/3211 and no other deployment URL.
Keep the test accounts and data disposable. Run destructive contracts only against a separate contract-test database.

Rollback

Before every release, record the previous image digest and task definitions. When the new schema remains backward-compatible, roll all services back to the previous digest and verify auth, chat, files, and queue state. If the previous runtime is not schema-compatible, do not improvise a down migration. Restore the pre-deploy snapshot into a new database, point the previous release at the restored writer, and preserve the failed database and logs for investigation.

Product updates and customer customizations

Overlay updates never deploy automatically into the customer account:
Reusable fixes should go upstream. Customer policy, consent, curriculum, and proprietary data-lake logic should remain behind provider interfaces, service contracts, APIs, MCP servers, or extension modules where practical. Every customer customization needs tests, an owner, a data-flow description, an upgrade note, and rollback behavior.

Paste into a coding agent

Use this prompt only after the agent is authenticated through the customer’s approved AWS and source-control mechanisms:

Handover gate

The deployment is not handed over until the customer PoC can:
  1. Identify the deployed Git SHA, image digest, schema version, and task revisions.
  2. Redeploy the current digest through CI without changing source.
  3. Find web, convex-backend, migration, RDS, Redis, ALB, and S3 telemetry.
  4. Trigger and receive a test alarm.
  5. Roll back to the previous digest and roll forward again.
  6. Locate backups, restore instructions, secret rotation ownership, and incident contacts.
  7. Revoke or reduce the temporary Overlay operator role while CI continues to work.
For configuration details and provider matrices, continue with Self-Hosting and Security.