services: postgres: image: postgis/postgis:16-3.4 environment: POSTGRES_DB: ${POSTGRES_DB:-gendesign} POSTGRES_USER: ${POSTGRES_USER:-gendesign} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-gendesign} ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./backend/db/init:/docker-entrypoint-initdb.d:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER:-gendesign}"] interval: 5s timeout: 5s retries: 10 redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 backend: build: context: ./backend target: runner env_file: ./backend/.env depends_on: postgres: condition: service_healthy redis: condition: service_started ports: - "8000:8000" volumes: - ./backend/app:/app/app command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] frontend: build: ./frontend # BACKEND_URL is read by next.config.ts rewrites (/api/* -> backend). # The browser hits Next.js on :3000 with relative paths, Next.js proxies to backend. environment: BACKEND_URL: http://backend:8000 ports: - "3000:3000" depends_on: - backend worker: build: context: ./backend target: runner-with-chromium # +Playwright Chromium для kn-scraper env_file: ./backend/.env depends_on: postgres: condition: service_healthy redis: condition: service_started volumes: - ./backend/app:/app/app - ./data:/app/data # storage_state.json + photo binaries command: ["celery", "-A", "app.workers.celery_app", "worker", "--loglevel=info", "--concurrency=2"] beat: build: context: ./backend target: runner # lean — beat только триггерит, без Chromium env_file: ./backend/.env depends_on: redis: condition: service_started volumes: - ./backend/app:/app/app command: ["celery", "-A", "app.workers.celery_app", "beat", "--loglevel=info"] volumes: postgres_data: redis_data: