version: '3.8' services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: parentflow-postgres restart: unless-stopped environment: POSTGRES_DB: ${DATABASE_NAME:-parentflow_production} POSTGRES_USER: ${DATABASE_USER} POSTGRES_PASSWORD: ${DATABASE_PASSWORD} POSTGRES_INITDB_ARGS: "--encoding=UTF8" volumes: - postgres_data:/var/lib/postgresql/data - ./maternal-app/maternal-app-backend/src/database/migrations:/docker-entrypoint-initdb.d:ro networks: - parentflow-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USER}"] interval: 10s timeout: 5s retries: 5 # Redis Cache redis: image: redis:7-alpine container_name: parentflow-redis restart: unless-stopped command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data networks: - parentflow-network healthcheck: test: ["CMD", "redis-cli", "--pass", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 3s retries: 5 # MongoDB for AI Chat History mongodb: image: mongo:7 container_name: parentflow-mongodb restart: unless-stopped environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD} MONGO_INITDB_DATABASE: parentflow_ai volumes: - mongo_data:/data/db networks: - parentflow-network healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 10s timeout: 5s retries: 5 # MinIO Object Storage minio: image: minio/minio:latest container_name: parentflow-minio restart: unless-stopped command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ACCESS_KEY} MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY} MINIO_BROWSER_REDIRECT_URL: https://minio.parentflowapp.com volumes: - minio_data:/data networks: - parentflow-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 30s timeout: 20s retries: 3 # Backend API backend: build: context: ./maternal-app/maternal-app-backend dockerfile: Dockerfile.production args: - NODE_ENV=production container_name: parentflow-backend restart: unless-stopped env_file: - ./maternal-app/maternal-app-backend/.env.production environment: - NODE_ENV=production - DATABASE_HOST=postgres - REDIS_HOST=redis - MONGODB_HOST=mongodb depends_on: postgres: condition: service_healthy redis: condition: service_healthy mongodb: condition: service_healthy networks: - parentflow-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s # Frontend Application frontend: build: context: ./maternal-web dockerfile: Dockerfile.production args: - NEXT_PUBLIC_API_URL=https://api.parentflowapp.com - NEXT_PUBLIC_GRAPHQL_URL=https://api.parentflowapp.com/graphql container_name: parentflow-frontend restart: unless-stopped env_file: - ./maternal-web/.env.production environment: - NODE_ENV=production depends_on: backend: condition: service_healthy networks: - parentflow-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] interval: 30s timeout: 10s retries: 3 # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: parentflow-nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/sites-enabled:/etc/nginx/sites-enabled:ro - ./nginx/ssl:/etc/nginx/ssl:ro - nginx_cache:/var/cache/nginx depends_on: - frontend - backend networks: - parentflow-network healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 networks: parentflow-network: driver: bridge volumes: postgres_data: driver: local redis_data: driver: local mongo_data: driver: local minio_data: driver: local nginx_cache: driver: local