Merge pull request #8248 from osbre/feat/nginx-upstream-keepalive-property

Add `proxy-keepalive` to Nginx properties
This commit is contained in:
Jose Diaz-Gonzalez
2026-01-03 22:08:02 -05:00
committed by GitHub
8 changed files with 60 additions and 3 deletions

View File

@@ -338,6 +338,7 @@ Changing these value globally or on a per-app basis will require rebuilding the
| proxy-buffers | `8 8k` | string | Number and size of the buffers used for reading the proxied server response, for a single connection |
| proxy-busy-buffers-size | `16k` | string | Limits the total size of buffers that can be busy sending a response to the client while the response is not yet fully read. |
| proxy-connect-timeout | `60s` | string | Timeout (with units) for establishing a connection to your backend server |
| proxy-keepalive | empty (disabled) | integer | Number of idle keepalive connections to upstream servers (disabled by default) |
| proxy-read-timeout | `60s` | string | Timeout (with units) for reading response from your backend server |
| proxy-send-timeout | `60s` | string | Timeout (with units) for transmitting a request to your backend server |
| send-timeout | `60s` | string | Timeout (with units) for transmitting a response to your the client |

View File

@@ -110,6 +110,9 @@ cmd-nginx-report-single() {
"--nginx-send-timeout: $(fn-nginx-send-timeout "$APP")"
"--nginx-computed-send-timeout: $(fn-nginx-computed-send-timeout "$APP")"
"--nginx-global-send-timeout: $(fn-nginx-global-send-timeout "$APP")"
"--nginx-proxy-keepalive: $(fn-nginx-proxy-keepalive "$APP")"
"--nginx-computed-proxy-keepalive: $(fn-nginx-computed-proxy-keepalive "$APP")"
"--nginx-global-proxy-keepalive: $(fn-nginx-global-proxy-keepalive "$APP")"
"--nginx-underscore-in-headers: $(fn-nginx-underscore-in-headers "$APP")"
"--nginx-computed-underscore-in-headers: $(fn-nginx-computed-underscore-in-headers "$APP")"
"--nginx-global-underscore-in-headers: $(fn-nginx-global-underscore-in-headers "$APP")"

View File

@@ -304,6 +304,7 @@ nginx_build_config() {
local PROXY_BUFFERING="$(fn-nginx-computed-proxy-buffering "$APP")"
local PROXY_BUFFERS="$(fn-nginx-computed-proxy-buffers "$APP")"
local PROXY_BUSY_BUFFERS_SIZE="$(fn-nginx-computed-proxy-busy-buffers-size "$APP")"
local PROXY_KEEPALIVE="$(fn-nginx-computed-proxy-keepalive "$APP")"
if [[ -z "$DOKKU_APP_LISTENERS" ]]; then
dokku_log_warn_quiet "No web listeners specified for $APP"
@@ -370,6 +371,7 @@ nginx_build_config() {
PROXY_BUFFERING="$PROXY_BUFFERING"
PROXY_BUFFERS="$PROXY_BUFFERS"
PROXY_BUSY_BUFFERS_SIZE="$PROXY_BUSY_BUFFERS_SIZE"
PROXY_KEEPALIVE="$PROXY_KEEPALIVE"
NGINX_UNDERSCORE_IN_HEADERS="$NGINX_UNDERSCORE_IN_HEADERS"
# Deprecated: Remove this after a few versions
NGINX_PORT="$PROXY_PORT" NGINX_SSL_PORT="$PROXY_SSL_PORT"

View File

@@ -509,6 +509,27 @@ fn-nginx-global-send-timeout() {
fn-get-property --app "$APP" --global "send-timeout"
}
fn-nginx-proxy-keepalive() {
declare desc="get the configured upstream keepalive"
declare APP="$1"
fn-get-property --app "$APP" "proxy-keepalive"
}
fn-nginx-computed-proxy-keepalive() {
declare desc="get the computed upstream keepalive"
declare APP="$1"
fn-get-property --app "$APP" --computed "proxy-keepalive"
}
fn-nginx-global-proxy-keepalive() {
declare desc="get the global upstream keepalive"
declare APP="$1"
fn-get-property --app "$APP" --global "proxy-keepalive"
}
fn-nginx-underscore-in-headers() {
declare desc="get the configured underscore in headers value"
declare APP="$1"

View File

@@ -518,3 +518,20 @@ func ComputedXForwardedSSL(appName string) string {
func GlobalXForwardedSSL() string {
return common.PropertyGetDefault("nginx", "--global", "x-forwarded-ssl", "")
}
func AppProxyKeepalive(appName string) string {
return common.PropertyGet("nginx", appName, "proxy-keepalive")
}
func ComputedProxyKeepalive(appName string) string {
appValue := AppProxyKeepalive(appName)
if appValue != "" {
return appValue
}
return GlobalProxyKeepalive()
}
func GlobalProxyKeepalive() string {
return common.PropertyGetDefault("nginx", "--global", "proxy-keepalive", "")
}

View File

@@ -83,6 +83,8 @@ func appValue(appName string, property string) string {
value = nginx_vhosts.AppProxyReadTimeout(appName)
case "proxy-send-timeout":
value = nginx_vhosts.AppProxySendTimeout(appName)
case "proxy-keepalive":
value = nginx_vhosts.AppProxyKeepalive(appName)
case "send-timeout":
value = nginx_vhosts.AppSendTimeout(appName)
case "underscore-in-headers":
@@ -151,6 +153,8 @@ func computedValue(appName string, property string) string {
value = nginx_vhosts.ComputedProxyReadTimeout(appName)
case "proxy-send-timeout":
value = nginx_vhosts.ComputedProxySendTimeout(appName)
case "proxy-keepalive":
value = nginx_vhosts.ComputedProxyKeepalive(appName)
case "send-timeout":
value = nginx_vhosts.ComputedSendTimeout(appName)
case "underscore-in-headers":
@@ -219,6 +223,8 @@ func globalValue(appName string, property string) string {
value = nginx_vhosts.GlobalProxyReadTimeout()
case "proxy-send-timeout":
value = nginx_vhosts.GlobalProxySendTimeout()
case "proxy-keepalive":
value = nginx_vhosts.GlobalProxyKeepalive()
case "send-timeout":
value = nginx_vhosts.GlobalSendTimeout()
case "underscore-in-headers":

View File

@@ -9,13 +9,13 @@ cmd-nginx-set() {
declare cmd="nginx:set"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" KEY="$2" VALUE="$3"
local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-body-timeout" "client-header-timeout" "client-max-body-size" "disable-custom-config" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "keepalive-timeout" "lingering-timeout" "nginx-conf-sigil-path" "nginx-service-command" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "proxy-connect-timeout" "proxy-read-timeout" "proxy-send-timeout" "send-timeout" "underscore-in-headers" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local GLOBAL_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-body-timeout" "client-header-timeout" "client-max-body-size" "disable-custom-config" "error-log-path" "hsts-include-subdomains" "hsts-max-age" "hsts-preload" "hsts" "keepalive-timeout" "lingering-timeout" "nginx-conf-sigil-path" "nginx-service-command" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "proxy-connect-timeout" "proxy-read-timeout" "proxy-send-timeout" "send-timeout" "underscore-in-headers" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-body-timeout" "client-header-timeout" "client-max-body-size" "disable-custom-config" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "keepalive-timeout" "lingering-timeout" "nginx-conf-sigil-path" "nginx-service-command" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "proxy-connect-timeout" "proxy-read-timeout" "proxy-send-timeout" "proxy-keepalive" "send-timeout" "underscore-in-headers" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local GLOBAL_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-body-timeout" "client-header-timeout" "client-max-body-size" "disable-custom-config" "error-log-path" "hsts-include-subdomains" "hsts-max-age" "hsts-preload" "hsts" "keepalive-timeout" "lingering-timeout" "nginx-conf-sigil-path" "nginx-service-command" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "proxy-connect-timeout" "proxy-read-timeout" "proxy-send-timeout" "proxy-keepalive" "send-timeout" "underscore-in-headers" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, client-body-timeout, client-header-timeout, client-max-body-size, disable-custom-config, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, keepalive-timeout, lingering-timeout, nginx-conf-sigil-path, nginx-service-command, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, proxy-connect-timeout, proxy-read-timeout, proxy-send-timeout, send-timeout, underscore-in-headers, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value, x-forwarded-ssl"
dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, client-body-timeout, client-header-timeout, client-max-body-size, disable-custom-config, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, keepalive-timeout, lingering-timeout, nginx-conf-sigil-path, nginx-service-command, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, proxy-connect-timeout, proxy-read-timeout, proxy-send-timeout, proxy-keepalive, send-timeout, underscore-in-headers, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value, x-forwarded-ssl"
fi
if ! fn-in-array "$KEY" "${GLOBAL_KEYS[@]}"; then
@@ -25,6 +25,12 @@ cmd-nginx-set() {
verify_app_name "$APP"
fi
if [[ "$KEY" == "proxy-keepalive" ]] && [[ -n "$VALUE" ]]; then
if ! is_number "$VALUE"; then
dokku_log_fail "Invalid value for proxy-keepalive: must be an integer"
fi
fi
if [[ -n "$VALUE" ]]; then
dokku_log_info2_quiet "Setting ${KEY} to ${VALUE}"
fn-plugin-property-write "nginx" "$APP" "$KEY" "$VALUE"

View File

@@ -212,6 +212,7 @@ server {
{{ if $.DOKKU_APP_WEB_LISTENERS }}
{{ range $upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
upstream {{ $.APP }}-{{ $upstream_port }} {
{{ if $.PROXY_KEEPALIVE }} keepalive {{ $.PROXY_KEEPALIVE }};{{ end }}
{{ range $listeners := $.DOKKU_APP_WEB_LISTENERS | split " " }}
{{ $listener_list := $listeners | split ":" }}
{{ $listener_ip := index $listener_list 0 }}