fix(beat): use /tmp/celerybeat-schedule (workdir /app not writable by app user) #226
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#226
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/beat-celerybeat-schedule-permission"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Beat container в restart-loop после PR #225 force-recreate. GlitchTip Issues заполняется одной и той же ошибкой:
Beat не работает → все scheduled tasks НЕ запускаются:
scrape_kn(DOM.РФ еженедельный)scrape_objective_sync(Объектив еженедельный)scrape_ekburg_permits_sync(РНС/РВЭ ежемесячный)scrape_nspd_geo,scrape_pzz,scrape_poi,scrape_noiseRoot cause
backend/Dockerfilerunner stage:WORKDIR /appсоздаётся под root → ownerroot:root.COPY --chown=app:appпереносит файлы (.venv/,app/,alembic/,alembic.ini) подapp, но саму директорию/app/не chown'ит.USER app→app(uid 1000) не может создавать новые файлы в/app/(нет write permission на parent dir)./app/celerybeat-scheduleсуществовал в writable форме из inherited state (предположительно от первого запуска под root). Force-recreate из PR #225 сбросил состояние.Fix
--schedule=/tmp/celerybeat-schedule—/tmpвсегда writable. Schedule-файл хранит толькоlast_run_atдля periodic tasks; потеря на container restart OK, beat перестраивает изcelery_app.conf.beat_scheduleна старте.Не делаю в этом PR
chown app:app /appв runner stage). Runner stage шарится с FastAPI backend image (uvicorn) и worker — риск регрессии больше чем у однострочного--scheduleoverride. Можно отдельным PR после verify что beat работает.Test plan
docker compose -p gendesign logs beat --tail 50— нетPermission denied, естьbeat: Starting..._gdbm.errorнетReferences
APPROVE — merged via deep-code-reviewer.
Findings
Fix корректен. Дефолт celery beat →
./celerybeat-scheduleотносительно cwd =/app(per DockerfileWORKDIR /app)./appownedroot:root(создан доuseradd app),COPY --chown=app:appchown'ит только содержимое, не сам каталог → uid 1000 не может создать новый файл./tmpвсегда1777вpython:3.12-slim(стандартный Debian base), tmpfs не смонтирован на beat → файл сохранится между beat-restart'ами в пределах одного container lifetime, потеряется приup -d --force-recreate— это OK.Idempotency проверена. Потеря shelve = потеря
last_run_at. На стартеbuild_beat_schedule()(см.backend/app/workers/beat_schedule.py) перестраивает расписание изjob_settingsБД (с env fallback). Все cron-таски в codebase идемпотентные (scrape_kn,objective_sync,refresh_analytics,nspd-geo-zombie-cleanup,poi-sync-weekly,noise-sync-weekly,ekburg-permits-monthly) — повторный запуск после restart безопасен.Single-file scope. Только
docker-compose.prod.yml→ триггеритdeploy.yml(см..claude/rules/deploy.md). Worker / backend / Caddyfile не тронуты. Нетread_only: true/ tmpfs override на beat —/tmpwritable.Anti-regression. В vault
meta/00_credentials.mdошибка уже была отмечена как pre-existing issue ("known Celery beat schedule file perms issue") — этот PR её закрывает. Никаких--no-verify/ force-push в истории ветки.Tradeoff (acceptable)
/tmpephemeral между recreate'ами → таска с week+ cron может выстрелить лишний раз после redeploy. Для всех текущих cron-таск это безопасно (idempotent scrapers/refresh).Recommendation для permanent fix (отдельный PR, не блокирующий)
В
backend/Dockerfilerunner stage добавитьRUN mkdir -p /app && chown app:app /appдоWORKDIR /app, либоUSER root→chown -R app:app /app→USER appпосле COPY. Тогда beat сможет писать schedule в default location, и поведение между recreate'ами станет deterministic (shelve переживёт перезапуск container'а с тем же image). Затронет shared image (uvicorn + worker + beat) — нужен smoke-test, но риск низкий (chown пустой dir → no-op для backend/worker, write для beat).Vault update note
После verify зелёного deploy — обнови
meta/00_credentials.md(убрать "Pre-existing issue" про beat) и добавьfixes/Fix_Beat_CelerybeatSchedule_Tmp_May16.mdper CLAUDE.md rule #6.Merge commit:
e4852b0.