# Локальный запуск и тесты: docker compose up -d --build # Шаблон для релизов — docker-compose.prod.yml (make release). x-backend-env: &backend-env RABBITMQ_URL: amqp://robotex:${RABBITMQ_PASSWORD:-robotex}@rabbitmq:5672/ REDIS_URL: redis://redis:6379/0 DATABASE_URL: postgresql+asyncpg://robotex:${POSTGRES_PASSWORD:-robotex}@postgres:5432/robotex services: api: build: context: . dockerfile: Dockerfile.api image: robotex-api:latest restart: unless-stopped ports: - "${API_PORT:-8000}:8000" env_file: - path: .env required: false environment: *backend-env depends_on: rabbitmq: {condition: service_healthy} redis: {condition: service_healthy} postgres: {condition: service_healthy} worker: build: . image: robotex-worker:latest restart: unless-stopped env_file: - path: .env required: false environment: *backend-env volumes: - extra:/app/extra # Chrome активно использует /dev/shm, дефолтных 64MB не хватает shm_size: "2gb" # Потолок ресурсов: при переборе OOM-killer прибьёт процесс Chrome внутри контейнера, # а не соседние сервисы на хосте. Подбирать под сервер вместе с BROWSER_SLOTS. cpus: ${WORKER_CPUS:-4} mem_limit: ${WORKER_MEM_LIMIT:-8g} memswap_limit: ${WORKER_MEM_LIMIT:-8g} # при остановке воркер дожидается текущих задач и закрывает окна stop_grace_period: 60s depends_on: rabbitmq: {condition: service_healthy} redis: {condition: service_healthy} postgres: {condition: service_healthy} rabbitmq: image: rabbitmq:4.1-alpine restart: unless-stopped environment: RABBITMQ_DEFAULT_USER: robotex RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-robotex} # задача выполняется до 3 ч, а по умолчанию RabbitMQ рвёт канал, если сообщение не подтверждено 30 мин RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: -rabbit consumer_timeout 14400000 volumes: - rabbitmq:/var/lib/rabbitmq healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 10s timeout: 10s retries: 10 # клиенты и API-ключи, журнал окон и запросов postgres: image: postgres:17-alpine restart: unless-stopped environment: POSTGRES_USER: robotex POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-robotex} POSTGRES_DB: robotex volumes: - postgres:/var/lib/postgresql/data healthcheck: test: ["CMD", "pg_isready", "-U", "robotex", "-d", "robotex"] interval: 5s timeout: 5s retries: 10 redis: image: redis:8.2-alpine restart: unless-stopped volumes: - redis:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 10 # HTTP-прокси для локальных тестов (exit-IP = IP хоста): docker compose --profile loadtest up -d # из контейнера worker доступен как http://proxy:8080 proxy: image: gogost/gost:3.1.0 profiles: ["loadtest"] restart: unless-stopped command: ["-L", "http://:8080"] volumes: extra: rabbitmq: redis: postgres: