Skip to main content

Deployment

Deploy to production using Docker, PM2, Coolify, Fly.io, or Railway.

Deployment

SaaS Starter ships production-ready configs for all major deployment targets.

Docker Compose (Recommended)

The primary deployment path. Full stack defined in docker-compose.yml:

| Service | Role | |---|---| | postgres | PostgreSQL 16 with pgvector | | redis-cache | Session cache (LRU, DB 0) | | redis-queue | BullMQ job queue (noeviction, DB 1) | | api | Hono API server (port 8000) | | worker | BullMQ background workers | | web | Next.js frontend (port 3000) | | caddy | Reverse proxy with auto-TLS (ports 80, 443) |

# Production stack with resource limits
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# With monitoring stack
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.monitoring.yml up -d

PM2 (Standalone)

For VPS deployments without Docker:

# Full rebuild and deploy
pnpm pm2:rebuild

# Safe deploy for low-memory servers
pnpm pm2:rebuild:safe

# Restart from existing artifacts only
pnpm pm2:restart:artifacts

The ecosystem.config.cjs defines three PM2 processes: api, web, and worker.

Coolify

  1. Import your repository into Coolify
  2. Set environment variables from .env.example as secrets
  3. Use the provided docker-compose.coolify.yml in deploy/coolify/
pnpm cli deploy coolify

Fly.io

Requires the Fly CLI:

fly auth login
pnpm cli deploy fly

Configs in deploy/fly/: fly.api.toml, fly.web.toml.

Railway

Push to a Railway project:

railway login
pnpm cli deploy railway

Configs in deploy/railway/: api.railway.json, web.railway.json.

Reverse Proxy Options

The boilerplate includes config templates for:

  • CaddyCaddyfile (auto-TLS, security headers, WebSocket support)
  • Nginxconfigs/nginx.conf.template
  • Apacheconfigs/apache.vhost.template

Required Environment Variables

Minimum for production:

APP_URL=https://yourdomain.com
API_URL=https://api.yourdomain.com
DATABASE_URL=postgresql://user:pass@host:5432/db
REDIS_URL=redis://...
AUTH_SECRET=<32+ random chars>
BILLING_PROVIDER=stripe
STRIPE_SECRET_KEY=your-stripe-secret-key
STRIPE_WEBHOOK_SECRET=your-stripe-webhook-secret

Health Check

pnpm doctor
# Checks: env vars, DB, Redis, billing, AI, storage, and more

Monitoring

Docker monitoring stack (Prometheus + Grafana):

docker compose -f docker-compose.monitoring.yml up -d
# Grafana: http://localhost:3080

Five pre-configured dashboards: API Overview, Business Metrics, Queues, System Health.

Important Notes

  • Database migrations must be applied manually (pnpm migrate) — never run automatically
  • Production domains require correct DNS + reverse proxy configuration before HTTPS works
  • For low-memory servers add --low-memory flag during setup
  • Use pnpm pm2:restart:artifacts when your server is unstable during builds