services: # Основное приложение MY UPLOADER BOT app: build: context: .. dockerfile: deployment/Dockerfile.simple container_name: my-uploader-app restart: unless-stopped depends_on: - postgres - redis ports: - "127.0.0.1:15100:15100" env_file: - ../.env volumes: - app_data:/app/data - app_logs:/app/logs - ../app/my_network/bootstrap.json:/app/app/my_network/bootstrap.json:ro - /var/run/docker.sock:/var/run/docker.sock # Для управления converter контейнерами - converter_shared:/shared/converter # Общая папка для converter заданий environment: # Основные настройки - NODE_ENV=production - DEBUG=false # Database - DATABASE_URL=postgresql://my_user:${POSTGRES_PASSWORD}@postgres:5432/my_uploader_db - POSTGRES_HOST=postgres - POSTGRES_PORT=5432 - POSTGRES_DB=my_uploader_db - POSTGRES_USER=my_user - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} # Redis - REDIS_URL=redis://redis:6379/0 - REDIS_HOST=redis - REDIS_PORT=6379 # Security - SECRET_KEY=${SECRET_KEY} - JWT_SECRET=${JWT_SECRET} - ENCRYPTION_KEY=${ENCRYPTION_KEY} # MY Network - MY_NETWORK_NODE_ID=${MY_NETWORK_NODE_ID} - MY_NETWORK_PORT=15100 - MY_NETWORK_HOST=0.0.0.0 - MY_NETWORK_DOMAIN=${MY_NETWORK_DOMAIN} - MY_NETWORK_SSL_ENABLED=true # API Settings - API_HOST=0.0.0.0 - API_PORT=15100 - API_WORKERS=4 - MAX_UPLOAD_SIZE=100MB # Converter Settings (on-demand) - CONVERTER_DOCKER_IMAGE=my-converter:latest - CONVERTER_SHARED_PATH=/shared/converter - CONVERTER_MAX_PARALLEL=3 - CONVERTER_TIMEOUT=300 # Logging - LOG_LEVEL=INFO - LOG_FORMAT=json networks: - uploader_network healthcheck: test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:15100/health')"] interval: 30s timeout: 10s retries: 3 start_period: 40s # PostgreSQL Database postgres: image: postgres:15-alpine container_name: my-postgres restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-db-production.sql:/docker-entrypoint-initdb.d/01-init.sql:ro environment: - POSTGRES_DB=my_uploader_db - POSTGRES_USER=my_user - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_INITDB_ARGS=--auth-host=md5 ports: - "127.0.0.1:5434:5432" networks: - uploader_network healthcheck: test: ["CMD-SHELL", "pg_isready -U my_user -d my_uploader_db"] interval: 10s timeout: 5s retries: 5 # Redis Cache redis: image: redis:7-alpine container_name: my-redis restart: unless-stopped volumes: - redis_data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf:ro command: redis-server /usr/local/etc/redis/redis.conf ports: - "127.0.0.1:6380:6379" networks: - uploader_network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 3 # Web2 Client web2-client: build: context: ./modules/web2-client dockerfile: Dockerfile profiles: ["main-node"] # Only build for main nodes container_name: my-web2-client restart: unless-stopped depends_on: - app ports: - "127.0.0.1:3000:3000" volumes: - web2_uploads:/app/uploads environment: - NODE_ENV=production - API_URL=http://app:15100 - UPLOAD_PATH=/app/uploads networks: - uploader_network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: my-nginx restart: unless-stopped depends_on: - app ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/sites-enabled:/etc/nginx/sites-enabled:ro - ./ssl:/etc/nginx/ssl:ro - nginx_logs:/var/log/nginx - ./nginx/html:/usr/share/nginx/html:ro networks: - uploader_network healthcheck: test: ["CMD", "nginx", "-t"] interval: 30s timeout: 10s retries: 3 # Monitoring Stack (Prometheus + Grafana) prometheus: image: prom/prometheus:latest container_name: my-prometheus restart: unless-stopped ports: - "127.0.0.1:9090:9090" volumes: - prometheus_data:/prometheus - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--web.enable-lifecycle' networks: - uploader_network grafana: image: grafana/grafana:latest container_name: my-grafana restart: unless-stopped ports: - "127.0.0.1:3001:3000" volumes: - grafana_data:/var/lib/grafana - ./monitoring/grafana:/etc/grafana/provisioning:ro environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} - GF_USERS_ALLOW_SIGN_UP=false - GF_SERVER_DOMAIN=${MY_NETWORK_DOMAIN} networks: - uploader_network # Log Management loki: image: grafana/loki:latest container_name: my-loki restart: unless-stopped ports: - "127.0.0.1:3100:3100" volumes: - loki_data:/loki - ./monitoring/loki.yml:/etc/loki/local-config.yaml:ro command: -config.file=/etc/loki/local-config.yaml networks: - uploader_network # Log Collection promtail: image: grafana/promtail:latest container_name: my-promtail restart: unless-stopped volumes: - /var/log:/var/log:ro - ./monitoring/promtail.yml:/etc/promtail/config.yml:ro - app_logs:/var/log/app:ro - nginx_logs:/var/log/nginx:ro command: -config.file=/etc/promtail/config.yml networks: - uploader_network # ============================================================================= # CONVERTER MODULE BUILD (собирается, но не запускается постоянно) # ============================================================================= # Этот сервис используется только для сборки image # Основное приложение будет создавать контейнеры on-demand converter-build: build: context: ./modules/converter-module dockerfile: Dockerfile image: my-converter:latest container_name: my-converter-build profiles: ["build-only"] # Запускается только при сборке volumes: - converter_shared:/shared/converter networks: - uploader_network volumes: # Application data app_data: driver: local app_logs: driver: local # Database postgres_data: driver: local redis_data: driver: local # Modules converter_shared: # Общая папка для on-demand converter заданий driver: local web2_uploads: driver: local # Infrastructure nginx_logs: driver: local # Monitoring prometheus_data: driver: local grafana_data: driver: local loki_data: driver: local networks: uploader_network: driver: bridge ipam: config: - subnet: 172.20.0.0/16