From 708ed9c57f7755f446c88a6215dbed8f477c4346 Mon Sep 17 00:00:00 2001 From: Oliver Rieger Date: Tue, 4 Aug 2026 14:20:08 +0200 Subject: [PATCH] Serve the same court twice, so staging can be tried before the crowd arrives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The image now answers at /staging/ as well as /, via an alias to the same root — that way the staging deploy works whether or not Coolify strips the path prefix, and the staging branch needs no diff of its own to merge. The manifest MIME moved from an exact-match location into the stock types map: an exact match would have missed the /staging/ copy, and a regex location would have out-ranked the prefix and resolved against root. Co-Authored-By: Claude Opus 5 --- Dockerfile | 13 +++++++++---- HANDOFF.md | 5 +++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index dff3b79..18f85a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,14 @@ FROM nginx:alpine # no-cache => browsers revalidate every request (ETag 304s are cheap), so a new # deploy is picked up on plain reload. ponytail: switch to hashed filenames if traffic ever matters. -# The exact-match location gives the manifest its own MIME type — nginx's default map has no -# .webmanifest entry and Chrome refuses to install a homescreen app served as octet-stream. -# (a bare `types {}` block would have REPLACED the whole map and broken .js/.png too.) -RUN printf 'server {\n listen 80;\n root /usr/share/nginx/html;\n etag on;\n location = /manifest.webmanifest { default_type application/manifest+json; add_header Cache-Control "no-cache, must-revalidate"; }\n location / { add_header Cache-Control "no-cache, must-revalidate"; }\n}\n' > /etc/nginx/conf.d/default.conf +# nginx's default map has no .webmanifest entry and Chrome refuses to install a homescreen app +# served as octet-stream, so we append the type to the stock map. It has to be the map and not a +# `location`: an exact match misses the /staging/ copy below, and a regex match would out-rank the +# /staging/ prefix and resolve against root instead of the alias. A local `types {}` block is out +# too — it REPLACES the whole map (breaking .js/.png), and mime.types can't be re-included inside one. +RUN sed -i 's#^}# application/manifest+json webmanifest;\n}#' /etc/nginx/mime.types +# The /staging/ alias serves the SAME files one level down, so the staging deploy works whether or +# not Coolify/Traefik strips the path prefix. Identical on every branch => never a merge conflict. +RUN printf 'server {\n listen 80;\n root /usr/share/nginx/html;\n etag on;\n index index.html;\n absolute_redirect off;\n location = /staging { return 301 /staging/; }\n location /staging/ { alias /usr/share/nginx/html/; add_header Cache-Control "no-cache, must-revalidate"; }\n location / { add_header Cache-Control "no-cache, must-revalidate"; }\n}\n' > /etc/nginx/conf.d/default.conf COPY index.html manifest.webmanifest *.js /usr/share/nginx/html/ COPY assets /usr/share/nginx/html/assets diff --git a/HANDOFF.md b/HANDOFF.md index ce9824b..e92043f 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -23,6 +23,11 @@ the primary target. a push. **Bump `main.js?v=N` in index.html every time** or phones keep the old build. The Dockerfile must also COPY any new top-level file (it currently ships `index.html`, `manifest.webmanifest`, `*.js`, `assets/`). +- **Staging**: the `staging` branch deploys to splatter-tennis.wuwi.one/staging (own Coolify + resource, same repo, branch `staging`). Test there first, then merge to `main` for the testteam. + The branch carries NO diff against main — the image serves the app at both `/` and `/staging/`, + so it can be fast-forwarded and merged freely. Note it shares the origin (and therefore + localStorage) with prod. - **Oliver edits files himself** (tuning values, sometimes sprites). ALWAYS Read current file state before editing; never assume your last version is what is on disk.