PostgreSQL compose file: no worker, and the documented worker command swaps the instance onto an empty SQLite #581

Closed
opened 2026-10-01 10:47:48 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, comparing the two compose files and the instructions for background work.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The wiki has moved to 9aefad9b6, where the Configuration.md passage is now at :407-415.

docker/compose.yml gained a worker service for POSTULO_BACKGROUND_WORK (#247); docker/compose.postgres.yml did not, which is the same drift #219 found for the scheduler. Both .env.example and the wiki tell every operator to start the worker with docker compose -f docker/compose.yml --profile worker up -d, naming only the SQLite file. Both files declare name: postulo, a service called postulo and the volume postulo-data, so on a PostgreSQL install that command replaces the running web container with one pointed at a new, empty SQLite database.

  • Where: docker/compose.postgres.yml:15-102 (services postulo, scheduler, db only); docker/compose.yml:88-123 (the worker); .env.example:125-126; the wiki's Configuration.md:405-413; Installing-Postulo.md:236 ("There is no background worker to run. Nothing in Postulo currently queues work."); tests/test_image_build.py:184, which checks only that the PostgreSQL file has a scheduler.
  • What happens:
    1. A PostgreSQL operator sets POSTULO_BACKGROUND_WORK=true as instructed. Their compose file has no worker, so every capture, logo, PDF and export queues work that nobody runs.
    2. If they run the documented command instead, Compose sees a changed postulo service in the same project and recreates it with POSTULO_DATABASE_URL: sqlite:////app/data/postulo.sqlite3. The entrypoint migrates a fresh SQLite file on the volume that holds the PostgreSQL instance's media, and the db container is left as an orphan.
    3. The instance now looks empty to its owner. On an empty instance the sign-up form is open and the first account becomes superuser (accounts/signals.py:47-61), in a container that shares the media volume and the .env secrets.
  • Why it matters: following the project's own instructions either leaves buttons that do nothing or takes a PostgreSQL instance offline behind an empty one that a stranger could claim.
  • Fix: add a worker service to compose.postgres.yml matching the SQLite one (profile worker, POSTULO_SKIP_MIGRATE and POSTULO_SKIP_PLUGIN_SYNC, the heartbeat healthcheck, depends_on both db and postulo healthy). Replace the scheduler-only test with one that holds the two files' sets of Postulo services equal. Make .env.example and Configuration give both commands (or "the compose file you started with"), and replace the "no background worker" paragraph in Installing Postulo with how to run manage.py work without Docker. Related to #219 (closed), which fixed the same gap for the scheduler.

Done when

  • A test in tests/test_image_build.py loads both compose files and asserts that the services other than db are the same set, and that each worker runs manage.py work with POSTULO_SKIP_MIGRATE: "1"; it fails today on the missing worker.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, comparing the two compose files and the instructions for background work. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The wiki has moved to `9aefad9b6`, where the `Configuration.md` passage is now at `:407-415`. `docker/compose.yml` gained a `worker` service for `POSTULO_BACKGROUND_WORK` (#247); `docker/compose.postgres.yml` did not, which is the same drift #219 found for the scheduler. Both `.env.example` and the wiki tell every operator to start the worker with `docker compose -f docker/compose.yml --profile worker up -d`, naming only the SQLite file. Both files declare `name: postulo`, a service called `postulo` and the volume `postulo-data`, so on a PostgreSQL install that command replaces the running web container with one pointed at a new, empty SQLite database. - **Where:** `docker/compose.postgres.yml:15-102` (services `postulo`, `scheduler`, `db` only); `docker/compose.yml:88-123` (the `worker`); `.env.example:125-126`; the wiki's `Configuration.md:405-413`; `Installing-Postulo.md:236` ("There is no background worker to run. Nothing in Postulo currently queues work."); `tests/test_image_build.py:184`, which checks only that the PostgreSQL file has a scheduler. - **What happens:** 1. A PostgreSQL operator sets `POSTULO_BACKGROUND_WORK=true` as instructed. Their compose file has no worker, so every capture, logo, PDF and export queues work that nobody runs. 2. If they run the documented command instead, Compose sees a changed `postulo` service in the same project and recreates it with `POSTULO_DATABASE_URL: sqlite:////app/data/postulo.sqlite3`. The entrypoint migrates a fresh SQLite file on the volume that holds the PostgreSQL instance's media, and the `db` container is left as an orphan. 3. The instance now looks empty to its owner. On an empty instance the sign-up form is open and the first account becomes superuser (`accounts/signals.py:47-61`), in a container that shares the media volume and the `.env` secrets. - **Why it matters:** following the project's own instructions either leaves buttons that do nothing or takes a PostgreSQL instance offline behind an empty one that a stranger could claim. - **Fix:** add a `worker` service to `compose.postgres.yml` matching the SQLite one (profile `worker`, `POSTULO_SKIP_MIGRATE` and `POSTULO_SKIP_PLUGIN_SYNC`, the heartbeat healthcheck, `depends_on` both `db` and `postulo` healthy). Replace the scheduler-only test with one that holds the two files' sets of Postulo services equal. Make `.env.example` and *Configuration* give both commands (or "the compose file you started with"), and replace the "no background worker" paragraph in *Installing Postulo* with how to run `manage.py work` without Docker. Related to #219 (closed), which fixed the same gap for the scheduler. ## Done when - A test in `tests/test_image_build.py` loads both compose files and asserts that the services other than `db` are the same set, and that each `worker` runs `manage.py work` with `POSTULO_SKIP_MIGRATE: "1"`; it fails today on the missing `worker`.
tiagoagueda added this to the 0.5.0 milestone 2026-10-01 10:47:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#581
No description provided.