# sched-pipelines — локальный стенд: sched daemon + 2 HTTP-воркера (ym/ozon) # + CDP-browser (ozon антибот) + локальный ntfy + alert-bridge (sched webhook → ntfy/email). # # Расписание (sched daemon, tasks.json): ozon 2:00, yandex 2:30 — ежедневно. # Воркеры в DRY-RUN: реальные publish/push НЕ выполняются до отмашки оператора. # # Запуск: docker compose up -d --build # Секреты: .env (gitignored; значения в pass: sched-pipelines/local/*) # Миграция на VDS: образы в registry, сеть proxy, ntfy → ntfy.vds.kzntsv.site. name: sched-pipelines services: # --- sched daemon (schedd) --- schedd: build: context: . dockerfile: schedd.Dockerfile args: VERDACCIO_TOKEN: ${VERDACCIO_TOKEN:-} image: sched-pipelines/schedd:local command: - --tasks - /app/tasks.json - --db - /data/sched.db - --admin-port - "8080" - --admin-host - 0.0.0.0 - --tick-interval - "1000" environment: SCHED_ADMIN_KEY: ${SCHED_ADMIN_KEY:?задайте в .env} volumes: - ./tasks.generated.json:/app/tasks.json:ro - sched-data:/data ports: - "127.0.0.1:18080:8080" healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/api/health',{headers:{authorization:'Bearer '+process.env.SCHED_ADMIN_KEY}}).then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"] interval: 5s timeout: 3s retries: 10 restart: unless-stopped networks: [sched-local] # --- воркер Yandex Market (HTTP-воркер sched, envelope) --- ym-client-builder: build: context: ../../../../yandex-market-partner-api-client dockerfile: Dockerfile image: sched-pipelines/ym-client-builder:local environment: PORT: "8080" SCHED_API_KEY: ${SCHED_API_KEY:?задайте в .env} UNISENDER_API_KEY: mock-key UNISENDER_FROM: noreply@snolla.com NPM_TOKEN: ${NPM_TOKEN:-} GITHUB_TOKEN: ${GITHUB_TOKEN:-} volumes: - ./data-ym:/app/data ports: - "127.0.0.1:18090:8080" restart: unless-stopped networks: [sched-local] # --- воркер Ozon Seller (HTTP-воркер sched + внутренний крон ОТКЛЮЧЁН) --- ozon-seller-builder: build: context: ../../../../ozon-seller-api-client dockerfile: service/Dockerfile image: sched-pipelines/ozon-seller-builder:local environment: WORKER_PORT: "8080" SCHED_API_KEY: ${SCHED_API_KEY:?задайте в .env} # внутренний крон не нужен — расписанием рулит sched (ozon 2:00). # 31 февраля не наступает никогда: страховая от двойного запуска. CRON_SCHEDULE: "0 0 29 2 *" STATE_FILE: /app/data/state.json LOCK_FILE: /app/data/pipeline.lock DRY_RUN: "1" BROWSER_CDP_URL: http://browser:9222 NTFY_URL: http://ntfy NTFY_TOPIC: ozon-seller-pipeline UNISENDER_API_KEY: mock-key UNISENDER_SENDER_EMAIL: noreply@snolla.com UNISENDER_SENDER_NAME: sched-pipeline UNISENDER_ENDPOINT: ${UNISENDER_ENDPOINT:-https://goapi.unisender.ru/ru/transactional/api/v1/email/send.json} NOTIFY_EMAIL_TO: ${NOTIFY_EMAIL_TO:-} GH_TOKEN: ${GITHUB_TOKEN:-} NPM_TOKEN: ${NPM_TOKEN:-} volumes: - ozon-data:/app/data # снапшот спеки из репо (fetch антиботом не ходим — dry-run от ручного снапшота) - ./data-ozon-openapi:/app/openapi ports: - "127.0.0.1:18091:8080" restart: unless-stopped depends_on: - browser networks: [sched-local] # --- headless Chrome + CDP (для антибот-fetch стадий ozon) --- browser: build: context: ../../../../ozon-seller-api-client/service/browser dockerfile: Dockerfile image: sched-pipelines/browser-cdp:local container_name: browser-cdp shm_size: "1gb" restart: unless-stopped networks: [sched-local] # --- локальный ntfy (на время локального периода; VDS-ntfy требует auth-топика) --- ntfy: image: binwiederhier/ntfy:v2.11.0 command: serve environment: NTFY_LISTEN_HTTP: ":80" NTFY_CACHE_FILE: /var/cache/ntfy/cache.db volumes: - ./data-ntfy:/var/cache/ntfy ports: - "127.0.0.1:8096:80" restart: unless-stopped networks: [sched-local] # --- alert-bridge: sched webhook-алерты → ntfy + email (unisender go2) --- alert-bridge: build: ./bridge image: sched-pipelines/alert-bridge:local environment: PORT: "9090" NTFY_URL: http://ntfy NTFY_TOPIC: sched-alerts WEBHOOK_SECRET: ${WEBHOOK_SECRET:?задайте в .env} UNISENDER_API_KEY: mock-key UNISENDER_FROM: noreply@snolla.com EMAIL_TO: ${NOTIFY_EMAIL_TO:-} ports: - "127.0.0.1:19090:9090" restart: unless-stopped depends_on: - ntfy networks: [sched-local] # --- мок Unisender Go: письма в ./data-mail, реальных отправок нет --- unisender-mock: build: ./unisender-mock image: sched-pipelines/unisender-mock:local environment: PORT: "8080" MAIL_DIR: /mail volumes: - ./data-mail:/mail ports: - "127.0.0.1:18093:8080" restart: unless-stopped networks: [sched-local] volumes: sched-data: ozon-data: networks: sched-local: driver: bridge