Conversation
Upgrading the standalone image from v9.3.2 to v9.3.3 with an existing Postgres volume puts the container in a restart loop: Error: Config owner (postgres:102) and data owner (rabbitmq:103) do not match, and config owner is not root The service accounts get their UIDs allocated by the package installs, in package-configuration order, so the package set decides them. Adding --no-install-recommends in v9.3.3 dropped dbus (`messagebus`) from that layer and everything after it slid down one: v9.3.2: messagebus 101 redis 102 postgres 103 rabbitmq 104 ds 105 v9.3.3: redis 101 postgres 102 rabbitmq 103 messagebus 104 ds 105 A datadir written by v9.3.2 is therefore owned by a UID that resolves to `rabbitmq` in v9.3.3, postgresql-common refuses to start on the mismatch, and the entrypoint dies under `set -e` before nginx. `ds` kept 105 only because messagebus moved from ahead of postgres to behind it, so the document volume escaped by coincidence, not by design. Three parts: - entrypoint.sh chowns the state directories it owns when, and only when, the current owner differs, before starting anything. This is what rescues volumes that already exist, and it also covers a bind mount arriving owned by something else. $DATA_DIR/.private stays root-owned, since the recursive chown would otherwise hand the persisted secrets to ds. - The Dockerfile pins the UIDs/GIDs ahead of the installs, so a future packaging change cannot renumber them again. The pinned values are the ones v9.3.3 already shipped, which makes this a no-op for volumes written by v9.3.3 or later; adduser/useradd in the package postinsts (and the .deb's own, for `ds`) are no-ops when the account exists. - A new build.yml job boots the last released image against persistent volumes and then boots the image built here on the same volumes, asserting a row seeded before the upgrade is still readable after it. The e2e job only ever sees empty volumes, which is why this shipped green. Skipped on tag pushes, where :latest is already the image under test. Fixes #314 Assisted-by: ClaudeCode:claude-opus-5 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Christoph Schaefer <christoph.schaefer@nextcloud.com>
|
Confirming from the reporter side of #335: my setup bind-mounts /var/lib/euro-office/documentserver in addition to $DATA_DIR (host: ~/eurooffice/data:/var/lib/euro-office/documentserver), and on 9.3.4 Build 37 every upload failed with receiveTask Error: EACCES: permission denied, mkdir '/var/lib/euro-office/documentserver/App_Data' until I ran chown -R ds:ds on that path inside the running container. |
The converter creates App_Data under /var/lib/euro-office/documentserver, and that path is commonly mounted alongside $DATA_DIR. A bind mount there arrives owned by whatever the host created it with, so every upload fails with EACCES on mkdir App_Data until it is chowned to ds by hand (#335). Add it to the ds ensure_owner list as $EO_LIB. The upgrade job now mounts it as a third volume, hands both ds volumes to a foreign owner before booting the built image, and asserts they come back owned by ds. Assisted-by: ClaudeCode:claude-opus-5 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Christoph Schaefer <christoph.schaefer@nextcloud.com>
|
Thanks @junkerderprovinz and @eelcowijbrands, |
|
Happy to test the branch against my two-bind-mount setup, but docker pull ghcr.io/euro-office/documentserver:pr-333 returns not found — so the PR image doesn't appear to be published publicly. I've backed up and torn down my previous :latest container, so I'm ready to go as soon as there's an image to pull. Is there a public tag or artifact for this branch, or would you prefer I wait for the next :nightly after merge? (For reference: my setup is ~/eurooffice/data:/var/lib/euro-office/documentserver + ~/eurooffice/private:/var/www/euro-office/Data, both currently fresh and owned by my host user, i.e. the exact #335 reproduction case.) |
Upgrading the standalone image from v9.3.2 to v9.3.3 with an existing Postgres volume puts the container in a restart loop:
Error: Config owner (postgres:102) and data owner (rabbitmq:103) do not
match, and config owner is not root
The service accounts get their UIDs allocated by the package installs, in package-configuration order, so the package set decides them. Adding --no-install-recommends in v9.3.3 dropped dbus (
messagebus) from that layer and everything after it slid down one:v9.3.2: messagebus 101 redis 102 postgres 103 rabbitmq 104 ds 105
v9.3.3: redis 101 postgres 102 rabbitmq 103 messagebus 104 ds 105
A datadir written by v9.3.2 is therefore owned by a UID that resolves to
rabbitmqin v9.3.3, postgresql-common refuses to start on the mismatch, and the entrypoint dies underset -ebefore nginx.dskept 105 only because messagebus moved from ahead of postgres to behind it, so the document volume escaped by coincidence, not by design.Three parts:
entrypoint.sh chowns the state directories it owns when, and only when, the current owner differs, before starting anything. This is what rescues volumes that already exist, and it also covers a bind mount arriving owned by something else. $DATA_DIR/.private stays root-owned, since the recursive chown would otherwise hand the persisted secrets to ds.
The Dockerfile pins the UIDs/GIDs ahead of the installs, so a future packaging change cannot renumber them again. The pinned values are the ones v9.3.3 already shipped, which makes this a no-op for volumes written by v9.3.3 or later; adduser/useradd in the package postinsts (and the .deb's own, for
ds) are no-ops when the account exists.A new build.yml job boots the last released image against persistent volumes and then boots the image built here on the same volumes, asserting a row seeded before the upgrade is still readable after it. The e2e job only ever sees empty volumes, which is why this shipped green. Skipped on tag pushes, where :latest is already the image under test.
Fixes #314
Assisted-by: ClaudeCode:claude-opus-5