improve batch sync add postgres upsert fix sync locking improve listing sync speed up scraper clean up project prepare for github update docker setup
191 lines
5.4 KiB
YAML
191 lines
5.4 KiB
YAML
x-app-env: &app-env
|
|
# NB: hardcoded to Postgres — .env may contain sqlite for local CLI, don't let it leak here
|
|
IAAI_DATABASE_URL: postgresql+psycopg2://iaai:iaai@postgres:5432/iaai_scraper
|
|
IAAI_REDIS_URL: ${IAAI_REDIS_URL:-redis://redis:6379/0}
|
|
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis:6379/0}
|
|
CELERY_RESULT_BACKEND: ${CELERY_RESULT_BACKEND:-redis://redis:6379/0}
|
|
IAAI_DATABASE_POOL_RECYCLE_SECONDS: ${IAAI_DATABASE_POOL_RECYCLE_SECONDS:-1800}
|
|
CELERY_TASK_SOFT_TIME_LIMIT: ${CELERY_TASK_SOFT_TIME_LIMIT:-3300}
|
|
CELERY_TASK_TIME_LIMIT: ${CELERY_TASK_TIME_LIMIT:-3600}
|
|
CELERY_BROKER_VISIBILITY_TIMEOUT: ${CELERY_BROKER_VISIBILITY_TIMEOUT:-7200}
|
|
# Без лимита beat может забирать слишком большой объём за один запуск.
|
|
# Консервативный дефолт для anti-fraud: 300 авто за запуск.
|
|
CELERY_BEAT_SYNC_LIMIT: ${CELERY_BEAT_SYNC_LIMIT:-300}
|
|
CELERY_WORKER_MAX_TASKS_PER_CHILD: ${CELERY_WORKER_MAX_TASKS_PER_CHILD:-5}
|
|
CELERY_BATCH_SIZE: ${CELERY_BATCH_SIZE:-200}
|
|
IAAI_PARALLEL_TABS: ${IAAI_PARALLEL_TABS:-40}
|
|
IAAI_BLOCK_RESOURCES: ${IAAI_BLOCK_RESOURCES:-true}
|
|
IAAI_MAX_PAGES_PER_RUN: ${IAAI_MAX_PAGES_PER_RUN:-9999}
|
|
IAAI_MAX_VEHICLES_PER_RUN: ${IAAI_MAX_VEHICLES_PER_RUN:-50000}
|
|
IAAI_HUMAN_PACE_ENABLED: ${IAAI_HUMAN_PACE_ENABLED:-true}
|
|
IAAI_TOKENS_FILE: ${IAAI_TOKENS_FILE:-/data/tokens.json}
|
|
IAAI_RUNTIME_CONFIG_FILE: ${IAAI_RUNTIME_CONFIG_FILE:-/app/runtime_config.json}
|
|
IAAI_BROWSER_ENGINE: ${IAAI_BROWSER_ENGINE:-auto}
|
|
TZ: ${TZ:-UTC}
|
|
|
|
x-env-file: &env-file
|
|
- path: .env
|
|
required: false
|
|
|
|
x-app-service: &app-service
|
|
build: .
|
|
env_file: *env-file
|
|
environment: *app-env
|
|
volumes:
|
|
- ./runtime_config.json:/app/runtime_config.json:ro
|
|
|
|
x-worker-service: &worker-service
|
|
<<: *app-service
|
|
volumes:
|
|
- ./runtime_config.json:/app/runtime_config.json:ro
|
|
- tokens_data:/data
|
|
|
|
services:
|
|
# PostgreSQL
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: iaai-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: iaai
|
|
POSTGRES_PASSWORD: iaai
|
|
POSTGRES_DB: iaai_scraper
|
|
ports:
|
|
- "127.0.0.1:5432:5432"
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U iaai -d iaai_scraper"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 5
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "5"
|
|
|
|
# Redis (Celery broker)
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: iaai-redis
|
|
restart: unless-stopped
|
|
ports:
|
|
- "127.0.0.1:6379:6379"
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 5
|
|
command: >
|
|
redis-server
|
|
--appendonly yes
|
|
--save 60 1000
|
|
volumes:
|
|
- redisdata:/data
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "5"
|
|
|
|
# DB migrations
|
|
migrate:
|
|
<<: *app-service
|
|
container_name: iaai-migrate
|
|
restart: "no"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
command: alembic upgrade head
|
|
|
|
# FastAPI
|
|
api:
|
|
<<: *app-service
|
|
container_name: iaai-api
|
|
restart: unless-stopped
|
|
ports:
|
|
- "127.0.0.1:8000:8000"
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
redis:
|
|
condition: service_healthy
|
|
command: >
|
|
uvicorn iaai_scraper.api.app:app
|
|
--host 0.0.0.0 --port 8000 --workers 1
|
|
healthcheck:
|
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=5)"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
stop_grace_period: 30s
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "5"
|
|
|
|
# Celery Worker
|
|
worker:
|
|
<<: *worker-service
|
|
container_name: iaai-worker
|
|
restart: unless-stopped
|
|
init: true
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
redis:
|
|
condition: service_healthy
|
|
stop_grace_period: 60s
|
|
command: >
|
|
celery -A iaai_scraper.worker.celery_app worker
|
|
--loglevel=info --concurrency=4 --pool=prefork
|
|
--pidfile=/tmp/celery-worker.pid
|
|
-Q scraping --max-tasks-per-child=5
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "test -f /tmp/celery-worker.pid && kill -0 $(cat /tmp/celery-worker.pid)"]
|
|
interval: 60s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 90s
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "5"
|
|
|
|
# Celery Beat (периодический планировщик)
|
|
beat:
|
|
<<: *worker-service
|
|
container_name: iaai-beat
|
|
restart: unless-stopped
|
|
init: true
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
redis:
|
|
condition: service_healthy
|
|
command: >
|
|
celery -A iaai_scraper.worker.celery_app beat
|
|
--loglevel=info
|
|
--pidfile=/tmp/celery-beat.pid
|
|
--schedule=/tmp/celerybeat-schedule
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "test -f /tmp/celery-beat.pid && kill -0 $(cat /tmp/celery-beat.pid)"]
|
|
interval: 60s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 90s
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "5"
|
|
|
|
volumes:
|
|
pgdata:
|
|
redisdata:
|
|
tokens_data:
|