version: '3.8' services: postgres: image: postgres:15-alpine container_name: pragativeer_prod_db restart: unless-stopped environment: POSTGRES_USER: pragativeer_admin POSTGRES_PASSWORD: local_secure_password_2026 POSTGRES_DB: pragativeer_prod ports: - "5440:5432" volumes: - pgdata:/var/lib/postgresql/data networks: - pragativeer_network healthcheck: test: ["CMD-SHELL", "pg_isready -U pragativeer_admin -d pragativeer_prod"] interval: 5s timeout: 5s retries: 12 redis: image: redis:7-alpine container_name: pragativeer_prod_cache restart: unless-stopped volumes: - redisdata:/data networks: - pragativeer_network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 12 minio: image: minio/minio:latest container_name: pragativeer_prod_storage restart: unless-stopped ports: - "9025:9000" - "9026:9001" volumes: - miniodata:/data environment: MINIO_ROOT_USER: minio_admin MINIO_ROOT_PASSWORD: minio_secure_password_2026 command: server /data --console-address ":9001" networks: - pragativeer_network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 5s timeout: 5s retries: 12 backend: build: context: ./backend dockerfile: Dockerfile.prod container_name: pragativeer_prod_backend restart: unless-stopped volumes: - ./admin_uploads:/app/admin_uploads:ro ports: - "8010:8000" environment: - DATABASE_URL=postgresql://pragativeer_admin:local_secure_password_2026@postgres:5432/pragativeer_prod - REDIS_URL=redis://redis:6379/0 - ENV=production - MINIO_ENDPOINT=minio:9000 - MINIO_ACCESS_KEY=minio_admin - MINIO_SECRET_KEY=minio_secure_password_2026 - MINIO_BUCKET=pragativeer-uploads - TZ=Asia/Kolkata env_file: - ./backend/.env depends_on: postgres: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy networks: - pragativeer_network healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"] interval: 10s timeout: 5s retries: 12 worker: build: context: ./backend dockerfile: Dockerfile.prod container_name: pragativeer_prod_worker restart: unless-stopped command: celery -A worker.celery_app worker --loglevel=info environment: - DATABASE_URL=postgresql://pragativeer_admin:local_secure_password_2026@postgres:5432/pragativeer_prod - REDIS_URL=redis://redis:6379/0 - MINIO_ENDPOINT=minio:9000 - MINIO_ACCESS_KEY=minio_admin - MINIO_SECRET_KEY=minio_secure_password_2026 - MINIO_BUCKET=pragativeer-uploads env_file: - ./backend/.env depends_on: - postgres - redis networks: - pragativeer_network healthcheck: # Celery worker serves no HTTP. Verify liveness via celery inspect ping. # NOTE: output goes to a tmp file (not a pipe) — celery's forked children hold # the pipe open and hang the check. Verified working in-container. test: ["CMD-SHELL", "celery -A worker.celery_app inspect ping -d celery@$$HOSTNAME --timeout=5 > /tmp/hc.txt 2>&1; grep -q pong /tmp/hc.txt || exit 1"] # Python cold-start makes the ping take 15-20s under load — generous timeout. interval: 60s timeout: 40s retries: 3 beat: build: context: ./backend dockerfile: Dockerfile.prod container_name: pragativeer_prod_beat restart: unless-stopped command: celery -A worker.celery_app beat --loglevel=info environment: - DATABASE_URL=postgresql://pragativeer_admin:local_secure_password_2026@postgres:5432/pragativeer_prod - REDIS_URL=redis://redis:6379/0 env_file: - ./backend/.env depends_on: - postgres - redis networks: - pragativeer_network healthcheck: # Celery beat is a scheduler — no HTTP endpoint. pgrep isn't installed in the # image; use a /proc scan instead. Verified working in-container. test: ["CMD-SHELL", "grep -as 'celery.*[b]eat' /proc/*/cmdline > /dev/null 2>&1 || exit 1"] interval: 30s timeout: 5s retries: 3 frontend: build: context: . dockerfile: Dockerfile args: - NEXT_PUBLIC_API_URL=https://pragativeer.com - BACKEND_INTERNAL_URL=http://backend:8000 container_name: pragativeer_prod_frontend restart: unless-stopped ports: - "3882:3000" environment: - NODE_ENV=production - BACKEND_INTERNAL_URL=http://backend:8000 - NEXT_PUBLIC_API_URL=https://pragativeer.com - NEXT_PUBLIC_PAYMENT_GATEWAY=razorpay depends_on: - backend networks: - pragativeer_network volumes: pgdata: redisdata: miniodata: networks: pragativeer_network: driver: bridge