This repo ships a Dockerized backend and a standalone Next.js frontend. Pick the platform that fits your stack; examples below use Render (backend) and Vercel (frontend), plus a generic Docker run option.
- Node 20 for local builds
- Docker 24+
- Postgres 14+ (Timescale optional) and Redis (e.g., Upstash)
- Domain/HTTPS handled by your host
PORT(default4000)DATABASE_URL(Postgres/Timescale connection string)REDIS_URL(Redis connection string)JWT_SECRET(long random string)ENCRYPTION_KEY(32-byte hex/utf-8 key for credential encryption)SLACK_WEBHOOK(optional, for budget alerts)
NEXT_PUBLIC_API_URL(e.g.,https://your-backend/api)NEXT_PUBLIC_APP_NAME(optional branding)
- Build context:
backend/ - Dockerfile:
backend/Dockerfile - Start command:
node dist/index.js(already set in image CMD) - Health check:
GET /healthon$PORT - Provision Postgres + Redis (managed) and set env vars above.
- For workers, create a second Render service using the same image with command
node dist/workers/index.js.
- Set project root to
frontend/. - Build command:
npm run build; Output:.next(Vercel auto-detects). - Env:
NEXT_PUBLIC_API_URLpointing to the backend public URL. - If self-hosting with Docker, use
frontend/Dockerfile(exposes 3000).
Example (adjust secrets before using):
version: "3.9"
services:
backend:
build: ./backend
environment:
PORT: 4000
DATABASE_URL: ${DATABASE_URL}
REDIS_URL: ${REDIS_URL}
JWT_SECRET: ${JWT_SECRET}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
SLACK_WEBHOOK: ${SLACK_WEBHOOK}
ports:
- "4000:4000"
depends_on:
- db
- redis
worker:
build: ./backend
command: ["node", "dist/workers/index.js"]
environment: *same as backend*
depends_on:
- db
- redis
frontend:
build: ./frontend
environment:
NEXT_PUBLIC_API_URL: http://localhost:4000/api
ports:
- "3000:3000"
db:
image: postgres:14
environment:
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
POSTGRES_DB: cloudoptima
volumes:
- db_data:/var/lib/postgresql/data
redis:
image: redis:7
volumes:
db_data:-
npm run buildpasses inbackend/andfrontend/ -
npx prisma generatesucceeded after any schema change - Env vars set in hosting dashboards (backend + frontend)
- Worker process is deployed (action/schedule/budget queues)
- Domain + TLS configured
- SLACK_WEBHOOK set if budget alerts are desired
# backend
cd backend && docker build -t cloudoptima-backend .
docker run --rm -p 4000:4000 --env-file .env cloudoptima-backend
# frontend
cd frontend && docker build -t cloudoptima-frontend .
docker run --rm -p 3000:3000 cloudoptima-frontend