How a push becomes a live URL.
Every git push to your default branch (and every manual redeploy) flows through the same pipeline. This page is the reference for what runs at each phase, what you can configure, and how to recover when something fails.
Deploy phases
- QUEUED
The deploy job is in BullMQ, waiting for a build worker.
- CLONING
Worker clones the repo at the target commit into an ephemeral build environment.
- SCANNING
gitleaks + semgrep + pnpm/npm audit run in parallel. A blocking finding fails the deploy here.
- BUILDING
Framework-specific build runs in a Docker buildx context; image is tagged and pushed to ECR.
- PROVISIONING
If your repo signals a DB (DATABASE_URL in .env.example, or @codayinc/auth|storage), a per-project Postgres is created. SDK schemas migrate. ALB target group + listener rule attach.
- DEPLOYING
ECS Fargate task definition registers; service rolls out (existing service = rolling update).
- LIVE
Service is healthy. URL on *.coday.app behind Cloudflare HTTPS is ready.
- FAILED
Any phase can fail. The deploy row carries an errorMessage; SECURITY_SCAN_BLOCK[scanId] errors deep-link to the Security tab.
Framework detection
Coday inspects package.json and common project files to pick a framework. Four are recognized zero-config; anything else falls back to a generic Node build (any script in package.json named build and start).
| Framework | Port | Build | Start |
|---|---|---|---|
| next.js | 3000 | next build | next start |
| vite | 4173 | vite build | vite preview |
| django | 8000 | — (Python container) | python manage.py runserver 0.0.0.0:8000 |
| rails | 3000 | — (Ruby container) | bin/rails server -b 0.0.0.0 |
Override anything from the Settings tab on the project — custom build branch, custom build command, or pinned framework. Auto- deploy on push can be toggled there too.
Environment variables
Coday reads your .env.example (also .env.template / .env.sample) and classifies each key. Some are filled automatically; the rest are listed under Project → Variables for you to provide.
- auto-database
DATABASE_URL / POSTGRES_URL / DB_URL / MONGODB_URI — Coday provisions a per-project Postgres and injects the URL.
- auto-secret
Anything matching *_SECRET, JWT_SECRET, NEXTAUTH_SECRET, AUTH_SECRET, SESSION_SECRET — Coday generates a random 64-character secret on first deploy.
- auto-domain
NEXT_PUBLIC_URL / NEXTAUTH_URL / PUBLIC_URL / BASE_URL / APP_URL — Coday fills in your project's public URL.
- user
External provider keys (STRIPE_*, OPENAI_API_KEY, ANTHROPIC_API_KEY, RESEND_API_KEY, GITHUB_CLIENT_SECRET, GOOGLE_CLIENT_SECRET, …) — you paste these from the provider dashboard.
Database, storage, auth
Coday provisions a per-project Postgres when your repo signals it — either by declaring DATABASE_URL in .env.example or by depending on @codayinc/auth or @codayinc/storage. Connection strings are injected as DATABASE_URL and never persisted on the dashboard side; read SDKs for how the managed packages plug in.
From the dashboard you get a read-only view of provisioned resources under Project → Database and Project → Storage. Empty states tell you what to add to your repo if a resource isn't there yet.
Custom domains & HTTPS
Every project gets a *.coday.app subdomain with HTTPS out of the box. Attach a custom domain from Dashboard → Domains — Coday-registered domains (Cloudflare Registrar) finish in seconds; BYO domains take one CNAME record.
Redeploy and rollback
Every push to your default branch redeploys automatically (toggleable per repo). From the Deployments tab you can also Redeploy a project on demand or Rollback to any prior LIVE deploy — the image already lives in ECR, so rollback is a rolling ECS update without a rebuild.
Cost & cost cap
Cloud usage is billed monthly on top of your Coday subscription. Set a cap from Dashboard → Usage; new deploys are paused before the cap is exceeded. The same page shows the running month total, broken down by service category.