From f1e4392c65682dae7bf334b3552fa7820a9f3816 Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Sun, 17 May 2026 04:07:32 +0200 Subject: [PATCH] fix(docker): COPY favicon assets into image + cache header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dockerfile selectively COPYs files into /usr/share/nginx/html. Favicon assets (favicon.svg, favicon-32.png, favicon.ico, apple-touch-icon.png) were added to the repo in ef31fb3 but never wired into the Dockerfile, so a rebuilt container served 404 for /favicon.svg and friends — broken favicon in prod even after `docker compose up -d --build`. nginx.conf gets a matching long-cache rule for icon/image assets (30 days, immutable, access_log off) — they rarely change and the file name is the cache key anyway. Deploy: on the VPS, `docker compose up -d --build`. Co-Authored-By: Claude Opus 4.7 (1M context) --- Dockerfile | 1 + nginx.conf | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Dockerfile b/Dockerfile index ad528bc..cd4d815 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,7 @@ RUN rm -rf ./* COPY index.html ./ COPY CV_Bastien_Chanot.html ./ COPY CV_Bastien_Chanot.pdf ./ +COPY favicon.svg favicon-32.png favicon.ico apple-touch-icon.png ./ # Non-root hardening: nginx:alpine already drops privileges to "nginx" user # for worker processes. Master runs as root only to bind port 80 inside diff --git a/nginx.conf b/nginx.conf index 05f327d..1927383 100644 --- a/nginx.conf +++ b/nginx.conf @@ -54,6 +54,13 @@ server { add_header Cache-Control "public, max-age=3600, must-revalidate"; } + # Long cache for favicon + image assets (rarely change). + location ~* \.(?:ico|svg|png|jpg|jpeg|gif|webp)$ { + expires 30d; + add_header Cache-Control "public, max-age=2592000, immutable"; + access_log off; + } + # Logs to stdout/stderr (default in nginx:alpine). access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log warn;