# Local stack. MinIO stands in for Cloudflare R2 (same S3 API); in prod drop minio and set R2_* vars. services: postgres: image: postgres:16-alpine environment: POSTGRES_USER: notestack POSTGRES_PASSWORD: notestack POSTGRES_DB: notestack ports: ["5432:5432"] volumes: [pgdata:/var/lib/postgresql/data] healthcheck: test: ["CMD-SHELL", "pg_isready -U notestack"] interval: 5s retries: 10 minio: image: minio/minio:latest command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: ["9000:9000", "9001:9001"] volumes: [miniodata:/data] api: build: ./backend env_file: .env environment: DATABASE_URL: postgresql+psycopg://notestack:notestack@postgres:5432/notestack R2_ENDPOINT_URL: ${R2_ENDPOINT_URL:-http://minio:9000} RENDERER_URL: http://renderer:3100 API_URL: http://api:8000 # API_URL above is the in-network name; Google must redirect the browser to the published port. GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-http://localhost:8000/api/auth/google/callback} CORPUS_CACHE_DIR: /cache/corpus volumes: [apicache:/cache] ports: ["8000:8000"] depends_on: postgres: { condition: service_healthy } worker: build: ./backend command: python -m app.worker env_file: .env environment: DATABASE_URL: postgresql+psycopg://notestack:notestack@postgres:5432/notestack R2_ENDPOINT_URL: ${R2_ENDPOINT_URL:-http://minio:9000} RENDERER_URL: http://renderer:3100 API_URL: http://api:8000 CORPUS_CACHE_DIR: /cache/corpus volumes: [workercache:/cache] depends_on: [api] renderer: build: ./renderer environment: INTERNAL_TOKEN: ${INTERNAL_TOKEN:-internal-change-me} ports: ["3100:3100"] frontend: image: node:22-alpine working_dir: /app command: sh -c "npm install && npx vite --host 0.0.0.0" environment: # The browser calls /api on :5173 and Vite proxies it to the api service (in-network name). VITE_API_PROXY: http://api:8000 VITE_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-} volumes: ["./frontend:/app", "/app/node_modules"] ports: ["5173:5173"] depends_on: [api] volumes: pgdata: miniodata: apicache: workercache: