services: api: build: ./api env_file: ./api/.env.example depends_on: - postgres - redis - minio expose: - "3000" restart: unless-stopped frontend: build: ./frontend env_file: ./frontend/.env.example depends_on: - api expose: - "3001" restart: unless-stopped worker: build: ./worker env_file: ./worker/.env.example depends_on: - postgres - redis - minio restart: unless-stopped # Scale render capacity locally with, e.g.: docker compose up --scale worker=3 # A `worker` can also run standalone on a separate machine, pointed at the same # postgres/redis/minio over a private network (VPN/Tailscale/LAN) — see README. postgres: image: postgres:17-alpine environment: POSTGRES_USER: mcmapper POSTGRES_PASSWORD: mcmapper POSTGRES_DB: mcmapper volumes: - postgres-data:/var/lib/postgresql/data restart: unless-stopped # Intentionally no `ports:` — only reachable on the compose network / a private # network for remote workers, never exposed publicly. redis: image: redis:7-alpine volumes: - redis-data:/data restart: unless-stopped # Same rule as postgres: no public ports. minio: image: minio/minio:latest command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: mcmapper MINIO_ROOT_PASSWORD: mcmapper-dev-only volumes: - minio-data:/data restart: unless-stopped # Same rule as postgres/redis: no public ports in production. The console (9001) and # S3 API (9000) are reachable on the compose network for api/worker; expose to your # private network only, same as postgres/redis, if you need the console remotely. caddy: image: caddy:2-alpine volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy-data:/data ports: - "80:80" - "443:443" depends_on: - api - frontend restart: unless-stopped volumes: postgres-data: redis-data: minio-data: caddy-data: