docker non-root and healthcheck fix
This commit is contained in:
@@ -3,12 +3,17 @@ FROM mcr.microsoft.com/playwright/python:v1.58.0-noble
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1
|
||||
|
||||
RUN groupadd --system app && useradd --system --gid app --create-home app
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Xvfb for headed Chromium in container (IAAI blocks headless)
|
||||
RUN apt-get update -qq && apt-get install -y --no-install-recommends xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Required for non-root Xvfb runtime in containers
|
||||
RUN mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix
|
||||
|
||||
COPY pyproject.toml uv.lock ./
|
||||
RUN pip install --no-cache-dir uv \
|
||||
&& uv export --format requirements-txt --no-dev --no-hashes --no-emit-project --frozen -o /tmp/requirements.txt \
|
||||
@@ -17,9 +22,12 @@ RUN pip install --no-cache-dir uv \
|
||||
COPY . .
|
||||
RUN python -m compileall -q iaai_scraper
|
||||
RUN chmod +x entrypoint.sh
|
||||
RUN chown -R app:app /app
|
||||
|
||||
STOPSIGNAL SIGINT
|
||||
|
||||
USER app
|
||||
|
||||
# По умолчанию API, но worker/beat переопределяют CMD в docker-compose
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
CMD ["uvicorn", "iaai_scraper.api.app:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
|
||||
@@ -121,6 +121,7 @@ services:
|
||||
<<: *worker-service
|
||||
container_name: iaai-worker
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
@@ -130,13 +131,14 @@ services:
|
||||
command: >
|
||||
celery -A iaai_scraper.worker.celery_app worker
|
||||
--loglevel=info --concurrency=1 --pool=prefork
|
||||
--pidfile=/tmp/celery-worker.pid
|
||||
-Q scraping --max-tasks-per-child=20
|
||||
healthcheck:
|
||||
test: ["CMD", "celery", "-A", "iaai_scraper.worker.celery_app", "inspect", "ping", "-d", "celery@$$HOSTNAME"]
|
||||
test: ["CMD-SHELL", "test -f /tmp/celery-worker.pid && kill -0 $(cat /tmp/celery-worker.pid)"]
|
||||
interval: 60s
|
||||
timeout: 20s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
start_period: 90s
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
@@ -148,6 +150,7 @@ services:
|
||||
<<: *worker-service
|
||||
container_name: iaai-beat
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
@@ -156,12 +159,14 @@ services:
|
||||
command: >
|
||||
celery -A iaai_scraper.worker.celery_app beat
|
||||
--loglevel=info
|
||||
--pidfile=/tmp/celery-beat.pid
|
||||
--schedule=/tmp/celerybeat-schedule
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import pathlib,sys; p=pathlib.Path('/tmp/celerybeat-schedule'); sys.exit(0 if p.exists() else 1)"]
|
||||
test: ["CMD-SHELL", "test -f /tmp/celery-beat.pid && kill -0 $(cat /tmp/celery-beat.pid)"]
|
||||
interval: 60s
|
||||
timeout: 20s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
start_period: 90s
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
|
||||
@@ -63,15 +63,35 @@ start_xvfb_if_needed() {
|
||||
# IAAI blocks headless Chromium on Linux; run headed via Xvfb virtual display
|
||||
export DISPLAY=:99
|
||||
export IAAI_HEADLESS=false
|
||||
local xvfb_pid_file="/tmp/xvfb-99.pid"
|
||||
|
||||
if [ -f "${xvfb_pid_file}" ]; then
|
||||
local existing_pid
|
||||
existing_pid="$(cat "${xvfb_pid_file}")"
|
||||
if [ -n "${existing_pid}" ] && kill -0 "${existing_pid}" 2>/dev/null; then
|
||||
echo "[entrypoint] Reusing existing Xvfb on DISPLAY=${DISPLAY} (PID ${existing_pid})"
|
||||
return 0
|
||||
fi
|
||||
echo "[entrypoint] Removing stale Xvfb pid file"
|
||||
rm -f "${xvfb_pid_file}"
|
||||
fi
|
||||
|
||||
if [ -S /tmp/.X11-unix/X99 ] || [ -f /tmp/.X99-lock ]; then
|
||||
echo "[entrypoint] Reusing existing Xvfb on DISPLAY=${DISPLAY}"
|
||||
return 0
|
||||
echo "[entrypoint] Removing stale Xvfb socket/lock files for DISPLAY=${DISPLAY}"
|
||||
rm -f /tmp/.X11-unix/X99 /tmp/.X99-lock
|
||||
fi
|
||||
|
||||
Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp &
|
||||
XVFB_PID=$!
|
||||
echo "${XVFB_PID}" > "${xvfb_pid_file}"
|
||||
sleep 0.5
|
||||
|
||||
if ! kill -0 "${XVFB_PID}" 2>/dev/null; then
|
||||
echo "[entrypoint] ERROR: Xvfb failed to start on DISPLAY=${DISPLAY}"
|
||||
rm -f "${xvfb_pid_file}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[entrypoint] Xvfb started (PID ${XVFB_PID}, DISPLAY=${DISPLAY})"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user