Reference architecture
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.
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: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:
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 Merge only through a reviewed pull request with required checks.
upstream, and branch from an approved
published release. The example defaults to the tested v0.1.0-rc.1 release.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:Convex schema and function deployment is a separate
Migration command:
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:
/api/v1/capabilities,/api/auth/session, and the ALB health path.- OIDC sign-in, refresh, new tab, sign-out, and account deletion.
- Chat create, stream, stop, refresh recovery, rename, and delete across two web tasks.
- Files, notes, projects, memory, knowledge, and citations when enabled.
- Convex cron execution and realtime subscriptions observed in backend logs.
- Redis fail-closed behavior and recovery.
- RDS failover and convex-backend lease recovery; automatic web recovery.
- S3 signed URL expiry, ownership checks, deletion, and reconciliation.
- Backup restore to a new database and application connection to the restore.
- CloudWatch alarms and delivery to the named operator.
- Convex connectivity: web tasks reach the backend on 3210/3211 and no other deployment URL.
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: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:- Identify the deployed Git SHA, image digest, schema version, and task revisions.
- Redeploy the current digest through CI without changing source.
- Find web, convex-backend, migration, RDS, Redis, ALB, and S3 telemetry.
- Trigger and receive a test alarm.
- Roll back to the previous digest and roll forward again.
- Locate backups, restore instructions, secret rotation ownership, and incident contacts.
- Revoke or reduce the temporary Overlay operator role while CI continues to work.