Production Deployment
This guide covers deploying Nodebyte to production with Docker Compose. Follow each section to ensure a secure, reliable deployment.
Production Checklist
Section titled “Production Checklist”Before going live, address every item:
-
JWT_SECRET— set to a long random string:openssl rand -hex 32 -
POSTGRES_PASSWORD— set to a strong, unique password -
COOKIE_SECURE=true— required when serving over HTTPS -
COOKIE_SAMESITE=lax— orstrictif frontend and API share a domain -
FRONTEND_ORIGIN— set to your actual frontend URL (e.g.https://nodebyte.example.com) -
NEXT_PUBLIC_API_BASE_URL— set to your actual backend URL -
NODEBYTE_ENV=production— enables security headers and restricts API docs visibility - Turnstile — replace test keys with real Cloudflare Turnstile keys, or set
TURNSTILE_ENABLED=false - Uvicorn workers — remove
--reloadfrombackend/entrypoint.shand add--workers N - HTTPS — terminate TLS in front of the containers
- Database backups — ensure
nodebyte_postgresvolume is backed up
Setting Up a Reverse Proxy
Section titled “Setting Up a Reverse Proxy”Nodebyte needs a reverse proxy for TLS termination. Here are configurations for common options.
server { listen 443 ssl http2; server_name nodebyte.example.com;
ssl_certificate /etc/letsencrypt/live/nodebyte.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/nodebyte.example.com/privkey.pem;
location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
location /api/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}
server { listen 80; server_name nodebyte.example.com; return 301 https://$host$request_uri;}nodebyte.example.com { handle /api/* { reverse_proxy localhost:8000 } handle { reverse_proxy localhost:3000 }}Caddy automatically provisions and renews TLS certificates via Let’s Encrypt.
Traefik
Section titled “Traefik”If you’re using Traefik (e.g. in a Docker or Kubernetes setup), add labels to your docker-compose.yml:
services: frontend: labels: - "traefik.enable=true" - "traefik.http.routers.nodebyte.rule=Host(`nodebyte.example.com`)" - "traefik.http.routers.nodebyte.tls.certresolver=letsencrypt" - "traefik.http.services.nodebyte.loadbalancer.server.port=3000"Security Hardening
Section titled “Security Hardening”When NODEBYTE_ENV=production, the backend automatically adds security headers:
Strict-Transport-Security(HSTS)X-Frame-Options: DENYX-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=block
Additional recommendations:
- Rate limiting — the backend includes built-in rate limiting on auth endpoints
- Firewall — restrict direct access to ports 8000 and 5432 from the public internet; only expose the reverse proxy (443)
- Registration — set
REGISTRATION_ENABLED=falsefor invite-only deployments
Database Backups
Section titled “Database Backups”The PostgreSQL data lives in the nodebyte_postgres Docker volume. Back it up regularly:
docker compose exec db pg_dump -U nodebyte nodebyte > backup_$(date +%Y%m%d).sqlTo restore:
docker compose exec -T db psql -U nodebyte nodebyte < backup_20250101.sqlFor automated backups, set up a cron job:
0 2 * * * cd /path/to/nodebyte && docker compose exec -T db pg_dump -U nodebyte nodebyte | gzip > /backups/nodebyte_$(date +\%Y\%m\%d).sql.gzScaling Workers
Section titled “Scaling Workers”For higher throughput, increase Uvicorn workers. Edit backend/entrypoint.sh:
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4A good starting point is 2 * CPU cores + 1.