Run the periodic commands in a scheduler service (no host cron)

Adds deploy/scheduler-entrypoint.sh to the backend image (entrypoint
j621-scheduler) and a scheduler service to the four composes that have a
backend. It waits until the database and migrations are ready, runs every
job once, then keeps to the intervals:

  sync_followed_tags + sync_followed_pools   every 30 min (J621_SYNC_EVERY)
  cleanup_similarity                         hourly      (J621_CLEAN_EVERY)
  refresh_guest_blacklist                    daily       (J621_BLACKLIST_EVERY)

It shares the backend image, media volume and env file, so commands see
the same library and database; failures are logged and retried next
interval. Output goes to docker compose logs scheduler; the frontend-only
composes have no backend and therefore no scheduler.

Verified against a real stack: the scheduler waited for migrations, ran all
four commands on start (follow syncs as anonymous, similarity cleanup, and
a guest blacklist refresh that pulled the real 14-tag list from e621), and
kept looping. All six composes still validate.
This commit is contained in:
2026-09-18 12:51:17 -05:00
parent 93cce6b9fd
commit f25526782c
10 changed files with 204 additions and 5 deletions
+17
View File
@@ -123,6 +123,23 @@ Push multi-arch images to the Gitea registry:
They tag `:latest` and `:<commit-sha>` and expect `docker login
gitea.rainbow-herring.ts.net` to succeed.
## Scheduled jobs
Compose files with a backend also run a **`scheduler`** service — the same
backend image with a different entrypoint, so no host cron is involved:
| Job | Default interval | Env override |
| --- | --- | --- |
| `sync_followed_tags` + `sync_followed_pools` | every 30 minutes | `J621_SYNC_EVERY` |
| `cleanup_similarity` | hourly | `J621_CLEAN_EVERY` |
| `refresh_guest_blacklist` | daily | `J621_BLACKLIST_EVERY` |
It waits for the database and migrations before its first run, runs every job
once on start, then keeps to the intervals (failures are logged and retried
next round). Output goes to `docker compose logs scheduler`. Intervals are
seconds, set in `deploy/.env`. The frontend-only composes have no backend, so
no scheduler.
## Tests
The security/permission suite lives in `backend/apps/core/tests/`: