diff --git a/.github/DISCUSSION_TEMPLATE/issue-triage.yml b/.github/DISCUSSION_TEMPLATE/issue-triage.yml index aad41527..68862a97 100644 --- a/.github/DISCUSSION_TEMPLATE/issue-triage.yml +++ b/.github/DISCUSSION_TEMPLATE/issue-triage.yml @@ -9,7 +9,7 @@ body: **Before submitting, please:** - Search [existing discussions](https://github.com/benoitc/gunicorn/discussions) and [issues](https://github.com/benoitc/gunicorn/issues) for duplicates - - Check the [FAQ](https://docs.gunicorn.org/en/latest/faq.html) and [documentation](https://docs.gunicorn.org/) + - Check the [FAQ](https://gunicorn.org/faq/) and [documentation](https://gunicorn.org/) - type: dropdown id: type diff --git a/.github/DISCUSSION_TEMPLATE/question.yml b/.github/DISCUSSION_TEMPLATE/question.yml index 2e343632..8f6abd34 100644 --- a/.github/DISCUSSION_TEMPLATE/question.yml +++ b/.github/DISCUSSION_TEMPLATE/question.yml @@ -6,9 +6,9 @@ body: Have a question about Gunicorn? Before asking, please check: - - [Documentation](https://docs.gunicorn.org/) - - [FAQ](https://docs.gunicorn.org/en/latest/faq.html) - - [Settings Reference](https://docs.gunicorn.org/en/latest/settings.html) + - [Documentation](https://gunicorn.org/) + - [FAQ](https://gunicorn.org/faq/) + - [Settings Reference](https://gunicorn.org/reference/settings/) - [Existing discussions](https://github.com/benoitc/gunicorn/discussions) - type: textarea diff --git a/docs/content/2012-news.md b/docs/content/2012-news.md index 7d338046..31f11e31 100644 --- a/docs/content/2012-news.md +++ b/docs/content/2012-news.md @@ -29,7 +29,7 @@ ## 0.15.0 / 2012-10-18 -- new documentation site on http://docs.gunicorn.org +- new documentation site on https://gunicorn.org - new website on http://gunicorn.org - add `haproxy PROXY protocol `_ support - add ForwardedAllowIPS option: allows to filter Front-end's IPs diff --git a/docs/content/2014-news.md b/docs/content/2014-news.md index ed1937c2..f9149cfb 100644 --- a/docs/content/2014-news.md +++ b/docs/content/2014-news.md @@ -80,7 +80,7 @@ ### Documentation - update faq: put a note on how `watch logs in the console - `_ + `_ since many people asked for it. @@ -88,7 +88,7 @@ Gunicorn 19.0 is a major release with new features and fixes. This version improve a lot the usage of Gunicorn with python 3 by adding `two -new workers `_ +new workers `_ to it: `gthread` a fully threaded async worker using futures and `gaiohttp` a worker using asyncio. diff --git a/docs/content/2026-news.md b/docs/content/2026-news.md index 2c9bd8d6..a5c3857a 100644 --- a/docs/content/2026-news.md +++ b/docs/content/2026-news.md @@ -1,6 +1,62 @@ # Changelog - 2026 +## 24.1.0 - 2026-01-23 + +### New Features + +- **PROXY Protocol v2 Support**: Extended PROXY protocol implementation to support + the binary v2 format in addition to the existing text-based v1 format + ([PR #3451](https://github.com/benoitc/gunicorn/pull/3451)) + - New `--proxy-protocol` modes: `off`, `v1`, `v2`, `auto` + - `auto` mode (default when enabled) detects v1 or v2 automatically + - v2 binary format is more efficient and supports additional metadata + - Works with HAProxy, AWS NLB/ALB, and other PROXY protocol v2 sources + +- **CIDR Network Support**: `--forwarded-allow-ips` and `--proxy-allow-from` now + accept CIDR notation (e.g., `192.168.0.0/16`) for specifying trusted networks + ([PR #3449](https://github.com/benoitc/gunicorn/pull/3449)) + +- **Socket Backlog Metric**: New `gunicorn.socket.backlog` gauge metric reports + the current socket backlog size on Linux systems + ([PR #3450](https://github.com/benoitc/gunicorn/pull/3450)) + +- **InotifyReloader Enhancement**: The inotify-based reloader now watches newly + imported modules, not just those loaded at startup + ([PR #3447](https://github.com/benoitc/gunicorn/pull/3447)) + +### Bug Fixes + +- Fix socket blocking mode on keepalive connections preventing SSL handshake + failures with async workers + ([PR #3452](https://github.com/benoitc/gunicorn/pull/3452)) + +- Use smaller buffer size in `finish_body()` for faster timeout detection on + slow or abandoned connections + ([PR #3453](https://github.com/benoitc/gunicorn/pull/3453)) + +- Handle `SSLWantReadError` in `finish_body()` to prevent worker hangs during + SSL renegotiation + ([PR #3448](https://github.com/benoitc/gunicorn/pull/3448)) + +- Log SIGTERM as info level instead of warning to reduce noise in orchestrated + environments + ([PR #3446](https://github.com/benoitc/gunicorn/pull/3446)) + +- Print exception details to stderr when worker fails to boot + ([PR #3443](https://github.com/benoitc/gunicorn/pull/3443)) + +- Fix `unreader.unread()` to prepend data to buffer instead of appending + ([PR #3442](https://github.com/benoitc/gunicorn/pull/3442)) + +- Prevent `RecursionError` when pickling Config objects + ([PR #3441](https://github.com/benoitc/gunicorn/pull/3441)) + +- Use proper exception chaining with `raise from` in glogging.py + ([PR #3440](https://github.com/benoitc/gunicorn/pull/3440)) + +--- + ## 24.0.0 - 2026-01-23 ### New Features diff --git a/docs/content/deploy.md b/docs/content/deploy.md index 435bc426..63b807d9 100644 --- a/docs/content/deploy.md +++ b/docs/content/deploy.md @@ -78,6 +78,92 @@ proxy IP rather than the upstream client. To log the real client address, set When binding Gunicorn to a UNIX socket `REMOTE_ADDR` will be empty. +## PROXY Protocol + +The [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) +allows load balancers and reverse proxies to pass original client connection +information (IP address, port) to backend servers. This is especially useful +when TLS termination happens at the proxy layer. + +Gunicorn supports both PROXY protocol v1 (text format) and v2 (binary format). + +### Configuration + +Enable PROXY protocol with the `--proxy-protocol` option: + +```bash +# Auto-detect v1 or v2 (recommended) +gunicorn --proxy-protocol auto app:app + +# Force v1 only (text format) +gunicorn --proxy-protocol v1 app:app + +# Force v2 only (binary format, more efficient) +gunicorn --proxy-protocol v2 app:app +``` + +Using `--proxy-protocol` without a value is equivalent to `auto`. + +!!! warning "Security" + Only enable PROXY protocol when Gunicorn is behind a trusted proxy that sends + PROXY headers. Configure [`--proxy-allow-from`](reference/settings.md#proxy_allow_ips) + to restrict which IPs can send PROXY protocol headers. + +### HAProxy + +HAProxy can send PROXY protocol headers to backends. Example configuration: + +```haproxy +frontend https_front + bind *:443 ssl crt /etc/ssl/certs/site.pem + default_backend gunicorn_back + +backend gunicorn_back + # Send PROXY protocol v2 (binary, more efficient) + server gunicorn 127.0.0.1:8000 send-proxy-v2 + + # Or use v1 (text format) + # server gunicorn 127.0.0.1:8000 send-proxy +``` + +Start Gunicorn to accept PROXY protocol: + +```bash +gunicorn -b 127.0.0.1:8000 --proxy-protocol v2 --proxy-allow-from 127.0.0.1 app:app +``` + +### stunnel + +[stunnel](https://www.stunnel.org/) can terminate TLS and forward connections +with PROXY protocol headers: + +```ini +# /etc/stunnel/stunnel.conf +[https] +accept = 443 +connect = 127.0.0.1:8000 +cert = /etc/ssl/certs/stunnel.pem +key = /etc/ssl/certs/stunnel.key +protocol = proxy +``` + +The `protocol = proxy` directive tells stunnel to prepend PROXY protocol v1 +headers to forwarded connections. + +### AWS/ELB + +AWS Network Load Balancers (NLB) and Application Load Balancers (ALB) support +PROXY protocol v2. Enable it in the target group settings, then configure +Gunicorn: + +```bash +gunicorn --proxy-protocol v2 --proxy-allow-from '*' app:app +``` + +!!! note + When using `--proxy-allow-from '*'` ensure Gunicorn is not directly + accessible from the internet—only through the load balancer. + ## Using virtual environments Install Gunicorn inside your project diff --git a/docs/content/reference/settings.md b/docs/content/reference/settings.md index 79aecefa..76b58d5b 100644 --- a/docs/content/reference/settings.md +++ b/docs/content/reference/settings.md @@ -1179,7 +1179,7 @@ Example for stunnel config:: cert = /etc/ssl/certs/stunnel.pem key = /etc/ssl/certs/stunnel.key -!!! info "Changed in 24.0.0" +!!! info "Changed in 24.1.0" Extended to support version selection (v1, v2, auto). ### `proxy_allow_ips` diff --git a/examples/example_config.py b/examples/example_config.py index 59288242..f42b3d86 100644 --- a/examples/example_config.py +++ b/examples/example_config.py @@ -34,14 +34,14 @@ backlog = 2048 # worker_class - The type of workers to use. The default # sync class should handle most 'normal' types of work # loads. You'll want to read -# http://docs.gunicorn.org/en/latest/design.html#choosing-a-worker-type +# https://gunicorn.org/design/#choosing-a-worker-type # for information on when you might want to choose one # of the other worker classes. # # A string referring to a Python path to a subclass of # gunicorn.workers.base.Worker. The default provided values # can be seen at -# http://docs.gunicorn.org/en/latest/settings.html#worker-class +# https://gunicorn.org/reference/settings/#worker_class # # worker_connections - For the eventlet and gevent worker classes # this limits the maximum number of simultaneous clients that diff --git a/gunicorn/__init__.py b/gunicorn/__init__.py index 347557ce..8b90daf1 100644 --- a/gunicorn/__init__.py +++ b/gunicorn/__init__.py @@ -2,7 +2,7 @@ # This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. -version_info = (24, 0, 0) +version_info = (24, 1, 0) __version__ = ".".join([str(v) for v in version_info]) SERVER = "gunicorn" SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__) diff --git a/gunicorn/config.py b/gunicorn/config.py index 700c9429..58141e55 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -2143,7 +2143,7 @@ class ProxyProtocol(Setting): cert = /etc/ssl/certs/stunnel.pem key = /etc/ssl/certs/stunnel.key - .. versionchanged:: 24.0.0 + .. versionchanged:: 24.1.0 Extended to support version selection (v1, v2, auto). """ diff --git a/pyproject.toml b/pyproject.toml index c176784f..5bdf6e95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,10 +41,10 @@ dynamic = ["version"] [project.urls] Homepage = "https://gunicorn.org" -Documentation = "https://docs.gunicorn.org" +Documentation = "https://gunicorn.org" "Issue tracker" = "https://github.com/benoitc/gunicorn/issues" "Source code" = "https://github.com/benoitc/gunicorn" -Changelog = "https://docs.gunicorn.org/en/stable/news.html" +Changelog = "https://gunicorn.org/news/" [project.optional-dependencies] gevent = ["gevent>=24.10.1"]