version: '3.8' services: postgres: image: postgres:16-alpine platform: linux/amd64 container_name: viewer3d-postgres environment: POSTGRES_USER: viewer POSTGRES_PASSWORD: viewer_password POSTGRES_DB: viewer_db ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./infrastructure/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U viewer -d viewer_db"] interval: 10s timeout: 5s retries: 5 networks: - viewer3d-network redis: image: redis:7-alpine platform: linux/amd64 container_name: viewer3d-redis command: redis-server --appendonly yes --maxmemory-policy noeviction ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - viewer3d-network minio: image: minio/minio:latest platform: linux/amd64 container_name: viewer3d-minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: - "9000:9000" - "9001:9001" volumes: - minio_data:/data healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 30s timeout: 20s retries: 3 networks: - viewer3d-network minio-init: image: minio/mc:latest platform: linux/amd64 container_name: viewer3d-minio-init depends_on: minio: condition: service_healthy entrypoint: > /bin/sh -c " mc alias set local http://minio:9000 minioadmin minioadmin; mc mb --ignore-existing local/raw-models; mc mb --ignore-existing local/converted-models; mc mb --ignore-existing local/thumbnails; mc anonymous set download local/raw-models; mc anonymous set download local/converted-models; mc anonymous set download local/thumbnails; echo 'Buckets created successfully'; exit 0; " networks: - viewer3d-network api: build: context: ./api dockerfile: Dockerfile platform: linux/amd64 container_name: viewer3d-api ports: - "4000:3000" environment: NODE_ENV: production PORT: 3000 DATABASE_URL: postgresql://viewer:viewer_password@postgres:5432/viewer_db REDIS_URL: redis://redis:6379 MINIO_ENDPOINT: minio MINIO_PORT: 9000 MINIO_PUBLIC_ENDPOINT: ${HOST_IP:-localhost} MINIO_PUBLIC_PORT: 9000 MINIO_ACCESS_KEY: minioadmin MINIO_SECRET_KEY: minioadmin MINIO_USE_SSL: "false" CORS_ORIGINS: http://${HOST_IP:-localhost},http://${HOST_IP:-localhost}:80,http://localhost,http://localhost:80,http://localhost:5173 depends_on: postgres: condition: service_healthy redis: condition: service_healthy minio-init: condition: service_completed_successfully healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/api/health"] interval: 30s timeout: 10s retries: 3 networks: - viewer3d-network worker: build: context: ./worker dockerfile: Dockerfile platform: linux/amd64 environment: REDIS_URL: redis://redis:6379 DATABASE_URL: postgresql://viewer:viewer_password@postgres:5432/viewer_db MINIO_ENDPOINT: minio:9000 MINIO_PUBLIC_ENDPOINT: ${HOST_IP:-localhost}:9000 MINIO_ACCESS_KEY: minioadmin MINIO_SECRET_KEY: minioadmin MINIO_USE_SSL: "false" PYOPENGL_PLATFORM: osmesa depends_on: postgres: condition: service_healthy redis: condition: service_healthy minio-init: condition: service_completed_successfully deploy: replicas: 2 networks: - viewer3d-network frontend: build: context: ./frontend dockerfile: Dockerfile # VITE_API_URL no longer needed - using nginx proxy with relative path /api platform: linux/amd64 container_name: viewer3d-frontend ports: - "80:80" depends_on: - api networks: - viewer3d-network volumes: postgres_data: redis_data: minio_data: networks: viewer3d-network: driver: bridge