Installing Postulo: a plugin baked in with the build argument is lost by either documented upgrade #584

Closed
opened 2026-10-01 10:47:50 +00:00 by tiagoagueda · 1 comment
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d and postulo.wiki at de1f52467, following the wiki's install and upgrade recipes against docker/compose.yml and docker/Dockerfile.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The wiki has moved to 9aefad9b6; the two pages named here are unchanged.

The wiki offers baking a plugin into the image with POSTULO_EXTRA_PACKAGES and says the plugin "survives upgrades because it is part of the image you build". Both upgrade recipes on the same page throw it away: one rebuilds without the build argument, the other pulls the published image over the locally built one. A plugin installed this way is not in the volume's plugin record, so the entrypoint's plugins sync does not bring it back.

  • Where: wiki Installing-Postulo.md:118-125 (the build argument on the command line) and :147-149 (the promise); Installing-Postulo.md:309-313 (Upgrading → With Docker: build --pull with only POSTULO_APT_REFRESH); Installing-Postulo.md:346-355 (Releases and upgrading: docker compose … pull, and up -d --build); wiki Writing-a-plugin.md:1521-1525 repeats the build-argument recipe; docker/compose.yml:23-29 gives the postulo service both build: and image: source.tiagoagueda.com/postulo/postulo:0.2; docker/Dockerfile:119-128 installs the packages only when the argument is set; docker/entrypoint.sh:18-20 restores only what the record lists.
  • What happens:
    1. An operator follows the first recipe: docker compose -f docker/compose.yml build --build-arg POSTULO_EXTRA_PACKAGES="git+…/postulo-apprise.git". The result is tagged source.tiagoagueda.com/postulo/postulo:0.2, the name in image:.
    2. Later they upgrade as Upgrading → With Docker says. That build --pull passes no POSTULO_EXTRA_PACKAGES, so the new image has no apprise package. Or they upgrade as Releases and upgrading says: docker compose pull fetches the published :0.2 and replaces the local tag of the same name.
    3. The new container starts, plugins sync finds nothing to restore (the build-time install was never recorded), and the scheduler's notification pass logs "Connection … uses 'apprise', which is not installed" (notifications/service.py:63-67) and skips the connection. Notifications stop; the reason is only in the log.
      The compose-file variant (build.args) survives a rebuild, but it is a local edit to a tracked file that the recipe's own git pull may refuse to merge over, and it does not survive docker compose pull either.
  • Why it matters: the page tells an operator this path is the durable one, and the upgrade it documents next quietly removes the plugin.
  • Fix: in the baked-plugin recipe, use a Compose override file (docker/compose.override.yml or similar, untracked) that keeps POSTULO_EXTRA_PACKAGES in build.args and gives the image a local name (for example image: postulo-local:0.2), so docker compose pull never replaces it; drop the command-line form or say it must be repeated at every rebuild. In both upgrade sections, say that an instance with a baked image upgrades by rebuilding with its override (build --pull with the same arguments) and never by pull. Change "it survives upgrades" to say under which recipe it does. Make the same correction in Writing-a-plugin.md.

Done when

  • Installing-Postulo.md and Writing-a-plugin.md give one baked-plugin recipe whose image keeps its plugins through the upgrade steps the same page gives, and both upgrade sections name the exception.
Found on 2026-09-29 in a read-only review of postulo at 95348908d and postulo.wiki at de1f52467, following the wiki's install and upgrade recipes against `docker/compose.yml` and `docker/Dockerfile`. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The wiki has moved to `9aefad9b6`; the two pages named here are unchanged. The wiki offers baking a plugin into the image with `POSTULO_EXTRA_PACKAGES` and says the plugin "survives upgrades because it is part of the image you build". Both upgrade recipes on the same page throw it away: one rebuilds without the build argument, the other pulls the published image over the locally built one. A plugin installed this way is not in the volume's plugin record, so the entrypoint's `plugins sync` does not bring it back. - **Where:** wiki `Installing-Postulo.md:118-125` (the build argument on the command line) and `:147-149` (the promise); `Installing-Postulo.md:309-313` (*Upgrading → With Docker*: `build --pull` with only `POSTULO_APT_REFRESH`); `Installing-Postulo.md:346-355` (*Releases and upgrading*: `docker compose … pull`, and `up -d --build`); wiki `Writing-a-plugin.md:1521-1525` repeats the build-argument recipe; `docker/compose.yml:23-29` gives the `postulo` service both `build:` and `image: source.tiagoagueda.com/postulo/postulo:0.2`; `docker/Dockerfile:119-128` installs the packages only when the argument is set; `docker/entrypoint.sh:18-20` restores only what the record lists. - **What happens:** 1. An operator follows the first recipe: `docker compose -f docker/compose.yml build --build-arg POSTULO_EXTRA_PACKAGES="git+…/postulo-apprise.git"`. The result is tagged `source.tiagoagueda.com/postulo/postulo:0.2`, the name in `image:`. 2. Later they upgrade as *Upgrading → With Docker* says. That `build --pull` passes no `POSTULO_EXTRA_PACKAGES`, so the new image has no apprise package. Or they upgrade as *Releases and upgrading* says: `docker compose pull` fetches the published `:0.2` and replaces the local tag of the same name. 3. The new container starts, `plugins sync` finds nothing to restore (the build-time install was never recorded), and the scheduler's notification pass logs "Connection … uses 'apprise', which is not installed" (`notifications/service.py:63-67`) and skips the connection. Notifications stop; the reason is only in the log. The compose-file variant (`build.args`) survives a rebuild, but it is a local edit to a tracked file that the recipe's own `git pull` may refuse to merge over, and it does not survive `docker compose pull` either. - **Why it matters:** the page tells an operator this path is the durable one, and the upgrade it documents next quietly removes the plugin. - **Fix:** in the baked-plugin recipe, use a Compose override file (`docker/compose.override.yml` or similar, untracked) that keeps `POSTULO_EXTRA_PACKAGES` in `build.args` and gives the image a local name (for example `image: postulo-local:0.2`), so `docker compose pull` never replaces it; drop the command-line form or say it must be repeated at every rebuild. In both upgrade sections, say that an instance with a baked image upgrades by rebuilding with its override (`build --pull` with the same arguments) and never by `pull`. Change "it survives upgrades" to say under which recipe it does. Make the same correction in `Writing-a-plugin.md`. ## Done when - `Installing-Postulo.md` and `Writing-a-plugin.md` give one baked-plugin recipe whose image keeps its plugins through the upgrade steps the same page gives, and both upgrade sections name the exception.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:47:50 +00:00
Author
Owner

Corrected in the wiki (postulo.wiki ee6e8bd).

Corrected in the wiki (postulo.wiki ee6e8bd).
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#584
No description provided.