From d2bac6b8d39ffa25d9403f575247963c51a58006 Mon Sep 17 00:00:00 2001 From: Emma Thorpe Date: Thu, 11 Jun 2026 16:07:10 +0100 Subject: [PATCH] feat: containerise the site with nginx-unprivileged Serve the static site from a non-root nginx image listening on 8080, with cache headers, gzip and a /healthz endpoint. Designed to run behind an external reverse proxy that terminates TLS. Co-Authored-By: Claude Opus 4.8 (1M context) --- .dockerignore | 12 ++++++++++++ Dockerfile | 9 +++++++++ default.conf | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 default.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3a88f48 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +# Keep the build context minimal; only the site assets and nginx config +# referenced by the Dockerfile are needed. +.git +.gitea +.github +.idea +.vscode +*.md +renovate.json +.renovaterc* +Dockerfile +.dockerignore diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7525657 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +# Lightweight, non-root nginx serving the static site. +# Runs as user "nginx" and listens on 8080, ready to sit behind an +# external reverse proxy that terminates TLS and forwards requests. +FROM nginxinc/nginx-unprivileged:1.27-alpine-slim + +COPY default.conf /etc/nginx/conf.d/default.conf +COPY --chown=nginx:nginx index.html styles.css script.js messages.js /usr/share/nginx/html/ + +EXPOSE 8080 diff --git a/default.conf b/default.conf new file mode 100644 index 0000000..449930a --- /dev/null +++ b/default.conf @@ -0,0 +1,42 @@ +# Static file serving for "Why is the DLR shut today?". +# Intended to run behind an external reverse proxy (e.g. NGINX) which +# handles TLS, host routing and any X-Forwarded-* headers. + +server { + listen 8080; + listen [::]:8080; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + gzip on; + gzip_vary on; + gzip_types text/css application/javascript; + + location / { + try_files $uri $uri/ =404; + } + + # HTML should always be revalidated so deploys are picked up promptly. + location = /index.html { + add_header Cache-Control "no-cache"; + } + + # The message list is edited frequently; do not cache it. + location = /messages.js { + add_header Cache-Control "no-cache"; + } + + # Other static assets may be cached for a short period. + location ~* \.(?:css|js)$ { + add_header Cache-Control "public, max-age=3600"; + } + + # Health endpoint for the proxy / orchestrator. + location = /healthz { + access_log off; + default_type text/plain; + return 200 "ok\n"; + } +}