Docker Setup

Docker Compose orchestrates all local development services for Renewa One.

Compose Files

FilePurpose
renewa-one/docker-compose.ymlBase config: PostgreSQL 18-alpine, Redis 8-alpine
renewa-one/docker-compose.local.ymlDev override: backend hot-reload via backend/Dockerfile.dev, env vars (incl. AUTO_MOCK default true)
renewa-one/docker-compose.test.ymlTest runner configuration

Postgres 18 mounts the postgres_data volume at /var/lib/postgresql (not .../data) because PG 18 images manage major-version-specific subdirectories themselves.

Production Build

renewa-one/Dockerfile uses a multi-stage build with Bun:

  1. deps — install dependencies
  2. build — compile frontend + backend
  3. runtime — minimal production image (nginx + backend via supervisord)

Per-service Dockerfiles also exist: backend/Dockerfile, backend/Dockerfile.dev (local hot-reload), frontend/Dockerfile.

nginx Configuration

ConfigPurpose
renewa-one/nginx.confSPA routing, /api/* proxy to backend:3000, /health endpoint, 100MB upload limit
renewa-one/nginx-main.confTop-level nginx daemon config copied to /etc/nginx/nginx.conf in the production image (runs as nobody)
renewa-one/nginx.dev.confDevelopment-specific overrides

nginx serves static frontend files and proxies API requests to the backend on port 3000. Fly.io connects to port 80 (nginx).

Named Volumes

VolumeContent
postgres_dataDatabase Architecture persistent storage
redis_dataRedis cache and Background Jobs queue data

Port Allocation

ServiceDefault Port
nginx80
Backend3000
Frontend (Vite)5173
PostgreSQL5432

Each worktree gets an isolated Docker stack via make setup, which calls renewa-one/scripts/allocate-dev-ports.sh. nginx ports are constrained to 18 deterministic slots (10000-10017) so every slot can be registered as a HubSpot OAuth redirect URI; each worktree also gets a unique COMPOSE_PROJECT_NAME. make port-status shows the slot map across worktrees. See Scripts for details.

Background Workers

renewa-one/supervisord.conf manages Background Jobs workers alongside the main application process in the production container.

Environment Precedence

.env.local (per-worktree ports, auto-generated) > .env.hubspot (shared HubSpot credentials) > .env > docker-compose.local.yml defaults.

Run [[Makefile Commands|make setup]] to generate env files; make env-pull pulls secrets from Infisical. Set JWT_SECRET in .env on first run:

openssl rand -base64 32

Key Files

  • renewa-one/docker-compose.yml
  • renewa-one/docker-compose.local.yml
  • renewa-one/docker-compose.test.yml
  • renewa-one/Dockerfile
  • renewa-one/backend/Dockerfile.dev
  • renewa-one/nginx.conf
  • renewa-one/nginx-main.conf
  • renewa-one/nginx.dev.conf
  • renewa-one/supervisord.conf
  • renewa-one/scripts/allocate-dev-ports.sh

See Also