Deploying to production
LaunchApp is designed to deploy as two separate services: the React Router 7 web app and the Hono API server. Both are standard Node.js processes that you can run on any platform that supports a Dockerfile or a Node runtime — Railway, Fly.io, Render, AWS ECS, or your own Kubernetes cluster.
- deploy
- infrastructure
LaunchApp Team
Feb 3, 2025
LaunchApp is designed to deploy as two separate services: the React Router 7 web app and the Hono API server. Both are standard Node.js processes that you can run on any platform that supports a Dockerfile or a Node runtime — Railway, Fly.io, Render, AWS ECS, or your own Kubernetes cluster.
Build once, ship everywhere
Before deploying, build the entire monorepo with pnpm build. Turborepo caches build artefacts and only rebuilds packages that have changed, so incremental builds are fast. The web app output lands in apps/web/build and the API in packages/api/dist.
The included Dockerfile is a multi-stage build that:
- Installs dependencies using the frozen lockfile.
- Runs
pnpm build --filter webin a build stage. - Copies only the production output and
node_modulesinto the final image.
This keeps the runtime image lean and avoids shipping dev dependencies to production.
Environment variables
Set all required environment variables on your hosting platform:
DATABASE_URL— production PostgreSQL connection stringBETTER_AUTH_SECRET— a long random string (useopenssl rand -base64 32)BETTER_AUTH_URL— the public URL of your API- Optional integrations like
STRIPE_SECRET_KEYorSENTRY_DSN
The .env.example file lists every variable the templates read. If you add a new one, update .env.example in the same PR so teammates see it on the next clone.
Running migrations
Run database migrations against the production database with pnpm db:migrate before starting the new release. The migration command reads DATABASE_URL from the environment, so no code changes are needed between environments.
For zero-downtime deployments, consider running migrations in a pre-deploy step and keeping the old and new schema compatible until the old release is drained. The Pulumi program in infrastructure/pulumi can provision the cloud resources if you prefer infrastructure-as-code.
Health checks and observability
The API exposes /api/health which the Dockerfile's HEALTHCHECK directive uses. Point your load balancer at the same endpoint. For observability, wire up Sentry via SENTRY_DSN and the optional PostHog or Vercel Analytics integrations — both ship as separate @repo/* packages so you can drop them in without refactoring the rest of the app.