diff --git a/Dockerfile b/Dockerfile index 417fc97..d13e53e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,8 +77,9 @@ COPY --from=frontend /app/dist /usr/share/nginx/html COPY --from=builder /src/netwatch-server /usr/local/bin/netwatch-server COPY bin/entrypoint.sh /usr/local/bin/entrypoint.sh +# bin/entrypoint.sh creates DATA_DIR at start and gives it and /data to +# the netwatch user, whatever is mounted there. ENV DATA_DIR=/data/reports -RUN mkdir -p /data/reports && chown -R netwatch:netwatch /data VOLUME /data # The default public port; PORT changes it. diff --git a/README.md b/README.md index 415457e..c42f007 100644 --- a/README.md +++ b/README.md @@ -191,8 +191,9 @@ only inside the container, on `127.0.0.1:8081`. The image: - Sends the security headers `REPO_POLICIES.md` requires on every response, as `security-headers.conf` sets them, in place of the backend's own - Stores reports in `DATA_DIR`, `/data/reports` by default, on the `/data` - volume. The backend runs as user `netwatch` (uid 1000), so a directory - bind-mounted at `/data` must be writable by uid 1000 + volume. Before the backend starts, the image creates `DATA_DIR` and gives it + and `/data` to user `netwatch` (uid 1000), which the backend runs as, so a + host directory bind-mounted at `/data` ends up owned by uid 1000 - Writes buffered reports to disk on `docker stop`, and exits non-zero if nginx or the backend exits on its own, so the platform restarts it @@ -202,16 +203,6 @@ What the [upaas](https://git.eeqj.de/sneak/upaas) app for netwatch needs: - **Port:** container port `8080`. - **Volume:** container path `/data`; the reports are kept in `/data/reports`. -- **First run:** upaas bind-mounts the host directory it is given and does not - create it, and the backend, which runs as uid 1000, does not start unless it - can write there. Create the directory, owned by uid 1000, before the first - deploy: - - ```bash - mkdir -p /path/to/data - chown 1000:1000 /path/to/data - ``` - - **Environment variables:** none is required. An empty one counts as unset, and one set to a value netwatch cannot use stops the container at start, with the reason in its log. diff --git a/TODO.md b/TODO.md index 212faab..3eb53de 100644 --- a/TODO.md +++ b/TODO.md @@ -23,6 +23,13 @@ latest run passes. # Completed Steps +- 2026-09-29: the container sets up its own data directory (issue #75): + `bin/entrypoint.sh`, still as root, creates `DATA_DIR` if missing and gives it + and `/data` to the `netwatch` user with mode 750 before starting the backend + as that user, so an empty host directory owned by root, or one holding files + from another uid, works with no step on the host. The `README.md` first-run + step that created and chowned the host directory is gone, and the image no + longer sets that ownership at build time - 2026-09-29: `backend/.golangci.yml` re-vendored from `sneak/prompts` (issue #41): `gomodguard`, deprecated in golangci-lint v2.12.0, is disabled and its successor `gomodguard_v2` enabled with the org block list, so lint runs print diff --git a/backend/README.md b/backend/README.md index ad29c08..9914eb0 100644 --- a/backend/README.md +++ b/backend/README.md @@ -104,7 +104,8 @@ this server. The image's entrypoint, `bin/entrypoint.sh`, starts the server as user `netwatch` (uid 1000) with `BIND_ADDRESS=127.0.0.1` and `PORT=8081`, so only nginx reaches it, and with `TRUSTED_PROXIES=127.0.0.1/32`, so it takes the client address nginx passes on and no other. `DATA_DIR` is `/data/reports`, on -the `/data` volume, which `netwatch` owns. nginx replaces the security headers +the `/data` volume; the entrypoint creates it and gives it and `/data` to +`netwatch` before starting the server. nginx replaces the security headers this server sets with those in the root `security-headers.conf`, so those are what clients of the image see. diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 4458f9e..ebde676 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -61,6 +61,16 @@ for proxy in $(printf '%s' "$TRUSTED_PROXIES" | tr ',' ' '); do echo "set_real_ip_from $cidr;" done > /etc/nginx/trusted-proxies.conf +# netwatch-server keeps its report files in DATA_DIR, on the /data +# volume, which may be a host directory owned by root or by another +# uid. Both are given to the netwatch user here, with the mode the +# server gives a directory it creates, so the host directory needs no +# preparing. +export DATA_DIR="${DATA_DIR:-/data/reports}" +mkdir -p "$DATA_DIR" || exit 1 +chown -R netwatch:netwatch /data "$DATA_DIR" || exit 1 +chmod 750 /data "$DATA_DIR" || exit 1 + # A stop signal is only noted here; the loop below acts on it. stop_requested="" trap 'stop_requested=yes' TERM INT