The container sets its data directory permissions itself before startup #166

Open
opened 2026-09-29 11:07:47 +02:00 by clawbot · 1 comment
Collaborator

sneak, 2026-09-29 in chat, on the README instruction that the host data directory must be created and chowned to the app's uid before the first deploy (verbatim):

this is wrong. always make sure that the container sets appropriate permissions on the data dir before startup.

A standing rule for every app image: the container itself makes its data directory usable before the app starts. No operator step (mkdir, chown, chmod on the host) is needed or documented.

Definition of done:

  • The image starts correctly with an empty, root-owned host directory bind-mounted as its data directory, on first start and on every later start: an entrypoint running as root creates the directory if needed, sets its owner and mode for the app's user, then drops to that user (for example with su-exec or setpriv) and execs the app. The app process never runs as root.
  • It also works when the directory already holds data owned by another uid (for example from an earlier run under a different uid).
  • A test or a recorded run shows both cases: container healthy, app running as its unprivileged user, data written.
  • README: every instruction to pre-create or chown the host directory is removed; the upaas section says only which path to mount.
  • No change to where data lives or to the app's uid is needed; if one is, say why on this issue first.

Model: opus-5-5

sneak, 2026-09-29 in chat, on the README instruction that the host data directory must be created and chowned to the app's uid before the first deploy (verbatim): > this is wrong. always make sure that the container sets appropriate permissions on the data dir before startup. A standing rule for every app image: the container itself makes its data directory usable before the app starts. No operator step (mkdir, chown, chmod on the host) is needed or documented. Definition of done: - The image starts correctly with an empty, root-owned host directory bind-mounted as its data directory, on first start and on every later start: an entrypoint running as root creates the directory if needed, sets its owner and mode for the app's user, then drops to that user (for example with `su-exec` or `setpriv`) and execs the app. The app process never runs as root. - It also works when the directory already holds data owned by another uid (for example from an earlier run under a different uid). - A test or a recorded run shows both cases: container healthy, app running as its unprivileged user, data written. - README: every instruction to pre-create or chown the host directory is removed; the upaas section says only which path to mount. - No change to where data lives or to the app's uid is needed; if one is, say why on this issue first. Model: opus-5-5
clawbot self-assigned this 2026-09-29 11:07:47 +02:00
Author
Collaborator

Plan, following the pattern pixa already ships (deploy/docker-entrypoint.sh in https://git.eeqj.de/sneak/pixa):

  1. The runtime image drops USER and gets an entrypoint script that runs as root: it creates the data directory if needed (DNSWATCHER_DATA_DIR, default /var/lib/dnswatcher), gives it and everything in it to the dnswatcher user (uid 10001) with mode 700 on the directory, then exec su-exec dnswatcher the binary. The app never runs as root. Ownership is changed recursively because state left by another uid must stay readable; the directory holds one small state file.
  2. su-exec is added to the runtime stage's apk add. Base images stay pinned by sha256.
  3. The startup check that the data directory is writable stays, as a guard.
  4. README: the upaas section and the Docker section say only which path to mount; every instruction to create, chown or chmod a host directory goes.
  5. Recorded run on the final head, two cases: an empty root-owned host directory, and one holding a state file owned by another uid. Each: healthy, app running as uid 10001, state written, restart keeps it. The PR body says so in one line.

No change to where data lives or to the uid.

Model: opus-5-5

Plan, following the pattern pixa already ships (`deploy/docker-entrypoint.sh` in https://git.eeqj.de/sneak/pixa): 1. The runtime image drops `USER` and gets an entrypoint script that runs as root: it creates the data directory if needed (`DNSWATCHER_DATA_DIR`, default `/var/lib/dnswatcher`), gives it and everything in it to the `dnswatcher` user (uid 10001) with mode 700 on the directory, then `exec su-exec dnswatcher` the binary. The app never runs as root. Ownership is changed recursively because state left by another uid must stay readable; the directory holds one small state file. 2. `su-exec` is added to the runtime stage's `apk add`. Base images stay pinned by sha256. 3. The startup check that the data directory is writable stays, as a guard. 4. README: the upaas section and the Docker section say only which path to mount; every instruction to create, chown or chmod a host directory goes. 5. Recorded run on the final head, two cases: an empty root-owned host directory, and one holding a state file owned by another uid. Each: healthy, app running as uid 10001, state written, restart keeps it. The PR body says so in one line. No change to where data lives or to the uid. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/dnswatcher#166