Skip to content

Conversation

@kmhallen
Copy link

@kmhallen kmhallen commented Nov 19, 2025

Add option to nginx_proxy for HTTP/3 (QUIC) support over UDP.

Try it out here with this custom addon repository:
https://github.com/kmhallen/ha-addon-nginx_proxy_quic

HTTP/3 should enable more seamless roaming from WiFi to cellular because the connection ID feature enables a connection to continue when the client IP address changes.

I couldn't find any reliable online HTTP/3 test websites, but browser developer consoles can be used to verify if HTTP/3 is being used. Chromium based browsers seem to be more likely to use HTTP/3 than Firefox. I'm not sure about the Android and iOS companion apps.

The port is specified both in options and ports because I couldn't find a way to read the port value directly. The port is needed to advertise HTTP/3 support in the Alt-Svc header.

Summary by CodeRabbit

  • New Features

    • HTTP/3 (QUIC) support added with an enable/disable option, configurable UDP port mapping (443/udp), and Alt‑Svc header exposure for HTTP/3.
  • Documentation

    • Changelog, docs, translations, and troubleshooting notes updated with HTTP/3 usage guidance, port/UDP details, and a new 3.15.0 entry.

✏️ Tip: You can customize this high-level summary in your review settings.

Copy link

@home-assistant home-assistant bot left a comment

Choose a reason for hiding this comment

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

Hi @kmhallen

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant home-assistant bot marked this pull request as draft November 19, 2025 02:42
@home-assistant
Copy link

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@kmhallen kmhallen marked this pull request as ready for review November 19, 2025 02:55
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

📝 Walkthrough

Walkthrough

Adds HTTP/3 (QUIC) support: bumps addon version to 3.15.0, exposes UDP port 443, detects/configures a quic_port at runtime, passes quic_port into the nginx template, conditions QUIC listeners and Alt‑Svc on the presence of quic_port, and updates docs, changelog, and translations. No other API/signature changes.

Changes

Cohort / File(s) Summary
Changelog
nginx_proxy/CHANGELOG.md
Adds a new 3.15.0 entry with "Support HTTP/3 (QUIC)".
Configuration
nginx_proxy/config.yaml
Bumps addon version to 3.15.0 and adds 443/udp port mapping alongside existing 443/tcp.
Runtime init / template vars
nginx_proxy/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
Detects QUIC_PORT by querying addon for UDP 443, coerces empty value to null, and passes quic_port as a JSON number into the nginx template renderer.
Nginx template
nginx_proxy/rootfs/etc/nginx/nginx.conf.gtpl
Replaces .options.http3.active gating with checks on .variables.quic_port; when set, adds listen ... quic (including reuseport/proxy_protocol variants), enables http3 on, and emits Alt‑Svc header. Existing HTTP/2, SSL, and proxy_protocol logic preserved.
Documentation
nginx_proxy/DOCS.md
Adds HTTP/3 (QUIC) documentation: optional UDP port section and troubleshooting note about Alt‑Svc/firewall/ports.
Translations
nginx_proxy/translations/en.yaml
Adds 443/udp network mapping description ("HTTP/3 (QUIC) Port") and related labels for HTTP/3.

Sequence Diagram(s)

sequenceDiagram
    participant Addon as Addon metadata
    participant s6run as s6-run script
    participant Template as nginx.conf.gtpl renderer
    participant nginx as nginx

    Addon->>s6run: provide mapped ports (tcp/udp)
    s6run->>s6run: QUIC_PORT = UDP 443 or null
    s6run->>Template: render with JSON { port: <tcp>, quic_port: <number|null> }
    Template->>nginx: write generated nginx.conf
    nginx->>nginx: enable listeners based on quic_port presence

    alt quic_port set
        note right of nginx `#DFF2E1`: UDP QUIC listeners added\nlisten ... quic\nhttp3 on\nAlt-Svc header emitted
    else quic_port null
        note right of nginx `#F7F2E8`: No QUIC/HTTP3 configuration emitted
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title directly summarizes the main change: adding HTTP/3 (QUIC) support to nginx_proxy. It is clear, concise, and accurately reflects the primary objective of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 332cf7a and 5544361.

📒 Files selected for processing (1)
  • nginx_proxy/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
🚧 Files skipped from review as they are similar to previous changes (1)
  • nginx_proxy/rootfs/etc/s6-overlay/s6-rc.d/nginx/run

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
nginx_proxy/translations/en.yaml (1)

23-25: HTTP/3 labels look good; consider minor text polish

The new http3 configuration label and the 443/udp port label are clear and consistent with the rest of the add-on.

Two small optional tweaks:

  • Consider aligning the description with the docs by mentioning “HTTP/3 over QUIC/UDP in addition to HTTP/2 and HTTP/1.1” for extra clarity.
  • There is an existing typo in the keyfile description (“Private Private Key File”) you might want to correct while touching this file.

Also applies to: 37-37

nginx_proxy/DOCS.md (1)

41-43: Tighten http3 docs wording and fix minor typo

The new HTTP/3 documentation is clear but can be tightened and aligned with existing style:

  • For the boolean flag, “If true” is clearer than “If specified”:
-If specified, configures Nginx to use HTTP/3 with QUIC/UDP in addition to HTTP/2 and HTTP/1.1; [for more information](https://nginx.org/en/docs/http/ngx_http_v3_module.html).
-Make sure to enable UDP in your port forward or firewall in addition to TCP.
+If true, configures Nginx to use HTTP/3 with QUIC/UDP in addition to HTTP/2 and HTTP/1.1; [for more information](https://nginx.org/en/docs/http/ngx_http_v3_module.html).
+Enable UDP in your port forward or firewall in addition to TCP.
  • Fix the spelling of “advertize” and slightly clarify the description of http3.port as the advertised HTTP/3 port that must match the network port label:
-Port to advertize with the `Alt-Svc 'h3=":443";` header. Must match the specified network HTTP/3 (QUIC) Port value.
+Port to advertise with the `Alt-Svc 'h3=":443";` header. Must match the configured network **HTTP/3 (QUIC) Port** value.

These changes keep the docs concise and more directive while matching the new configuration surface.

Also applies to: 85-93

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 86e40f6 and 897b04d.

📒 Files selected for processing (5)
  • nginx_proxy/CHANGELOG.md (1 hunks)
  • nginx_proxy/DOCS.md (2 hunks)
  • nginx_proxy/config.yaml (2 hunks)
  • nginx_proxy/rootfs/etc/nginx/nginx.conf.gtpl (2 hunks)
  • nginx_proxy/translations/en.yaml (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
*/**(html|markdown|md)

⚙️ CodeRabbit configuration file

*/**(html|markdown|md): - For instructional content in documentation, use a direct and authoritative tone. Avoid expressions of politeness such as 'may' or 'please', and ensure the goal of the instruction is fronted.

  • Apply the Microsoft Style Guide to ensure documentation maintains clarity and conciseness.
  • In step-by-step instructions, front the location phrase in the instructional sentence.
  • In step-by-step instructions, front the 'goal' in the instructional sentence.
  • In step-by-step instructions, if in doubt what to front, front the 'goal' before the location phrase in the instructional sentence.
  • do not hyphenate terms like 'top-right' or 'bottom-left' with 'corner'

*/**(html|markdown|md): - Use bold to mark UI strings.

  • If "" are used to mark UI strings, replace them by bold.

  • Be brief in your replies and don't add fluff like "thank you for..." and "Please let me know if"

  • Use sentence-style capitalization also in headings.

do not comment on HTML used for icons

Avoid flagging inline HTML for embedding videos in future reviews for this repository.

Files:

  • nginx_proxy/DOCS.md
  • nginx_proxy/config.yaml
  • nginx_proxy/CHANGELOG.md
🔇 Additional comments (2)
nginx_proxy/config.yaml (1)

2-2: HTTP/3 options, port mapping, and schema are consistent

The manifest changes are internally consistent:

  • version: 3.15.0 matches introducing a new feature and should pair with a 3.15.0 changelog entry.
  • The new http3 block (active: false, port: 443) cleanly exposes an opt-in flag and the Alt-Svc port.
  • Adding 443/udp: 443 in ports aligns with the new QUIC listen 443 quic directives and the “HTTP/3 (QUIC) Port” label in translations/en.yaml.
  • The schema.http3 definition (active: bool, port: int) matches the options structure and the way .options.http3 is used in nginx.conf.gtpl.

No structural issues spotted here.

Also applies to: 25-27, 35-35, 43-45

nginx_proxy/rootfs/etc/nginx/nginx.conf.gtpl (1)

43-47: HTTP/3 configuration verified as correct

The NGINX HTTP/3 setup in the template is correct and aligns with current NGINX 1.28.x best practices. The pattern using listen ... quic reuseport with http3 on; is the current recommendation from official NGINX documentation, and both quic and proxy_protocol are valid listen directive parameters.

The conditional blocks at lines 43-47, 77-81, 86-90, and 97-99 properly implement HTTP/3 support with all directives correctly used.

@kmhallen kmhallen force-pushed the nginx_proxy/http3_quic branch from 897b04d to 11466d1 Compare November 19, 2025 03:07
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
nginx_proxy/config.yaml (1)

35-35: UDP 443 mapping default is reasonable but always exposed

Adding 443/udp: 443 ensures HTTP/3 works out of the box once enabled, but it also exposes UDP 443 even when http3.active is false. If you want a stricter default surface, consider defaulting this to null and relying on docs to have users enable UDP when they turn on HTTP/3.

nginx_proxy/rootfs/etc/nginx/nginx.conf.gtpl (1)

97-99: Alt-Svc wiring is correct; consider edge cases

Using Alt-Svc 'h3=":{{ .options.http3.port }}"; ma=86400' correctly ties advertisement to the configured HTTP/3 port and only emits it when HTTP/3 is active. Ensure documentation clearly states that http3.port must match the externally exposed UDP port, and consider adding always if you want Alt-Svc on error responses as well (optional).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 897b04d and 11466d1.

📒 Files selected for processing (5)
  • nginx_proxy/CHANGELOG.md (1 hunks)
  • nginx_proxy/DOCS.md (2 hunks)
  • nginx_proxy/config.yaml (2 hunks)
  • nginx_proxy/rootfs/etc/nginx/nginx.conf.gtpl (2 hunks)
  • nginx_proxy/translations/en.yaml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • nginx_proxy/translations/en.yaml
  • nginx_proxy/CHANGELOG.md
  • nginx_proxy/DOCS.md
🧰 Additional context used
📓 Path-based instructions (1)
*/**(html|markdown|md)

⚙️ CodeRabbit configuration file

*/**(html|markdown|md): - For instructional content in documentation, use a direct and authoritative tone. Avoid expressions of politeness such as 'may' or 'please', and ensure the goal of the instruction is fronted.

  • Apply the Microsoft Style Guide to ensure documentation maintains clarity and conciseness.
  • In step-by-step instructions, front the location phrase in the instructional sentence.
  • In step-by-step instructions, front the 'goal' in the instructional sentence.
  • In step-by-step instructions, if in doubt what to front, front the 'goal' before the location phrase in the instructional sentence.
  • do not hyphenate terms like 'top-right' or 'bottom-left' with 'corner'

*/**(html|markdown|md): - Use bold to mark UI strings.

  • If "" are used to mark UI strings, replace them by bold.

  • Be brief in your replies and don't add fluff like "thank you for..." and "Please let me know if"

  • Use sentence-style capitalization also in headings.

do not comment on HTML used for icons

Avoid flagging inline HTML for embedding videos in future reviews for this repository.

Files:

  • nginx_proxy/config.yaml
🔇 Additional comments (3)
nginx_proxy/config.yaml (2)

2-2: Version bump aligns with new functionality

Version change to 3.15.0 is appropriate for introducing HTTP/3 support; no issues from a config perspective.


25-27: http3 options/schema look consistent; verify upgrade behavior

The http3 options and schema are consistent, and defaulting active: false is a safe way to gate the feature. Verify that on upgrade from pre-3.15.0 installs, the supervisor populates the nested http3 structure so that .options.http3.active and .options.http3.port are always defined for the template.

Also applies to: 43-45

nginx_proxy/rootfs/etc/nginx/nginx.conf.gtpl (1)

43-47: Conditional HTTP/3 listeners are wired consistently

The new listen ... quic directives and http3 on; are consistently wrapped in {{- if .options.http3.active }} across the default, non‑proxy_protocol, and proxy_protocol servers, which cleanly gates QUIC support without affecting existing HTTP/1.1/2 behavior. Confirm that the nginx version in this add‑on is built with HTTP/3/QUIC support and that the quic reuseport proxy_protocol combination matches the versioned nginx docs you target.

Also applies to: 77-81, 86-90

@agners
Copy link
Member

agners commented Nov 19, 2025

Thank you for your PR, nice addition 🤩

The port is specified both in options and ports because I couldn't find a way to read the port value directly. The port is needed to advertise HTTP/3 support in the Alt-Svc header.

It should be possible to read the port using quic_port="$(bashio::addon.port '443/udp')".

Comment on lines 16 to 18
# shellcheck disable=SC2046
JSON_CONF=$(jq --arg port $(bashio::core.port) \
'({options: .}) + ({variables: {port: $port}})' \
JSON_CONF=$(jq --argjson port $(bashio::core.port) --argjson quic_port $QUIC_PORT \
'({options: .}) + ({variables: {port: $port, quic_port: $quic_port}})' \
Copy link
Member

Choose a reason for hiding this comment

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

With simple quotes the values are still consumed as numbers (since bash removes them). This eliminates the linter error:

Suggested change
# shellcheck disable=SC2046
JSON_CONF=$(jq --arg port $(bashio::core.port) \
'({options: .}) + ({variables: {port: $port}})' \
JSON_CONF=$(jq --argjson port $(bashio::core.port) --argjson quic_port $QUIC_PORT \
'({options: .}) + ({variables: {port: $port, quic_port: $quic_port}})' \
JSON_CONF=$(jq --argjson port "$(bashio::core.port)" --argjson quic_port "$QUIC_PORT" \
'({options: .}) + ({variables: {port: $port, quic_port: $quic_port}})' \

listen [::]:443 ssl;
http2 on;
{{- if .variables.quic_port }}
listen 443 quic reuseport;
Copy link
Member

Choose a reason for hiding this comment

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

Is reuseport required here? We don't use it for the other instances. I'd expect a problem if that port is already used by some other process. 🤔

Copy link
Author

Choose a reason for hiding this comment

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

I don't know, but every example of NGINX and QUIC I found used the reuseport keyword.

@home-assistant home-assistant bot marked this pull request as draft November 24, 2025 08:11
@kmhallen kmhallen marked this pull request as ready for review January 7, 2026 15:26
@home-assistant home-assistant bot requested a review from agners January 7, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants