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
+6 -4
View File
@@ -145,10 +145,12 @@ Files now stage first and are resolved before entering the library.
## 6. Infrastructure
- [ ] Guest blacklist refresh on a timer (in-container scheduler)
- [ ] Follow sync on a timer (in-container scheduler, e.g. every 30 minutes)
- [ ] Similarity temp cleanup on a timer (in-container scheduler; the TTL
also cleans lazily when new checks are created)
- [x] Guest blacklist refresh on a timer (the composes' `scheduler` service;
`J621_BLACKLIST_EVERY`, default daily)
- [x] Follow sync on a timer (same scheduler: `sync_followed_tags` +
`sync_followed_pools`, default every 30 minutes)
- [x] Similarity temp cleanup on a timer (same scheduler, default hourly;
the TTL also cleans lazily when new checks are created)
- [x] Production setup: two Docker images (SPA on static nginx, API on
gunicorn + whitenoise with ffmpeg) and three compose variants (both /
frontend-only / backend-only) behind a shared nginx proxy service, each