Deploy with Docker
Build the web app (and optional customer docs) from the repo-root Dockerfiles
Setup offers Docker as a third host (scripts/hosts.ts — "Docker / AWS / VPS").
Compose files in this repo:
| File | Role |
|---|---|
docker-compose.yml | Local Postgres + MailDev (+ optional web for dev) |
docker-compose.e2e.yml | Playwright Postgres on 5433 + MailDev |
docker-compose.prod.yml | Exists, unsupported — incomplete (healthcheck/storage/env gaps). Do not follow it. |
Build the image and run it behind your own reverse proxy.
Web app
Build from the repo root. NEXT_PUBLIC_* are baked in at next build and are required (apps/web/lib/env.ts). Host .env files are excluded by .dockerignore — they never enter the build context.
docker build -f apps/web/Dockerfile \
--build-arg NEXT_PUBLIC_APP_URL=https://app.example.com \
--build-arg NEXT_PUBLIC_APP_NAME=YourApp \
--build-arg NEXT_PUBLIC_DOCS_URL=https://docs.example.com \
-t web:latest .next build also validates server env. If the build fails on missing DATABASE_URL / BETTER_AUTH_SECRET, pass dummy build-time values for those (they are not the production secrets). Runtime secrets go in docker run.
docker run -p 3000:3000 --env-file apps/web/.env.local web:latestRuntime env: DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL, BETTER_AUTH_TRUSTED_ORIGINS, NEXT_PUBLIC_APP_URL, EMAIL_FROM (plus provider creds), STORAGE_PROVIDER (plus S3 when s3), Stripe keys. EMAIL_PROVIDER is optional (auto-detect). Postgres is not in the app image.
The app reads client IPs from cf-connecting-ip, then x-real-ip, then x-forwarded-for. Put a reverse proxy in front; without one, rate limiting collapses every visitor into one bucket.
Then follow the shared post-deploy configuration and the verification checklist. Do not run the dev seed against production.
Customer docs (optional)
apps/docs/Dockerfile builds the customer's Fumadocs app (apps/docs, port 3004):
docker build -f apps/docs/Dockerfile -t docs:latest .
docker run -p 3004:3004 docs:latestTag it docs:latest (not saasprokit-docs). This is the customer's product docs, not kit-docs (docs/ on port 3006).