Skip to content

feat(traefik): add HTTP_PROXY_DISABLE_HTTP2 to force HTTP/1.1 on TLS …#99

Open
lussoluca wants to merge 1 commit into
sparkfabrik:mainfrom
lussoluca:feat/disable-http2
Open

feat(traefik): add HTTP_PROXY_DISABLE_HTTP2 to force HTTP/1.1 on TLS …#99
lussoluca wants to merge 1 commit into
sparkfabrik:mainfrom
lussoluca:feat/disable-http2

Conversation

@lussoluca

Copy link
Copy Markdown

Summary

Adds an opt-in environment variable HTTP_PROXY_DISABLE_HTTP2 on the traefik service. When set to true, the entrypoint writes a dynamic Traefik config that restricts TLS ALPN negotiation to http/1.1, so browsers fall back from HTTP/2 to HTTP/1.1 over TLS.
Default is false — existing setups are unaffected.

Motivation

On macOS with Docker Desktop, long-lived HTTP/2 sessions between the browser and the proxy can become zombies: the host-side TCP socket (terminated by vpnkit) stays alive while the container-side socket has already closed, and no FIN/RST is propagated across the loopback shim. The browser keeps multiplexing new requests into a dead session, and all .loc hosts time out (ERR_TIMED_OUT) until the browser is fully restarted. Command-line clients (curl, wget) are not affected because they open a fresh TCP connection per request.
HTTP/1.1 detects dead connections aggressively at the socket layer (the next write returns EPIPE immediately) and avoids this entire class of bugs, at the cost of losing HTTP/2 multiplexing for local development traffic — usually an acceptable
trade-off for a dev-only proxy.

Implementation

  • build/traefik/entrypoint.sh: new generate_disable_http2_config function. When HTTP_PROXY_DISABLE_HTTP2=true, writes /traefik/dynamic/disable-http2.yml with tls.options.default.alpnProtocols = [http/1.1]. When false (or unset), removes the file if it exists, so toggling the flag off cleans up.
  • compose.yml: surfaces the variable on the traefik service with a safe false default.
  • README.md: new subsection under HTTPS Support explaining when to enable it.

Verification

Smoke-tested the entrypoint locally with a stubbed exec traefik:

  • Flag unset / false → no dynamic file written, no behavior change.
  • Flag truedisable-http2.yml written with expected content.
  • Flag toggled back to false → file removed on next startup.
    End-to-end on a real proxy: with the flag on, browser network panel reports HTTP/1.1 instead of h2 for .loc sites; curl --http2 falls back without errors; openssl s_client -alpn h2,http/1.1 reports the negotiated protocol as http/1.1.

Compatibility

  • No breaking change. Default behavior is preserved (HTTP_PROXY_DISABLE_HTTP2=false).
  • Affects only TLS entrypoints. Plain HTTP traffic (port 80) is untouched.
  • HTTPS keeps working; only the wire protocol version is constrained.

@paolomainardi

Copy link
Copy Markdown
Member

@lussoluca should we make this the default option ?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an opt-in mechanism to force HTTP/1.1 over TLS for the Traefik
frontend, intended as a workaround for stuck/zombie browser HTTP/2 sessions on
macOS Docker Desktop setups.

Changes:

  • Add HTTP_PROXY_DISABLE_HTTP2 env var to the traefik service (default
    false).
  • Extend the Traefik container entrypoint to generate/remove a dynamic config
    that restricts TLS ALPN to http/1.1 when the flag is enabled.
  • Document the new option and rationale in the README under HTTPS Support.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
README.md Documents the new HTTP/2-disable workaround and how to enable it.
compose.yml Exposes HTTP_PROXY_DISABLE_HTTP2 on the Traefik service with a safe default.
build/traefik/entrypoint.sh Generates/removes a dynamic Traefik TLS config to force ALPN to HTTP/1.1.

Comment on lines +98 to +110
generate_disable_http2_config() {
if [ "${HTTP_PROXY_DISABLE_HTTP2:-false}" = "true" ]; then
echo "Disabling HTTP/2 (HTTP_PROXY_DISABLE_HTTP2=true): forcing ALPN to http/1.1"
cat > "${DISABLE_HTTP2_FILE}" << 'EOF'
# Auto-generated by entrypoint.sh when HTTP_PROXY_DISABLE_HTTP2=true.
# Restricts the TLS ALPN list to http/1.1, preventing HTTP/2 negotiation
# on TLS entrypoints.
tls:
options:
default:
alpnProtocols:
- http/1.1
EOF
@lussoluca

Copy link
Copy Markdown
Author

@lussoluca should we make this the default option ?

I don't know if switching to HTTP 1 can have any effect on other stacks. I've tested this only with pkg/drupal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants