postgres redis docker compose setup
This commit is contained in:
@@ -14,4 +14,3 @@ coverage.xml
|
|||||||
*.egg-info/
|
*.egg-info/
|
||||||
dist/
|
dist/
|
||||||
build/
|
build/
|
||||||
artifacts/
|
|
||||||
|
|||||||
26
.env.example
26
.env.example
@@ -1,15 +1,11 @@
|
|||||||
IAAI_HEADLESS=true
|
IAAI_HEADLESS=true
|
||||||
IAAI_RAW_OUTPUT_JSON=iaai_raw_network.json
|
|
||||||
IAAI_LOG_LEVEL=INFO
|
IAAI_LOG_LEVEL=INFO
|
||||||
# IAAI_LOG_FILE=iaai_scraper.log
|
# IAAI_LOG_FILE=iaai_scraper.log
|
||||||
|
|
||||||
# Conservative first-run mode.
|
# Network capture settings.
|
||||||
IAAI_GENTLE_MODE=true
|
|
||||||
IAAI_CAPTURE_SAME_ORIGIN_ONLY=true
|
IAAI_CAPTURE_SAME_ORIGIN_ONLY=true
|
||||||
IAAI_MAX_CAPTURED_REQUESTS=40
|
IAAI_MAX_CAPTURED_REQUESTS=40
|
||||||
IAAI_MAX_CAPTURED_JSON_RESPONSES=30
|
IAAI_MAX_CAPTURED_JSON_RESPONSES=30
|
||||||
IAAI_WARM_SCROLL_ROUNDS=1
|
|
||||||
IAAI_POST_OPEN_IDLE_MS=3500
|
|
||||||
|
|
||||||
# Sequential listing-first mode.
|
# Sequential listing-first mode.
|
||||||
IAAI_CARS_LISTING_URL=https://www.iaai.com/Vehiclelisting/Cars
|
IAAI_CARS_LISTING_URL=https://www.iaai.com/Vehiclelisting/Cars
|
||||||
@@ -34,8 +30,7 @@ IAAI_BETWEEN_VEHICLES_MAX_S=6.0
|
|||||||
IAAI_AFTER_PAGE_CHANGE_MIN_S=3.0
|
IAAI_AFTER_PAGE_CHANGE_MIN_S=3.0
|
||||||
IAAI_AFTER_PAGE_CHANGE_MAX_S=6.0
|
IAAI_AFTER_PAGE_CHANGE_MAX_S=6.0
|
||||||
|
|
||||||
# Scheduler (default once per hour)
|
# Sync settings
|
||||||
IAAI_SCHEDULER_INTERVAL_MINUTES=60
|
|
||||||
IAAI_SYNC_ONLY_NEW=true
|
IAAI_SYNC_ONLY_NEW=true
|
||||||
|
|
||||||
# Retry / backoff
|
# Retry / backoff
|
||||||
@@ -50,6 +45,19 @@ IAAI_RETRY_JITTER_SECONDS=0.25
|
|||||||
# IAAI_PROXY_USERNAME=
|
# IAAI_PROXY_USERNAME=
|
||||||
# IAAI_PROXY_PASSWORD=
|
# IAAI_PROXY_PASSWORD=
|
||||||
|
|
||||||
# Database.
|
# Database (PostgreSQL).
|
||||||
IAAI_DATABASE_URL=sqlite:///iaai_scraper.db
|
IAAI_DATABASE_URL=postgresql+psycopg2://iaai:iaai@postgres:5432/iaai_scraper
|
||||||
IAAI_DATABASE_ECHO=false
|
IAAI_DATABASE_ECHO=false
|
||||||
|
IAAI_DATABASE_POOL_SIZE=5
|
||||||
|
IAAI_DATABASE_MAX_OVERFLOW=10
|
||||||
|
|
||||||
|
# ─── Redis (Celery broker) ─────────────────────────────────
|
||||||
|
IAAI_REDIS_URL=redis://redis:6379/0
|
||||||
|
|
||||||
|
# ─── Celery ────────────────────────────────────────────────
|
||||||
|
CELERY_BROKER_URL=redis://redis:6379/0
|
||||||
|
CELERY_RESULT_BACKEND=redis://redis:6379/0
|
||||||
|
CELERY_TASK_SOFT_TIME_LIMIT=600
|
||||||
|
CELERY_TASK_TIME_LIMIT=900
|
||||||
|
CELERY_WORKER_CONCURRENCY=1
|
||||||
|
CELERY_BEAT_SYNC_INTERVAL_MINUTES=60
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,9 +8,10 @@ coverage.xml
|
|||||||
*.pyd
|
*.pyd
|
||||||
*.log
|
*.log
|
||||||
*.db
|
*.db
|
||||||
*.json
|
|
||||||
.env
|
.env
|
||||||
.vscode/
|
.vscode/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
dist/
|
dist/
|
||||||
build/
|
build/
|
||||||
|
artifacts/
|
||||||
|
celerybeat-schedule*
|
||||||
@@ -17,5 +17,6 @@ RUN chmod +x entrypoint.sh
|
|||||||
|
|
||||||
STOPSIGNAL SIGINT
|
STOPSIGNAL SIGINT
|
||||||
|
|
||||||
|
# По умолчанию — API, но worker/beat переопределяют CMD в docker-compose
|
||||||
ENTRYPOINT ["./entrypoint.sh"]
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
CMD ["python", "main.py", "run-daemon"]
|
CMD ["uvicorn", "iaai_scraper.api.app:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
|
|||||||
@@ -1,15 +1,105 @@
|
|||||||
services:
|
services:
|
||||||
iaai-scraper:
|
# ─── 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:
|
||||||
|
- "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
|
||||||
|
|
||||||
|
# ─── Redis (Celery broker) ────────────────────────────────
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: iaai-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
# ─── FastAPI ──────────────────────────────────────────────
|
||||||
|
api:
|
||||||
build: .
|
build: .
|
||||||
container_name: iaai-scraper
|
container_name: iaai-api
|
||||||
|
restart: unless-stopped
|
||||||
env_file:
|
env_file:
|
||||||
- path: .env
|
- path: .env
|
||||||
required: false
|
required: false
|
||||||
volumes:
|
environment:
|
||||||
- ./:/app
|
IAAI_DATABASE_URL: postgresql+psycopg2://iaai:iaai@postgres:5432/iaai_scraper
|
||||||
- /app/.venv
|
IAAI_REDIS_URL: redis://redis:6379/0
|
||||||
- /app/__pycache__
|
CELERY_BROKER_URL: redis://redis:6379/0
|
||||||
working_dir: /app
|
CELERY_RESULT_BACKEND: redis://redis:6379/0
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
command: >
|
||||||
|
uvicorn iaai_scraper.api.app:app
|
||||||
|
--host 0.0.0.0 --port 8000 --workers 2
|
||||||
|
|
||||||
|
# ─── Celery Worker ────────────────────────────────────────
|
||||||
|
worker:
|
||||||
|
build: .
|
||||||
|
container_name: iaai-worker
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_grace_period: 30s
|
env_file:
|
||||||
command: python main.py run-daemon
|
- path: .env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
IAAI_DATABASE_URL: postgresql+psycopg2://iaai:iaai@postgres:5432/iaai_scraper
|
||||||
|
IAAI_REDIS_URL: redis://redis:6379/0
|
||||||
|
CELERY_BROKER_URL: redis://redis:6379/0
|
||||||
|
CELERY_RESULT_BACKEND: redis://redis:6379/0
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
stop_grace_period: 60s
|
||||||
|
command: >
|
||||||
|
celery -A iaai_scraper.worker.celery_app worker
|
||||||
|
--loglevel=info --concurrency=1 --pool=prefork
|
||||||
|
-Q scraping --without-heartbeat
|
||||||
|
|
||||||
|
# ─── Celery Beat (периодический планировщик) ──────────────
|
||||||
|
beat:
|
||||||
|
build: .
|
||||||
|
container_name: iaai-beat
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
IAAI_DATABASE_URL: postgresql+psycopg2://iaai:iaai@postgres:5432/iaai_scraper
|
||||||
|
IAAI_REDIS_URL: redis://redis:6379/0
|
||||||
|
CELERY_BROKER_URL: redis://redis:6379/0
|
||||||
|
CELERY_RESULT_BACKEND: redis://redis:6379/0
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
command: >
|
||||||
|
celery -A iaai_scraper.worker.celery_app beat
|
||||||
|
--loglevel=info
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
|||||||
@@ -20,12 +20,38 @@ if [ -n "$SOCKS5_PROXY_HOST" ]; then
|
|||||||
echo "[entrypoint] Proxy bridge started (PID $BRIDGE_PID)"
|
echo "[entrypoint] Proxy bridge started (PID $BRIDGE_PID)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# IAAI blocks headless Chromium on Linux; run headed via Xvfb virtual display
|
# Xvfb needed only for worker (Playwright) — not for API or beat
|
||||||
export DISPLAY=:99
|
NEEDS_XVFB=false
|
||||||
export IAAI_HEADLESS=false
|
case "$1" in
|
||||||
Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp &
|
celery*|python*main*)
|
||||||
XVFB_PID=$!
|
NEEDS_XVFB=true
|
||||||
sleep 0.5
|
;;
|
||||||
echo "[entrypoint] Xvfb started (PID $XVFB_PID, DISPLAY=$DISPLAY)"
|
*)
|
||||||
|
# Check if any arg contains "worker"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
*worker*) NEEDS_XVFB=true; break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$NEEDS_XVFB" = "true" ]; then
|
||||||
|
# IAAI blocks headless Chromium on Linux; run headed via Xvfb virtual display
|
||||||
|
export DISPLAY=:99
|
||||||
|
export IAAI_HEADLESS=false
|
||||||
|
Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp &
|
||||||
|
XVFB_PID=$!
|
||||||
|
sleep 0.5
|
||||||
|
echo "[entrypoint] Xvfb started (PID $XVFB_PID, DISPLAY=$DISPLAY)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run Alembic migrations (only for API service, skip for worker/beat)
|
||||||
|
case "$1" in
|
||||||
|
uvicorn*)
|
||||||
|
echo "[entrypoint] Running Alembic migrations..."
|
||||||
|
alembic upgrade head || echo "[entrypoint] WARNING: Alembic migration failed, continuing..."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ playwright>=1.53.0
|
|||||||
python-dotenv>=1.0.1
|
python-dotenv>=1.0.1
|
||||||
pydantic>=2.8.2
|
pydantic>=2.8.2
|
||||||
SQLAlchemy>=2.0.32
|
SQLAlchemy>=2.0.32
|
||||||
PySocks>=1.7.1
|
fastapi>=0.115.0
|
||||||
|
uvicorn>=0.34.0
|
||||||
|
celery>=5.4.0
|
||||||
|
redis>=5.2.0
|
||||||
|
psycopg2-binary>=2.9.9
|
||||||
|
alembic>=1.14.0
|
||||||
pytest>=8.3.0
|
pytest>=8.3.0
|
||||||
pytest-cov>=5.0.0
|
pytest-cov>=5.0.0
|
||||||
Reference in New Issue
Block a user