name: touchbase services: postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: touchbase POSTGRES_PASSWORD: touchbase POSTGRES_DB: touchbase_dev ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data - ./db/init:/docker-entrypoint-initdb.d:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U touchbase -d touchbase_dev"] interval: 5s timeout: 5s retries: 10 mailpit: image: axllent/mailpit:latest restart: unless-stopped ports: - "1025:1025" # SMTP - "8025:8025" # web UI environment: MP_MAX_MESSAGES: "1000" MP_SMTP_AUTH_ACCEPT_ANY: "1" MP_SMTP_AUTH_ALLOW_INSECURE: "1" # Web tier — runs `pnpm start` (Next.js production server). app: image: touchbase/app:latest profiles: [prod] build: context: . dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy # Reads all env vars from .env in the project root. Override any of these # via host env vars before `docker-compose up` (e.g. on the production # host you'd point DATABASE_URL at the real DB host, set AUTH_SECRET # to a generated value, etc.). env_file: .env environment: NODE_ENV: production DATABASE_URL: ${DATABASE_URL:-postgresql://touchbase:touchbase@postgres:5432/touchbase_dev?schema=public} APP_URL: ${APP_URL:-http://localhost:3000} expose: - "3000" healthcheck: test: ["CMD-SHELL", "node -e \"fetch('http://localhost:3000/api/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 30s # Background worker — runs `pnpm worker` (pg-boss handlers). worker: image: touchbase/app:latest profiles: [prod] build: context: . dockerfile: Dockerfile command: ["pnpm", "worker"] restart: unless-stopped depends_on: postgres: condition: service_healthy env_file: .env environment: NODE_ENV: production DATABASE_URL: ${DATABASE_URL:-postgresql://touchbase:touchbase@postgres:5432/touchbase_dev?schema=public} APP_TZ: ${APP_TZ:-America/Detroit} SMTP_HOST: ${SMTP_HOST:-mailpit} SMTP_PORT: ${SMTP_PORT:-1025} SMTP_USER: ${SMTP_USER:-dev} SMTP_PASS: ${SMTP_PASS:-dev} SMTP_FROM: ${SMTP_FROM:-TouchBase } caddy: image: caddy:2-alpine profiles: [prod] restart: unless-stopped depends_on: - app ports: - "80:80" - "443:443" volumes: - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data - caddy_config:/config volumes: pgdata: caddy_data: caddy_config: