Deployment
Production deployment guide for Cyborg7.
Docker (Recommended)
The Dockerfile produces a standalone Next.js container:
# Builddocker build -t cyborg7 \--build-arg DATABASE_URL=postgresql://... \--build-arg BETTER_AUTH_URL=https://your-domain.com \--build-arg NEXT_PUBLIC_BETTER_AUTH_URL=https://your-domain.com \--build-arg NEXT_PUBLIC_APP_URL=https://your-domain.com \--build-arg NEXT_PUBLIC_DEPLOYMENT_MODE=self-hosted \.# Rundocker run -d \--name cyborg7 \-p 3000:3000 \-e DATABASE_URL=postgresql://... \-e BETTER_AUTH_SECRET=... \-e RESEND_API_KEY=... \-e REDIS_URL=redis://redis:6379 \-e MQTT_BROKER_URL=mqtt://broker:1883 \-e MQTT_ROLE=primary \cyborg7
Docker Compose (Full Stack)
version: '3.8'services:app:build: .ports:- "3000:3000"environment:- DATABASE_URL=postgresql://postgres:password@db:5432/cyborg7- REDIS_URL=redis://redis:6379- MQTT_BROKER_URL=mqtt://mqtt:1883- MQTT_ROLE=primary# ... other env varsdepends_on:- db- redis- mqttdb:image: postgres:15-alpinevolumes:- pgdata:/var/lib/postgresql/dataenvironment:POSTGRES_DB: cyborg7POSTGRES_PASSWORD: passwordredis:image: redis:7-alpinevolumes:- redisdata:/datamqtt:image: emqx/emqx:5-alpineports:- "1883:1883"volumes:pgdata:redisdata:
Build Arguments vs Runtime Variables
Next.js bakes NEXT_PUBLIC_* variables into the client bundle at build time. All other variables are read at runtime.
| Type | When | Examples |
|---|---|---|
| Build args | Docker --build-arg | NEXT_PUBLIC_APP_URL, NEXT_PUBLIC_DEPLOYMENT_MODE |
| Runtime env | Docker -e | DATABASE_URL, STRIPE_SECRET_KEY, RESEND_API_KEY |
Reverse Proxy (nginx)
server {listen 443 ssl;server_name your-domain.com;ssl_certificate /etc/ssl/cert.pem;ssl_certificate_key /etc/ssl/key.pem;location / {proxy_pass http://localhost:3000;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_buffering off; # required for SSEproxy_read_timeout 86400; # keep SSE alive}}
Database Migrations
Run migrations before starting the app:
pnpm drizzle-kit migrate
Health Check
The app listens on port 3000. Check startup logs for:
Ready on http://0.0.0.0:3000[Redis] Connected[MQTT] Connected to broker