diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..67b9ee1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,255 @@ +version: '3.8' + +services: + # Main Application + app: + build: + context: . + dockerfile: Dockerfile + target: production + container_name: ai-renamer-app + environment: + NODE_ENV: production + DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB} + REDIS_URL: redis://redis:6379 + MINIO_ENDPOINT: minio:9000 + MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} + MINIO_SECRET_KEY: ${MINIO_SECRET_KEY} + CLAMAV_HOST: clamav + CLAMAV_PORT: 3310 + ports: + - "${APP_PORT:-3000}:3000" + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + minio: + condition: service_healthy + networks: + - ai-renamer-prod + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + resources: + limits: + memory: 1G + cpus: '0.5' + reservations: + memory: 512M + cpus: '0.25' + + # Worker Service + worker: + build: + context: . + dockerfile: Dockerfile + target: worker + container_name: ai-renamer-worker + environment: + NODE_ENV: production + DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB} + REDIS_URL: redis://redis:6379 + MINIO_ENDPOINT: minio:9000 + MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} + MINIO_SECRET_KEY: ${MINIO_SECRET_KEY} + CLAMAV_HOST: clamav + CLAMAV_PORT: 3310 + OPENAI_API_KEY: ${OPENAI_API_KEY} + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + minio: + condition: service_healthy + networks: + - ai-renamer-prod + restart: unless-stopped + deploy: + replicas: 2 + resources: + limits: + memory: 2G + cpus: '1.0' + reservations: + memory: 1G + cpus: '0.5' + + # PostgreSQL Database + postgres: + image: postgres:16-alpine + container_name: ai-renamer-postgres + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" + volumes: + - postgres_data:/var/lib/postgresql/data + - ./db/init:/docker-entrypoint-initdb.d + networks: + - ai-renamer-prod + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + deploy: + resources: + limits: + memory: 1G + cpus: '0.5' + reservations: + memory: 512M + cpus: '0.25' + + # Redis Cache & Queue + redis: + image: redis:7-alpine + container_name: ai-renamer-redis + volumes: + - redis_data:/data + - ./redis/redis-prod.conf:/usr/local/etc/redis/redis.conf + networks: + - ai-renamer-prod + restart: unless-stopped + command: redis-server /usr/local/etc/redis/redis.conf + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + deploy: + resources: + limits: + memory: 512M + cpus: '0.25' + reservations: + memory: 256M + cpus: '0.1' + + # MinIO Object Storage + minio: + image: minio/minio:latest + container_name: ai-renamer-minio + environment: + MINIO_ROOT_USER: ${MINIO_ACCESS_KEY} + MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY} + volumes: + - minio_data:/data + networks: + - ai-renamer-prod + restart: unless-stopped + command: server /data --console-address ":9001" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 20s + retries: 3 + deploy: + resources: + limits: + memory: 1G + cpus: '0.5' + reservations: + memory: 512M + cpus: '0.25' + + # MinIO Client for bucket initialization + minio-client: + image: minio/mc:latest + container_name: ai-renamer-minio-client + depends_on: + minio: + condition: service_healthy + networks: + - ai-renamer-prod + entrypoint: > + /bin/sh -c " + sleep 10; + /usr/bin/mc alias set minio http://minio:9000 ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY}; + /usr/bin/mc mb minio/images --ignore-existing; + /usr/bin/mc mb minio/processed --ignore-existing; + /usr/bin/mc mb minio/temp --ignore-existing; + /usr/bin/mc policy set download minio/processed; + echo 'Production MinIO buckets configured successfully'; + " + + # ClamAV Antivirus Scanner + clamav: + image: clamav/clamav:latest + container_name: ai-renamer-clamav + volumes: + - clamav_data:/var/lib/clamav + networks: + - ai-renamer-prod + restart: unless-stopped + environment: + CLAMAV_NO_FRESHCLAMD: "false" + CLAMAV_NO_CLAMD: "false" + healthcheck: + test: ["CMD", "clamdscan", "--ping"] + interval: 60s + timeout: 30s + retries: 3 + start_period: 300s + deploy: + resources: + limits: + memory: 2G + cpus: '0.5' + reservations: + memory: 1G + cpus: '0.25' + + # Nginx Reverse Proxy + nginx: + image: nginx:alpine + container_name: ai-renamer-nginx + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + - ./nginx/ssl:/etc/nginx/ssl + - ./nginx/logs:/var/log/nginx + depends_on: + - app + networks: + - ai-renamer-prod + restart: unless-stopped + healthcheck: + test: ["CMD", "nginx", "-t"] + interval: 30s + timeout: 10s + retries: 3 + deploy: + resources: + limits: + memory: 256M + cpus: '0.25' + reservations: + memory: 128M + cpus: '0.1' + +volumes: + postgres_data: + driver: local + redis_data: + driver: local + minio_data: + driver: local + clamav_data: + driver: local + +networks: + ai-renamer-prod: + driver: bridge + name: ai-renamer-prod-network \ No newline at end of file