diff --git a/docs/networking/proxies/nginx.md b/docs/networking/proxies/nginx.md index bd6b5d92a..330f5fa0f 100644 --- a/docs/networking/proxies/nginx.md +++ b/docs/networking/proxies/nginx.md @@ -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 | diff --git a/plugins/nginx-vhosts/command-functions b/plugins/nginx-vhosts/command-functions index a27ef914d..84490ec8a 100755 --- a/plugins/nginx-vhosts/command-functions +++ b/plugins/nginx-vhosts/command-functions @@ -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")" diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 2d190e613..0f81141c4 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -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" diff --git a/plugins/nginx-vhosts/internal-functions b/plugins/nginx-vhosts/internal-functions index 1950e199e..19186c4dd 100755 --- a/plugins/nginx-vhosts/internal-functions +++ b/plugins/nginx-vhosts/internal-functions @@ -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" diff --git a/plugins/nginx-vhosts/nginx_vhosts.go b/plugins/nginx-vhosts/nginx_vhosts.go index 8c25ac1a7..6c552fd62 100644 --- a/plugins/nginx-vhosts/nginx_vhosts.go +++ b/plugins/nginx-vhosts/nginx_vhosts.go @@ -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", "") +} diff --git a/plugins/nginx-vhosts/src/nginx-property/nginx-property.go b/plugins/nginx-vhosts/src/nginx-property/nginx-property.go index 47c3bbd49..ce61ef4ae 100644 --- a/plugins/nginx-vhosts/src/nginx-property/nginx-property.go +++ b/plugins/nginx-vhosts/src/nginx-property/nginx-property.go @@ -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": diff --git a/plugins/nginx-vhosts/subcommands/set b/plugins/nginx-vhosts/subcommands/set index 12cfaaab5..e3118c4c7 100755 --- a/plugins/nginx-vhosts/subcommands/set +++ b/plugins/nginx-vhosts/subcommands/set @@ -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" diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index 9c200882e..85c76cac1 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -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 }}