diff --git a/.env.example b/.env.example index 0f378eb..8d5d573 100644 --- a/.env.example +++ b/.env.example @@ -12,7 +12,8 @@ ENABLED_MODULES=tenancy,organizations,identity,access,admin,dashboard,policy,aud CELERY_ENABLED=true REDIS_URL=redis://127.0.0.1:6379/0 -CELERY_QUEUES=send_email,append_sent,default +CELERY_QUEUES=send_email,append_sent,notifications,calendar,default +CALENDAR_OUTBOX_TERMINAL_RETENTION_DAYS=90 CORS_ORIGINS=https://govoplan.example.org AUTH_COOKIE_SECURE=true diff --git a/dev/production-like/.env.example b/dev/production-like/.env.example index 8390fa9..e45431d 100644 --- a/dev/production-like/.env.example +++ b/dev/production-like/.env.example @@ -16,7 +16,8 @@ DATABASE_URL=postgresql+psycopg://govoplan:govoplan-dev@127.0.0.1:55433/govoplan GOVOPLAN_DATABASE_URL_PGTOOLS=postgresql://govoplan:govoplan-dev@127.0.0.1:55433/govoplan REDIS_URL=redis://127.0.0.1:56379/0 CELERY_ENABLED=true -CELERY_QUEUES=send_email,append_sent,default +CELERY_QUEUES=send_email,append_sent,notifications,calendar,default +CALENDAR_OUTBOX_TERMINAL_RETENTION_DAYS=90 ENABLED_MODULES=tenancy,organizations,identity,access,admin,dashboard,policy,audit,campaigns,files,mail,calendar,docs,ops CORS_ORIGINS=http://127.0.0.1:5173,http://localhost:5173 diff --git a/dev/production-like/README.md b/dev/production-like/README.md index afe20d5..759b25e 100644 --- a/dev/production-like/README.md +++ b/dev/production-like/README.md @@ -1,7 +1,7 @@ # Production-Like Development Profile This profile runs the shared services that production depends on while keeping -API, worker, and WebUI code in the editable local repositories. +API, worker, scheduler, and WebUI code in the editable local repositories. It provides: @@ -10,6 +10,7 @@ It provides: - explicit `ENABLED_MODULES` - local durable file storage under `runtime/production-like/files` - a Celery worker process using the same queues as the API +- a Celery beat process for durable retry and recovery schedules Start it from the meta repository: @@ -37,7 +38,7 @@ password changes: cp dev/production-like/.env.example dev/production-like/.env ``` -The API and worker use: +The API, worker, and scheduler use: ```text DATABASE_URL=postgresql+psycopg://govoplan:govoplan-dev@127.0.0.1:55433/govoplan @@ -45,7 +46,7 @@ REDIS_URL=redis://127.0.0.1:56379/0 CELERY_ENABLED=true ``` -Stop the launched API/WebUI/worker with `Ctrl+C`. The PostgreSQL and Redis +Stop the launched API/WebUI/worker/scheduler with `Ctrl+C`. The PostgreSQL and Redis containers keep running by default so the next launch is fast. To stop them too: ```bash diff --git a/tools/launch/launch-production-like-dev.sh b/tools/launch/launch-production-like-dev.sh index bc3b994..56973f7 100644 --- a/tools/launch/launch-production-like-dev.sh +++ b/tools/launch/launch-production-like-dev.sh @@ -27,12 +27,14 @@ STOP_DEPENDENCIES_ON_EXIT="${GOVOPLAN_STOP_PROFILE_DEPENDENCIES_ON_EXIT:-0}" LOG_DIR="$META_ROOT/runtime/production-like/logs" BACKEND_LOG="$LOG_DIR/backend.log" WORKER_LOG="$LOG_DIR/worker.log" +BEAT_LOG="$LOG_DIR/beat.log" FRONTEND_LOG="$LOG_DIR/frontend.log" BACKEND_URL="http://$BACKEND_HOST:$BACKEND_PORT" FRONTEND_URL="http://$FRONTEND_HOST:$FRONTEND_PORT" backend_pid="" worker_pid="" +beat_pid="" frontend_pid="" fail() { @@ -54,7 +56,7 @@ export DATABASE_URL="${DATABASE_URL:-${GOVOPLAN_PRODUCTION_LIKE_DATABASE_URL:-po export GOVOPLAN_DATABASE_URL_PGTOOLS="${GOVOPLAN_DATABASE_URL_PGTOOLS:-${GOVOPLAN_PRODUCTION_LIKE_DATABASE_URL_PGTOOLS:-postgresql://govoplan:govoplan-dev@127.0.0.1:55433/govoplan}}" export REDIS_URL="${REDIS_URL:-${GOVOPLAN_PRODUCTION_LIKE_REDIS_URL:-redis://127.0.0.1:56379/0}}" export CELERY_ENABLED="${CELERY_ENABLED:-true}" -export CELERY_QUEUES="${CELERY_QUEUES:-send_email,append_sent,default}" +export CELERY_QUEUES="${CELERY_QUEUES:-send_email,append_sent,notifications,calendar,default}" export FILE_STORAGE_BACKEND="${FILE_STORAGE_BACKEND:-local}" export FILE_STORAGE_LOCAL_ROOT="${FILE_STORAGE_LOCAL_ROOT:-$META_ROOT/runtime/production-like/files}" export DEV_AUTO_MIGRATE_ENABLED="${DEV_AUTO_MIGRATE_ENABLED:-false}" @@ -146,6 +148,9 @@ cleanup() { if [ -n "${worker_pid:-}" ] && kill -0 "$worker_pid" 2>/dev/null; then kill "$worker_pid" 2>/dev/null || true fi + if [ -n "${beat_pid:-}" ] && kill -0 "$beat_pid" 2>/dev/null; then + kill "$beat_pid" 2>/dev/null || true + fi if [ "$STOP_DEPENDENCIES_ON_EXIT" = "1" ]; then compose down >/dev/null 2>&1 || true fi @@ -160,6 +165,7 @@ trap cleanup EXIT INT TERM mkdir -p "$LOG_DIR" "$FILE_STORAGE_LOCAL_ROOT" : > "$BACKEND_LOG" : > "$WORKER_LOG" +: > "$BEAT_LOG" : > "$FRONTEND_LOG" port_is_free "$BACKEND_HOST" "$BACKEND_PORT" || fail "$BACKEND_URL is already in use" @@ -200,6 +206,14 @@ printf 'Starting Celery worker for queues %s\n' "$CELERY_QUEUES" ) >"$WORKER_LOG" 2>&1 & worker_pid="$!" +printf 'Starting Celery beat for durable recovery schedules\n' +( + cd "$ROOT" + "$PYTHON" -m celery -A govoplan_core.celery_app:celery beat \ + --loglevel INFO +) >"$BEAT_LOG" 2>&1 & +beat_pid="$!" + printf 'Starting GovOPlaN WebUI at %s\n' "$FRONTEND_URL" ( cd "$WEBUI_ROOT" @@ -235,10 +249,11 @@ Files: $FILE_STORAGE_LOCAL_ROOT Logs: Backend: $BACKEND_LOG Worker: $WORKER_LOG +Beat: $BEAT_LOG WebUI: $FRONTEND_LOG Docker dependencies remain running after Ctrl+C unless GOVOPLAN_STOP_PROFILE_DEPENDENCIES_ON_EXIT=1. -Press Ctrl+C to stop API, worker, and WebUI. +Press Ctrl+C to stop API, worker, beat, and WebUI. EOF wait diff --git a/tools/launch/production-like-dev.sh b/tools/launch/production-like-dev.sh index 12bab81..ae01e25 100644 --- a/tools/launch/production-like-dev.sh +++ b/tools/launch/production-like-dev.sh @@ -19,7 +19,7 @@ usage() { Usage: tools/launch/production-like-dev.sh [--yes] Commands: - start Start the production-like API, worker, WebUI, PostgreSQL, and Redis profile. + start Start the production-like API, worker, scheduler, WebUI, PostgreSQL, and Redis profile. stop Stop PostgreSQL and Redis profile containers. status Show profile container status and validate the effective environment. seed Run migrations and seed development data against the profile database. @@ -27,7 +27,7 @@ Commands: validate-config Validate the profile environment only. The start command delegates to tools/launch/launch-production-like-dev.sh. Stop/reset -operate on Docker dependencies; API/WebUI/worker processes started by the +operate on Docker dependencies; API/WebUI/worker/scheduler processes started by the launcher are stopped with Ctrl+C in that launcher terminal. EOF }