- schedd.Dockerfile: daemon 0.6.0 → 0.7.0 (cancel-канал: cancelUrl в accepted-envelope) - tasks.json: publish+githubDistro с dryRun:true у обеих тасок (мок-publish dry, ноль мутаций) - compose: DRY_RUN=1 безопасный дефолт; ozon state персистентен (bind-mount, noop работает) - тесты: мок-publish dry — yandex 13/13, ozon 10/10, GitHub/Gitea/verdaccio чисто - баг cancel воспроизведён (воркер продолжает после cancel) → ТЗ worker-cancel-url обеим командам
178 lines
6.4 KiB
YAML
178 lines
6.4 KiB
YAML
# 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:-}
|
||
# мок-publish: verdaccio (npm) + Gitea (репо/релизы)
|
||
PUBLISH_REGISTRY: ${PUBLISH_REGISTRY:-}
|
||
PUBLISH_REMOTE_BASE: ${PUBLISH_REMOTE_BASE:-}
|
||
PUBLISH_GH_API_BASE: ${PUBLISH_GH_API_BASE:-}
|
||
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/output на хосте (фикс state-output-in-image-layer):
|
||
# /app/data — единая точка, bind-mount ./data-ozon ниже.
|
||
STATE_FILE: /app/data/state.json
|
||
OUTPUT_DIR: /app/data/output/typescript
|
||
# безопасный дефолт: DRY_RUN=1. Реальный мок-publish — только явным data.dryRun=false в таске.
|
||
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:-}
|
||
# мок-publish: verdaccio (npm) + Gitea (репо/релизы) — без выхода в npmjs/github.com
|
||
PUBLISH_REGISTRY: ${PUBLISH_REGISTRY:-}
|
||
PUBLISH_REMOTE_BASE: ${PUBLISH_REMOTE_BASE:-}
|
||
PUBLISH_GH_API_BASE: ${PUBLISH_GH_API_BASE:-}
|
||
volumes:
|
||
- ./data-ozon:/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:
|
||
|
||
networks:
|
||
sched-local:
|
||
driver: bridge
|