From daf5949392c327b07f06e6885a64b54c8979a9c3 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Fri, 25 Sep 2026 18:32:44 +0100 Subject: [PATCH] contrib: gate QUIC reuseport on production + Org only reuseport is legal only once per addr:port (443/udp). preprod and prod share the same IP today, so enabling it on preprod-Org clashed with prod-Org and made nginx refuse the config. QUIC_OPTS now resolves to " reuseport" only when APP_INSTALL_ENV=production AND the host is Org; preprod and the Api/Blogs vhosts get a plain `listen 443 quic;`. Also drop the stray space before `;` when QUIC_OPTS is empty by moving the separator into the QUIC_OPTS value (`listen 443 quic$QUIC_OPTS;`). Co-Authored-By: Claude Code --- contrib/Makefile | 7 ++++++- contrib/template.vhost | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/contrib/Makefile b/contrib/Makefile index f16973af1..deb55bcc6 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -66,13 +66,18 @@ nginx_subdomain = $(if $(filter Org,$1),yavsc,$(if $(filter Api,$1),api,$(if $(f # preprod Org -> preprod-yavsc.pschneider.fr nginx_domain = $(APP_INSTALL_PREFIX)$(call nginx_subdomain,$1).$(DOMAIN_ROOT) +# QUIC_OPTS : "reuseport" n'est légal qu'une seule fois par addr:port +# (443/udp). preprod et prod partagent aujourd'hui la même IP, donc on ne +# l'active qu'en production, sur Org uniquement. En preprod, QUIC_OPTS est +# vide sur tous les vhosts (sinon nginx refuse la config : duplicate +# reuseport sur le même socket 443/udp entre preprod-Org et prod-Org). $(NGINX_OUT_DIR)/$(APP_INSTALL_PREFIX)yavsc%: $(NGINX_OUT_DIR) $(NGINX_TEMPLATE) .$(APP_INSTALL_ENV).env @cat $(NGINX_TEMPLATE) \ | DOMAIN="$(call nginx_domain,$*)" \ BACKEND_SCHEME="$(BACKEND_SCHEME)" \ HTTP_HOST="$(HTTP_HOST)" \ BACKEND_PORT="$($*_PORT)" \ - QUIC_OPTS="$(if $(filter Org,$*),reuseport,)" \ + QUIC_OPTS="$(if $(filter production,$(APP_INSTALL_ENV)),$(if $(filter Org,$*), reuseport,),)" \ envsubst '$$DOMAIN $$BACKEND_SCHEME $$HTTP_HOST $$BACKEND_PORT $$QUIC_OPTS' > $@ @echo Created nginx vhost: $@ diff --git a/contrib/template.vhost b/contrib/template.vhost index 1e9bbdb7e..ea2c2cb6d 100644 --- a/contrib/template.vhost +++ b/contrib/template.vhost @@ -8,8 +8,10 @@ # # Variables substituées par envsubst (allowlist) : # DOMAIN BACKEND_SCHEME HTTP_HOST BACKEND_PORT QUIC_OPTS -# $QUIC_OPTS = "reuseport" sur un seul vhost (Org), vide sur les autres -# (règle : reuseport une seule fois par addr:port, cf. contrib/quic.md). +# $QUIC_OPTS = "reuseport" sur un seul vhost (Org) ET en production +# uniquement ; vide en preprod et sur les autres hôtes. Règle : reuseport +# une seule fois par addr:port (443/udp) — or preprod et prod partagent la +# même IP, donc seule la prod (Org) l'active. # Les variables nginx intrinsèques ($host, $scheme, $remote_addr, …) sont # préservées (hors allowlist). @@ -29,8 +31,8 @@ server { http2 on; # 2. UDP : HTTP/3 (QUIC). reuseport sur UN seul vhost (Org via QUIC_OPTS). - listen 443 quic $QUIC_OPTS; - listen [::]:443 quic $QUIC_OPTS; + listen 443 quic$QUIC_OPTS; + listen [::]:443 quic$QUIC_OPTS; http3 on; server_name $DOMAIN;