nginx: listen on PORT, default 8080; server_tokens off (closes #26) #65

Merged
clawbot merged 1 commits from fix/nginx-port-env into next 2026-09-29 04:55:49 +02:00
5 changed files with 40 additions and 5 deletions
+4 -1
View File
@@ -68,8 +68,10 @@ FROM nginx@sha256:15e96e59aa3b0aada3a121296e3bce117721f42d88f5f64217ef4b18f458c6
RUN addgroup -g 1000 -S netwatch && \ RUN addgroup -g 1000 -S netwatch && \
adduser -u 1000 -S netwatch -G netwatch adduser -u 1000 -S netwatch -G netwatch
# At start-up the nginx image renders every template here into
# conf.d; bin/entrypoint.sh says how.
RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/netwatch.conf COPY nginx.conf /etc/nginx/templates/netwatch.conf.template
COPY --from=frontend /app/dist /usr/share/nginx/html COPY --from=frontend /app/dist /usr/share/nginx/html
COPY --from=builder /src/netwatch-server /usr/local/bin/netwatch-server COPY --from=builder /src/netwatch-server /usr/local/bin/netwatch-server
COPY bin/entrypoint.sh /usr/local/bin/entrypoint.sh COPY bin/entrypoint.sh /usr/local/bin/entrypoint.sh
@@ -78,6 +80,7 @@ ENV DATA_DIR=/data/reports
RUN mkdir -p /data/reports && chown -R netwatch:netwatch /data RUN mkdir -p /data/reports && chown -R netwatch:netwatch /data
VOLUME /data VOLUME /data
# The default public port; PORT changes it.
EXPOSE 8080 EXPOSE 8080
# The nginx image stops its container with SIGQUIT; the entrypoint # The nginx image stops its container with SIGQUIT; the entrypoint
+6
View File
@@ -23,6 +23,12 @@ latest run passes.
# Completed Steps # Completed Steps
- 2026-09-29: nginx listens on `PORT` (issue #26), 8080 when unset or empty: the
nginx image renders `nginx.conf` as a template at container start, filling in
`PORT` and no other variable. `bin/entrypoint.sh` refuses to start when `PORT`
is not digits only. `server_tokens off` keeps the nginx version out of
responses. `script/frontend-viewport-test` renders the template the same way.
Gzip and a `50x.html` error page are not added
- 2026-09-29: bounded the report endpoint (issue #20): `POST /api/v1/reports` - 2026-09-29: bounded the report endpoint (issue #20): `POST /api/v1/reports`
still needs no credentials, but each client address, as resolved through still needs no credentials, but each client address, as resolved through
`TRUSTED_PROXIES`, may send `REPORTS_PER_MINUTE` (default 60) reports a `TRUSTED_PROXIES`, may send `REPORTS_PER_MINUTE` (default 60) reports a
+18 -1
View File
@@ -8,6 +8,18 @@
# No set -e: kill and wait return non-zero here in normal operation. # No set -e: kill and wait return non-zero here in normal operation.
set -u set -u
# PORT is the public port nginx listens on, 8080 when unset or empty.
# nginx would take a value such as localhost or unix:/tmp/x.sock as an
# address and start anyway, so anything but digits stops the container
# here, before either process starts.
export PORT="${PORT:-8080}"
case "$PORT" in
*[!0-9]*)
echo "entrypoint: PORT must be a port number, not '$PORT'" >&2
exit 1
;;
esac
# A stop signal is only noted here; the loop below acts on it. # A stop signal is only noted here; the loop below acts on it.
stop_requested="" stop_requested=""
trap 'stop_requested=yes' TERM INT trap 'stop_requested=yes' TERM INT
@@ -23,7 +35,12 @@ backend=$!
# nginx starts through the nginx image's own entrypoint, which applies # nginx starts through the nginx image's own entrypoint, which applies
# the image's start-up configuration and then replaces itself with # the image's start-up configuration and then replaces itself with
# nginx. # nginx. Part of that start-up configuration renders nginx.conf into
# conf.d with nginx listening on PORT. NGINX_ENVSUBST_FILTER limits
# that rendering to PORT: a variable nginx itself uses, such as $uri,
# would otherwise be replaced by an environment variable of the same
# name.
NGINX_ENVSUBST_FILTER='^PORT$' \
/docker-entrypoint.sh nginx -g 'daemon off;' & /docker-entrypoint.sh nginx -g 'daemon off;' &
nginx=$! nginx=$!
+7 -1
View File
@@ -1,7 +1,13 @@
# A template: the nginx image renders it into conf.d at container start,
# filling in PORT and nothing else. bin/entrypoint.sh sets PORT and that
# limit.
server { server {
listen 8080; listen ${PORT};
server_name _; server_name _;
# Keep the nginx version out of the Server header and error pages.
server_tokens off;
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html; index index.html;
+4 -1
View File
@@ -61,10 +61,13 @@ main() {
# host. # host.
docker network create --internal "$NETWORK" > /dev/null docker network create --internal "$NETWORK" > /dev/null
# nginx.conf is a template: the image renders it over its own
# default.conf, with the same port and limit bin/entrypoint.sh uses.
docker run -d --rm --name "$SERVER" \ docker run -d --rm --name "$SERVER" \
--network "$NETWORK" --network-alias netwatch \ --network "$NETWORK" --network-alias netwatch \
-e PORT=8080 -e NGINX_ENVSUBST_FILTER='^PORT$' \
-v "$ROOT/dist:/usr/share/nginx/html:ro" \ -v "$ROOT/dist:/usr/share/nginx/html:ro" \
-v "$ROOT/nginx.conf:/etc/nginx/conf.d/default.conf:ro" \ -v "$ROOT/nginx.conf:/etc/nginx/templates/default.conf.template:ro" \
"$SERVER_IMAGE" > /dev/null "$SERVER_IMAGE" > /dev/null
# The image's own entrypoint already exposes CDP on 9222 and passes # The image's own entrypoint already exposes CDP on 9222 and passes