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

Closed
opened 2026-09-29 11:07:47 +02:00 by clawbot · 2 comments
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. Most of this is already on next: entrypoint.sh starts as root, takes ownership of /var/lib/berlin.sneak.app.routewatch (chown -R, chmod 700) and then replaces itself with the daemon as the routewatch user through setpriv, so data owned by another uid is already taken over. What is missing:

  • entrypoint.sh creates the directory if it is missing (mkdir -p) and stops the start if any of these steps fails. Today it has no set -e, so a failed cd would go on to change the ownership of whatever directory the script happens to be in.
  • A recorded run on the image from make docker, with the directory bind-mounted the way upaas mounts it: an empty root-owned directory, and a directory already holding data owned by another uid. Each ends healthy, with the daemon running as the routewatch user and the database written; a second start on the same directory works too.
  • README.md, "Running under upaas": the volume line says only which container path to mount. The sentences telling the operator to create the host directory before the first deploy, and that a root-owned directory works, go. TODO.md gains its Completed Steps line.
  • The data path and the uid stay as they are.

The milestone PR description no longer tells the operator to create the directory.

Model: opus-5-5

Plan. Most of this is already on `next`: `entrypoint.sh` starts as root, takes ownership of `/var/lib/berlin.sneak.app.routewatch` (`chown -R`, `chmod 700`) and then replaces itself with the daemon as the `routewatch` user through `setpriv`, so data owned by another uid is already taken over. What is missing: - `entrypoint.sh` creates the directory if it is missing (`mkdir -p`) and stops the start if any of these steps fails. Today it has no `set -e`, so a failed `cd` would go on to change the ownership of whatever directory the script happens to be in. - A recorded run on the image from `make docker`, with the directory bind-mounted the way upaas mounts it: an empty root-owned directory, and a directory already holding data owned by another uid. Each ends `healthy`, with the daemon running as the `routewatch` user and the database written; a second start on the same directory works too. - `README.md`, "Running under upaas": the volume line says only which container path to mount. The sentences telling the operator to create the host directory before the first deploy, and that a root-owned directory works, go. `TODO.md` gains its Completed Steps line. - The data path and the uid stay as they are. The milestone PR description no longer tells the operator to create the directory. Model: opus-5-5
Author
Collaborator

PR: #44

Model: opus-5-5

PR: https://git.eeqj.de/sneak/routewatch/pulls/44 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/routewatch#42