Skip to main content
Use this guide for the first customer-controlled deployment. It proves that the release can start in the customer’s VPC, reach a self-hosted Convex backend, PostgreSQL, and Redis, complete OIDC sign-in, persist a conversation, and recover after a container restart.
This is a disposable sanity check, not the pilot production architecture. It runs one web container and one Convex backend on one EC2 host. Move to Deploy On AWS after this check passes.

What this runs

The sanity profile deliberately disables files, memory, knowledge, vector search, automations, webhooks, integrations, browser use, sandboxes, analytics, error reporting, and billing. Enable those only in the qualified AWS deployment.

Before you start

You need: Use security-group references, not public database endpoints:
  • EC2 inbound: SSH only from the operator’s current IP. Do not expose port 3000.
  • RDS inbound: PostgreSQL 5432 only from the EC2 security group.
  • Redis inbound: TLS Redis 6379 only from the EC2 security group.
  • EC2 outbound: HTTPS plus the approved RDS and Redis destinations.

Install

1

Connect to the EC2 instance

Connect through Session Manager when available. Otherwise use the temporary, IP-restricted SSH rule:
2

Install Docker, Git, and PostgreSQL tools

Review the Docker installation script before running it if customer policy requires source inspection.
Install the AWS RDS CA bundle for administrative psql commands:
3

Create the Better Auth database with the RDS administrator

Run this once with a temporary administrative connection. The Better Auth role must not retain administrative membership. Replace all angle-bracket values before running it.
If the role or database already exists, inspect it instead of blindly rerunning the creation statements.
4

Clone the approved release

Clone the public repository for the initial sanity check. If your organization maintains an approved private mirror, set OVERLAY_REPOSITORY_URL to that mirror instead. The commands below default to the tested v0.1.0-rc.1 release; change OVERLAY_RELEASE only when you have approved another published release.
Record the exact commit and tag:
Published releases are listed at github.com/LayerNorm/overlay-web/releases.
5

Create the runtime files

The real environment file is ignored by Git.
Edit deploy/ec2/.env and replace every replace_me or replace-me value. Generate every Overlay-owned secret independently:
Do not reuse a generated value. Do not paste secret values into chat, tickets, logs, screenshots, Git, or the coding agent’s final report.Database passwords containing reserved URL characters must be URL-encoded in BETTER_AUTH_DATABASE_URL. NEXT_PUBLIC_CONVEX_URL points at the convex-backend service on the same host; INTERNAL_API_SECRET must match the value set on the backend deployment.
6

Configure Google Workspace login

In a customer-controlled Google Cloud project, configure Google Auth Platform with an Internal audience and create a Web application OAuth client. Register these exact values:
In deploy/ec2/.env, replace example.edu with the Workspace domain and set BETTER_AUTH_CONNECTION_CLIENT_ID and BETTER_AUTH_CONNECTION_CLIENT_SECRET. Keep the connection ID as workspace so it matches the callback path.Follow Google Workspace for the complete console flow. If Auth0 is the approved broker instead, follow Auth0 and use connection ID auth0. Cognito, Okta, and Keycloak use Generic OIDC.
7

Validate and pull the release image

Define a short helper for the remaining commands:
OVERLAY_WEB_IMAGE must name the approved versioned release, such as ghcr.io/layernorm/overlay-web:0.1.0-rc.1. Do not use latest for a customer qualification run. The web and migration roles use the same immutable image; backend uses the pinned official convex-backend image.To build inspected or customized source instead, use the build override:
Continue with compose_source instead of compose for the remaining steps when using a source build. The override builds the tested enterprise runtime, including the web server and migration tooling.
8

Start the Convex backend and run migrations once

Start the backend and wait for its /version health check:
Then run the Better Auth migration once:
The command must exit with status 0 and report that Better Auth migrations are current. Do not run migrations from every web container. Deploy the Convex functions and schema to the backend once per release with the bootstrap flow from Self-hosted Convex backend, which also sets INTERNAL_API_SECRET and INTERNAL_SERVICE_AUTH_SECRET on the deployment.
9

Start the web service

Wait for web to become healthy. Backend logs should show the persistence lease held and regular function traffic without restart loops.
10

Open the SSH tunnel

From the operator’s computer, open a second terminal. The tunnel must carry both the app and the Convex client/realtime port:
Keep that terminal open and visit http://localhost:3000. The browser, IdP, and Convex client see localhost origins while the application runs inside the customer VPC.

Verify the sanity check

Run these commands on EC2:
Then verify in the browser:
  1. A signed-out user sees one Continue with Google option on a single line.
  2. Sign-in returns to /app/chat.
  3. /api/auth/session reports authenticated: true and emailVerified: true.
  4. Create a conversation and send one model request.
  5. Rename the conversation and refresh the page.
  6. Restart only the web container with compose restart web.
  7. Refresh again and confirm the conversation and title persist.
  8. Sign out and confirm the session is cleared.
  9. Confirm the browser network and container logs reach only the local Convex backend URL.
Expected capability signals include provider: "convex". Features disabled by the sanity profile should not appear as usable navigation or routes.

Troubleshooting

Stop and remove the sanity host

Delete the disposable EC2 instance, databases, Redis deployment, security-group rules, snapshots, and OIDC callback when they are no longer needed. Retain only the redacted result, release commit, and approved evidence.

Paste into a coding agent

Paste the following only after authenticating the agent through the customer’s approved AWS mechanism:

Next: Deploy On AWS

Replace the single EC2 host with the qualified ECS, RDS, Redis, S3, Secrets Manager, and CloudWatch architecture.