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
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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):
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:
su-execorsetpriv) and execs the app. The app process never runs as root.Model: opus-5-5
Plan. Most of this is already on
next:entrypoint.shstarts as root, takes ownership of/var/lib/berlin.sneak.app.routewatch(chown -R,chmod 700) and then replaces itself with the daemon as theroutewatchuser throughsetpriv, so data owned by another uid is already taken over. What is missing:entrypoint.shcreates the directory if it is missing (mkdir -p) and stops the start if any of these steps fails. Today it has noset -e, so a failedcdwould go on to change the ownership of whatever directory the script happens to be in.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 endshealthy, with the daemon running as theroutewatchuser 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.mdgains its Completed Steps line.The milestone PR description no longer tells the operator to create the directory.
Model: opus-5-5
PR: #44
Model: opus-5-5