# Development Docker Compose - Unified local development setup # Start infrastructure: pnpm docker:up # Start all services: pnpm docker:up:all # Stop: pnpm docker:down services: # Shared PostgreSQL Database (multiple databases) postgres: image: postgres:16-alpine container_name: mana-postgres restart: unless-stopped environment: POSTGRES_DB: mana_platform POSTGRES_USER: ${POSTGRES_USER:-mana} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-devpassword} volumes: - postgres-data:/var/lib/postgresql/data - ./docker/init-db:/docker-entrypoint-initdb.d:ro ports: - "5432:5432" networks: - mana-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mana}"] interval: 10s timeout: 5s retries: 5 # Redis cache redis: image: redis:7-alpine container_name: mana-redis restart: unless-stopped command: redis-server --requirepass ${REDIS_PASSWORD:-devpassword} --maxmemory 256mb --maxmemory-policy noeviction volumes: - redis-data:/data ports: - "6379:6379" networks: - mana-network healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-devpassword}", "ping"] interval: 10s timeout: 5s retries: 5 # Mailpit — fake SMTP server for local development. # Catches every outbound mail and exposes them via web UI + REST API. # Point any service that sends email at SMTP_HOST=mailpit, SMTP_PORT=1025 # and inspect what came in at http://localhost:8025. mailpit: image: axllent/mailpit:latest container_name: mana-mailpit restart: unless-stopped environment: MP_SMTP_AUTH_ACCEPT_ANY: "1" MP_SMTP_AUTH_ALLOW_INSECURE: "1" ports: - "1025:1025" # SMTP - "8025:8025" # Web UI + REST API networks: - mana-network healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:8025/api/v1/info"] interval: 10s timeout: 5s retries: 3 # MinIO Object Storage (S3-compatible) minio: image: minio/minio:latest container_name: mana-minio restart: unless-stopped command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin} volumes: - minio-data:/data ports: - "9000:9000" # S3 API - "9001:9001" # Web Console networks: - mana-network healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 30s timeout: 20s retries: 3 # MinIO bucket initialization (runs once) minio-init: image: minio/mc:latest container_name: mana-minio-init depends_on: minio: condition: service_healthy entrypoint: > /bin/sh -c " mc alias set myminio http://minio:9000 $${MINIO_ROOT_USER:-minioadmin} $${MINIO_ROOT_PASSWORD:-minioadmin}; mc mb --ignore-existing myminio/mana-storage; mc mb --ignore-existing myminio/picture-storage; mc mb --ignore-existing myminio/chat-storage; mc mb --ignore-existing myminio/cards-storage; mc mb --ignore-existing myminio/food-storage; mc mb --ignore-existing myminio/presi-storage; mc mb --ignore-existing myminio/calendar-storage; mc mb --ignore-existing myminio/contacts-storage; mc mb --ignore-existing myminio/storage-storage; mc mb --ignore-existing myminio/inventory-storage; mc mb --ignore-existing myminio/plants-storage; mc mb --ignore-existing myminio/projectdoc-storage; mc mb --ignore-existing myminio/music-storage; mc anonymous set download myminio/mana-storage; mc anonymous set download myminio/picture-storage; mc anonymous set download myminio/plants-storage; mc anonymous set download myminio/inventory-storage; mc ilm rule add --expire-days 90 myminio/chat-storage --prefix 'tmp/' 2>/dev/null || true; mc ilm rule add --expire-days 30 myminio/calendar-storage --prefix 'tmp/' 2>/dev/null || true; mc ilm rule add --expire-days 7 myminio/picture-storage --prefix 'tmp/' 2>/dev/null || true; echo 'Buckets and lifecycle rules created successfully'; exit 0; " networks: - mana-network # Mana Auth Service (Hono + Bun + Better Auth) mana-auth: profiles: ["auth", "all"] build: context: . dockerfile: ./services/mana-auth/Dockerfile container_name: mana-auth restart: unless-stopped environment: NODE_ENV: development PORT: 3001 DATABASE_URL: postgresql://${POSTGRES_USER:-mana}:${POSTGRES_PASSWORD:-devpassword}@postgres:5432/mana_platform BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:-dev-secret-change-me} BETTER_AUTH_URL: http://localhost:3001 CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000,http://localhost:5173,http://localhost:8081} depends_on: postgres: condition: service_healthy ports: - "3001:3001" networks: - mana-network # Chat Backend Service chat-backend: profiles: ["chat", "all"] build: context: . dockerfile: ./apps/chat/apps/backend/Dockerfile container_name: chat-backend restart: unless-stopped environment: NODE_ENV: development PORT: 3002 DATABASE_URL: postgresql://${POSTGRES_USER:-mana}:${POSTGRES_PASSWORD:-devpassword}@postgres:5432/mana_platform DB_HOST: postgres DB_PORT: 5432 DB_USER: ${POSTGRES_USER:-mana} DB_PASSWORD: ${POSTGRES_PASSWORD:-devpassword} DB_NAME: chat AZURE_OPENAI_ENDPOINT: ${AZURE_OPENAI_ENDPOINT} AZURE_OPENAI_API_KEY: ${AZURE_OPENAI_API_KEY:-} AZURE_OPENAI_API_VERSION: ${AZURE_OPENAI_API_VERSION:-2024-12-01-preview} MANA_AUTH_URL: http://mana-auth:3001 depends_on: postgres: condition: service_healthy ports: - "3002:3002" networks: - mana-network networks: mana-network: driver: bridge volumes: postgres-data: redis-data: minio-data: