initial pass at implementing DOKKU_PROXY_PORT_MAP. closes #2239.

This commit is contained in:
Michael Hobbs
2016-06-14 17:36:26 -07:00
parent 99c56ccd6d
commit 6c1d6225f9
33 changed files with 473 additions and 208 deletions

View File

@@ -72,6 +72,7 @@ upstream {{ .APP }} {
{{ .NGINX_PORT }} Non-SSL nginx listener port (same as `DOKKU_NGINX_PORT` config var)
{{ .NGINX_SSL_PORT }} SSL nginx listener port (same as `DOKKU_NGINX_SSL_PORT` config var)
{{ .NOSSL_SERVER_NAME }} List of non-SSL VHOSTS
{{ .PROXY_PORT_MAP }} List of port mappings (same as `DOKKU_PROXY_PORT_MAP` config var)
{{ .RAW_TCP_PORTS }} List of exposed tcp ports as defined by Dockerfile `EXPOSE` directive (**Dockerfile apps only**)
{{ .SSL_INUSE }} Boolean set when an app is SSL-enabled
{{ .SSL_SERVER_NAME }} List of SSL VHOSTS

View File

@@ -0,0 +1 @@
hook

View File

@@ -0,0 +1 @@
hook

View File

@@ -0,0 +1 @@
hook

View File

@@ -0,0 +1 @@
hook

View File

@@ -0,0 +1 @@
hook

View File

@@ -0,0 +1 @@
hook

View File

@@ -70,7 +70,8 @@ certs_set() {
chmod 750 "$APP_SSL_PATH"
chmod 640 "$APP_SSL_PATH/server.crt" "$APP_SSL_PATH/server.key"
cd "$DOKKU_ROOT"
nginx_build_config "$APP"
plugn trigger post-certs-update "$APP"
plugn trigger post-domains-update "$APP"
}
certs_set "$@"

View File

@@ -12,6 +12,7 @@ certs_remove_cmd() {
if [[ -d "$APP_SSL_PATH" ]]; then
dokku_log_info1 "Removing SSL endpoint from $APP"
rm -rf "$APP_SSL_PATH"
plugn trigger post-certs-remove "$APP"
plugn trigger post-domains-update "$APP"
else
dokku_log_fail "An app-specific SSL endpoint is not defined"

View File

@@ -573,9 +573,8 @@ disable_app_vhost() {
local APP=$1; verify_app_name "$APP"
local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
local APP_URLS_FILE="$DOKKU_ROOT/$APP/URLS"
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
local DOKKU_NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT)
plugn trigger pre-disable-vhost "$APP"
if [[ -f "$APP_VHOST_FILE" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/VHOST"
rm "$APP_VHOST_FILE"
@@ -584,12 +583,6 @@ disable_app_vhost() {
dokku_log_info1 "VHOST support disabled, deleting $APP/URLS"
rm "$APP_URLS_FILE"
fi
if [[ "$DOKKU_NGINX_PORT" == "80" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_PORT
fi
if [[ "$DOKKU_NGINX_SSL_PORT" == "443" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_SSL_PORT
fi
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
@@ -602,7 +595,7 @@ enable_app_vhost() {
local APP=$1; verify_app_name "$APP"
config_unset --no-restart "$APP" DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT
plugn trigger pre-enable-vhost "$APP"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS "$APP" NO_VHOST=0
@@ -676,36 +669,43 @@ get_container_ports() {
get_app_urls() {
declare desc="print an app's available urls"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
local APP="$2"; verify_app_name "$APP"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"
local URLS_FILE="$DOKKU_ROOT/$APP/URLS"
local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)
if [[ -s "$URLS_FILE" ]]; then
local app_urls="$(egrep -v "^#" "$URLS_FILE")"
if [[ -n "$RAW_TCP_PORTS" ]]; then
for url in ${app_urls[*]}; do
for p in $RAW_TCP_PORTS; do
local port_urls+="$url:$p "
if [[ -n "$DOKKU_PROXY_PORT_MAP" ]]; then
local port_map app_vhost
local app_vhosts=$(get_app_domains "$APP")
for port_map in $DOKKU_PROXY_PORT_MAP; do
local scheme="$(awk -F ':' '{ print $1 }' <<< "$port_map")"
local listen_port="$(awk -F ':' '{ print $2 }' <<< "$port_map")"
for app_vhost in $app_vhosts; do
if [[ "$listen_port" != "80" ]] && [[ "$listen_port" != "443" ]]; then
port_urls+=" $scheme://$app_vhost:$listen_port "
else
port_urls+=" $scheme://$app_vhost "
fi
done
done
local port_urls="$(echo "$port_urls"| xargs)"
fi
local URLS=${port_urls:=$app_urls}
local port_urls="$(echo "$port_urls"| xargs)"
local URLS="$(merge_dedupe_list "$port_urls $app_urls" " ")"
case "$1" in
url)
echo "$URLS" | tr ' ' '\n' | head -n1
;;
urls)
echo "$URLS" | tr ' ' '\n'
echo "$URLS" | tr ' ' '\n' | sort
;;
esac
else
local SCHEME="http"; local SSL="$DOKKU_ROOT/$APP/tls"
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT || true)
local DOKKU_NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT || true)
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]]; then
local SCHEME="https"
fi
@@ -724,13 +724,13 @@ get_app_urls() {
done
shopt -u nullglob
fi
elif [[ -n "$DOKKU_NGINX_PORT" ]] || [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
if [[ -n "$DOKKU_NGINX_PORT" ]];then
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_PORT ($(get_app_proxy_type "$APP"))"
fi
if [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
echo "https://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_SSL_PORT ($(get_app_proxy_type "$APP")-ssl)"
fi
elif [[ -n "$DOKKU_PROXY_PORT_MAP" ]]; then
local port_map
for port_map in $DOKKU_PROXY_PORT_MAP; do
local scheme="$(awk -F ':' '{ print $1 }' <<< "$port_map")"
local listen_port="$(awk -F ':' '{ print $2 }' <<< "$port_map")"
echo "$scheme://$(< "$DOKKU_ROOT/HOSTNAME"):$listen_port"
done
elif [[ -n "$RAW_TCP_PORTS" ]]; then
for p in $RAW_TCP_PORTS; do
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$p"
@@ -812,3 +812,11 @@ add_val_to_list() {
list+="${delimiter}$value"
echo "$list"
}
merge_dedupe_list() {
declare desc="combine lists ($1) separated by delimiter ($2) (delimiter defaults to comma), dedupe and return list"
local input_lists="$1" delimiter="${2:-,}"
local merged_list="$(tr "$delimiter" $'\n' <<< "$input_lists" | sort | uniq | xargs)"
echo "$merged_list"
}

View File

@@ -14,6 +14,12 @@ validate_nginx() {
set -e
if [[ "$exit_code" -ne "0" ]]; then
sudo /usr/sbin/nginx -t
shopt -s nullglob
local conf_file
for conf_file in $DOKKU_ROOT/*/nginx.conf; do
dokku_log_verbose "validate_nginx failed. contents of $conf_file below..."
cat "$conf_file"
done
exit "$exit_code"
fi
}
@@ -61,30 +67,51 @@ configure_nginx_ports() {
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
local DOKKU_NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT)
local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
local IS_APP_VHOST_ENABLED="$(is_app_vhost_enabled "$APP")"
if [[ -z "$DOKKU_NGINX_PORT" ]]; then
if [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "no nginx port set. setting to random open high port"
local NGINX_PORT=$(get_available_port)
else
local NGINX_PORT=80
fi
fi
if [[ -n "$NGINX_PORT" ]]; then
config_set --no-restart "$APP" DOKKU_NGINX_PORT="${NGINX_PORT}"
if [[ -z "$DOKKU_NGINX_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "no nginx port set. setting to random open high port"
local NGINX_PORT=$(get_available_port)
else
local NGINX_PORT=80
fi
fi
if (is_ssl_enabled "$APP") && [[ -z "$DOKKU_NGINX_SSL_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
local NGINX_SSL_PORT=$(get_available_port)
else
local NGINX_SSL_PORT=443
if [[ -z "$DOKKU_NGINX_SSL_PORT" ]]; then
if (is_ssl_enabled "$APP") && [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
local NGINX_SSL_PORT=$(get_available_port)
else
local NGINX_SSL_PORT=443
fi
fi
fi
if [[ -z "$DOKKU_PROXY_PORT_MAP" ]]; then
if [[ -n "$RAW_TCP_PORTS" ]]; then
local RAW_TCP_PORT
for RAW_TCP_PORT in $RAW_TCP_PORTS; do
local PROXY_PORT_MAP+=" http:${RAW_TCP_PORT}:${RAW_TCP_PORT} "
done
else
local NGINX_PORT=${NGINX_PORT:-$DOKKU_NGINX_PORT}
local NGINX_SSL_PORT=${NGINX_SSL_PORT:-$DOKKU_NGINX_SSL_PORT}
if [[ -n "$NGINX_PORT" ]] && [[ -n "$NGINX_SSL_PORT" ]]; then
local PROXY_PORT_MAP+=" http:${NGINX_PORT}:5000 https:${NGINX_SSL_PORT}:5000 "
elif [[ -n "$NGINX_PORT" ]]; then
local PROXY_PORT_MAP+=" http:${NGINX_PORT}:5000 "
fi
fi
if [[ -n "$PROXY_PORT_MAP" ]]; then
local PROXY_PORT_MAP="$(echo "$PROXY_PORT_MAP" | xargs)"
local PROXY_PORT_MAP+=" $(merge_dedupe_list "$(remove_val_from_list "$PORT_MAP" "$DOKKU_PROXY_PORT_MAP" " ")" " ") "
config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP"
fi
config_set --no-restart "$APP" DOKKU_NGINX_SSL_PORT="${NGINX_SSL_PORT}"
fi
}
@@ -93,12 +120,12 @@ validate_ssl_domains() {
local APP=$1; verify_app_name "$APP"
local SSL_HOSTNAME=$(get_ssl_hostnames "$APP")
local SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
local domain
if ! (egrep -q "^${SSL_HOSTNAME_REGEX}$" "$VHOST_PATH" &> /dev/null); then
dokku_log_info1 "No matching configured domains for $APP found in SSL certificate. Your app will show as insecure in a browser if accessed via SSL"
dokku_log_info1 "Please add appropriate domains via the dokku domains command"
[[ -n "$NONSSL_VHOSTS" ]] && dokku_log_info1 "Configured domains for app:"
local domain
for domain in $(echo "$NONSSL_VHOSTS"| xargs); do
dokku_log_info2 "$domain"
done
@@ -169,19 +196,29 @@ nginx_build_config() {
local DOKKU_APP_PORT_FILE="${DOKKU_APP_IP_FILE//IP/PORT}"
local DOKKU_APP_LISTENER_IP=$(< "$DOKKU_APP_IP_FILE")
local DOKKU_APP_LISTENER_PORT=$(< "$DOKKU_APP_PORT_FILE")
if [[ -z "$RAW_TCP_PORTS" ]]; then
local DOKKU_APP_LISTENERS+=" $DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT "
else
local DOKKU_APP_LISTENERS+=" $DOKKU_APP_LISTENER_IP "
fi
local DOKKU_APP_LISTENERS=$(echo "$DOKKU_APP_LISTENERS" | xargs)
local DOKKU_APP_LISTENERS+="$DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT "
done
local DOKKU_APP_LISTENERS="$(echo "$DOKKU_APP_LISTENERS" | xargs)"
shopt -u nullglob
elif [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
local PASSED_LISTEN_IP_PORT=true
fi
# setup nginx listen ports
configure_nginx_ports "$APP"
local NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
local NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT)
local PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
local PORT_MAP
for PORT_MAP in $PROXY_PORT_MAP; do
local PROXY_UPSTREAM_PORT="$(awk -F ':' '{ print $3 }' <<< "$PORT_MAP")"
if [[ "$(is_val_in_list "$PROXY_UPSTREAM_PORT" "$PROXY_UPSTREAM_PORTS" " ")" == "false" ]]; then
local PROXY_UPSTREAM_PORTS+="$PROXY_UPSTREAM_PORT "
fi
done
local PROXY_UPSTREAM_PORTS="$(echo "$PROXY_UPSTREAM_PORTS" | xargs)"
local NGINX_BUILD_CONFIG_TMP_WORK_DIR=$(mktemp -d /tmp/dokku_nginx_template.XXXXX)
local NGINX_CONF=$(mktemp --tmpdir="${NGINX_BUILD_CONFIG_TMP_WORK_DIR}" "nginx.conf.XXXXXX")
local CUSTOM_NGINX_TEMPLATE="$NGINX_BUILD_CONFIG_TMP_WORK_DIR/$NGINX_TEMPLATE_NAME"
@@ -195,11 +232,6 @@ nginx_build_config() {
local NGINX_TEMPLATE_SOURCE="app-supplied"
fi
# setup nginx listen ports
configure_nginx_ports "$APP"
local NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
local NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT)
local NONSSL_VHOSTS=$(get_app_domains "$APP")
local NOSSL_SERVER_NAME=$(echo "$NONSSL_VHOSTS" | xargs)
if is_ssl_enabled "$APP"; then
@@ -227,12 +259,13 @@ nginx_build_config() {
SPDY_SUPPORTED="$SPDY_SUPPORTED"
DOKKU_APP_LISTEN_PORT="$DOKKU_APP_LISTEN_PORT" DOKKU_APP_LISTEN_IP="$DOKKU_APP_LISTEN_IP"
APP_SSL_PATH="$APP_SSL_PATH" SSL_INUSE="$SSL_INUSE" SSL_SERVER_NAME="$SSL_SERVER_NAME"
NGINX_PORT="$NGINX_PORT" NGINX_SSL_PORT="$NGINX_SSL_PORT" RAW_TCP_PORTS="$RAW_TCP_PORTS")
NGINX_PORT="$NGINX_PORT" NGINX_SSL_PORT="$NGINX_SSL_PORT" RAW_TCP_PORTS="$RAW_TCP_PORTS"
PROXY_PORT_MAP="$PROXY_PORT_MAP" PROXY_UPSTREAM_PORTS="$PROXY_UPSTREAM_PORTS")
# execute sigil template processing
xargs -i echo "-----> Configuring {}...(using $NGINX_TEMPLATE_SOURCE template)" <<< "$(echo "${SSL_VHOSTS}" "${NONSSL_VHOSTS}" | tr ' ' '\n' | sort -u)"
# echo "sigil ${SIGIL_PARAMS[@]}"
sigil "${SIGIL_PARAMS[@]}" > "$NGINX_CONF"
sigil "${SIGIL_PARAMS[@]}" | cat -s > "$NGINX_CONF"
if is_deployed "$APP"; then
dokku_log_info1 "Creating $SCHEME nginx.conf"

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_post_certs_remove() {
declare desc="unset port config vars after SSL cert is removed"
local trigger="nginx_post_certs_remove"
local APP="$1"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT DOKKU_PROXY_PORT_MAP
fi
}
nginx_post_certs_remove "$@"

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_post_certs_update() {
declare desc="unset port config vars after SSL cert is added"
local trigger="nginx_post_certs_update"
local APP="$1"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
local DOKKU_NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT)
local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
if [[ "$DOKKU_NGINX_PORT" == "80" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_PORT
fi
if [[ "$DOKKU_NGINX_SSL_PORT" == "443" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_SSL_PORT
fi
if [[ "$DOKKU_PROXY_PORT_MAP" == *http:80:* ]]; then
config_unset --no-restart "$APP" DOKKU_PROXY_PORT_MAP
fi
fi
}
nginx_post_certs_update "$@"

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_post_proxy_ports_update() {
declare desc="calls nginx build_config when domains are updated"
local trigger="nginx_post_proxy_ports_update"
local APP="$1" ACTION="$2"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
nginx_build_config "$APP"
fi
}
nginx_post_proxy_ports_update "$@"

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_pre_disable_vhost_trigger() {
declare desc="unset port prior to vhosts being disabled"
local trigger="nginx_pre_disable_vhost_trigger"
local APP="$1"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT DOKKU_PROXY_PORT_MAP
fi
}
nginx_pre_disable_vhost_trigger "$@"

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_pre_enable_vhost_trigger() {
declare desc="unset port prior to vhosts being enabled"
local trigger="nginx_pre_enable_vhost_trigger"
local APP="$1"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
config_unset --no-restart "$APP" DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT DOKKU_PROXY_PORT_MAP
fi
}
nginx_pre_enable_vhost_trigger "$@"

View File

@@ -1,20 +0,0 @@
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;

View File

@@ -1,2 +0,0 @@
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;

View File

@@ -1,10 +1,87 @@
{{ if .RAW_TCP_PORTS }}
{{ include "tcp.server.config" . }}
{{ else if .SSL_INUSE }}
{{ include "nossl.server.config" . }}
{{ include "ssl.server.config" . }}
{{ include "upstream.config" . }}
{{ range $port_map := .PROXY_PORT_MAP | split " " }}
{{ $port_map_list := $port_map | split ":" }}
{{ $scheme := index $port_map_list 0 }}
{{ $listen_port := index $port_map_list 1 }}
{{ $upstream_port := index $port_map_list 2 }}
{{ if eq $scheme "http" }}
server {
listen [::]:{{ $listen_port }};
listen {{ $listen_port }};
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log /var/log/nginx/{{ $.APP }}-access.log;
error_log /var/log/nginx/{{ $.APP }}-error.log;
{{ if $.SSL_INUSE }}
{{ if eq $listen_port "80" }}
return 301 https://$host:{{ $.NGINX_SSL_PORT }}$request_uri;
{{ else }}
{{ include "nossl.server.config" . }}
{{ include "upstream.config" . }}
{{ end }}
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://{{ $.APP }}-{{ $upstream_port }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
{{ end }}{{ end }}
}
{{ else if eq $scheme "https"}}
server {
listen [::]:{{ $listen_port }} ssl {{ if eq .SPDY_SUPPORTED "true" }}spdy{{ else }}http2{{ end }};
listen {{ $listen_port }} ssl {{ if eq .SPDY_SUPPORTED "true" }}spdy{{ else }}http2{{ end }};
{{ if $.SSL_SERVER_NAME }}server_name {{ $.SSL_SERVER_NAME }}; {{ end }}
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log /var/log/nginx/{{ $.APP }}-access.log;
error_log /var/log/nginx/{{ $.APP }}-error.log;
ssl_certificate {{ $.APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key;
keepalive_timeout 70;
{{ if eq .SPDY_SUPPORTED "true" }}add_header Alternate-Protocol {{ .NGINX_SSL_PORT }}:npn-spdy/2;{{ end }}
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://{{ $.APP }}-{{ $upstream_port }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
}
{{ end }}{{ end }}
{{ if $.DOKKU_APP_LISTENERS }}
{{ range $upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
upstream {{ $.APP }}-{{ $upstream_port }} {
{{ range $listeners := $.DOKKU_APP_LISTENERS | split " " }}
{{ $listener_list := $listeners | split ":" }}
{{ $listener_ip := index $listener_list 0 }}
{{ $listener_port := index $listener_list 1 }}
server {{ $listener_ip }}:{{ $upstream_port }};{{ end }}
}
{{ end }}{{ end }}

View File

@@ -1,11 +0,0 @@
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
{{ if .NOSSL_SERVER_NAME }}server_name {{ .NOSSL_SERVER_NAME }}; {{ end }}
{{ include "log.config" . }}
{{ if .SSL_INUSE }}
return 301 https://$host:{{ .NGINX_SSL_PORT }}$request_uri;
{{ else }}
{{ include "location.config" . }}
{{ end }}
}

View File

@@ -1,13 +0,0 @@
server {
listen [::]:{{ .NGINX_SSL_PORT }} ssl {{ if eq .SPDY_SUPPORTED "true" }}spdy{{ else }}http2{{ end }};
listen {{ .NGINX_SSL_PORT }} ssl {{ if eq .SPDY_SUPPORTED "true" }}spdy{{ else }}http2{{ end }};
{{ if .SSL_SERVER_NAME }}server_name {{ .SSL_SERVER_NAME }}; {{ end }}
{{ if .NOSSL_SERVER_NAME }}server_name {{ .NOSSL_SERVER_NAME }}; {{ end }}
{{ include "log.config" . }}
ssl_certificate {{ .APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ .APP_SSL_PATH }}/server.key;
keepalive_timeout 70;
{{ if eq .SPDY_SUPPORTED "true" }}add_header Alternate-Protocol {{ .NGINX_SSL_PORT }}:npn-spdy/2;{{ end }}
{{ include "location.config" . }}
}

View File

@@ -1,35 +0,0 @@
{{ range .RAW_TCP_PORTS | split " " }}
{{ $port := . }}
server {
listen [::]:{{ $port }};
listen {{ $port }};
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log /var/log/nginx/{{ $.APP }}-access.log;
error_log /var/log/nginx/{{ $.APP }}-error.log;
location / {
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_comp_level 6;
proxy_pass http://{{ $.APP }}-{{ $port }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
}
{{ if $.DOKKU_APP_LISTENERS }}
upstream {{ $.APP }}-{{ $port }} {
{{ range $.DOKKU_APP_LISTENERS | split " " }} server {{ . }}:{{ $port }};{{ end }}
}
{{ end }}{{ end }}

View File

@@ -1,9 +0,0 @@
{{ if .DOKKU_APP_LISTENERS }}
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }} server {{ . }};
{{ end }}}
{{ else if .PASSED_LISTEN_IP_PORT }}
upstream {{ .APP }} {
server {{ .DOKKU_APP_LISTEN_IP }}:{{ .DOKKU_APP_LISTEN_PORT }};
}
{{ end }}

View File

@@ -7,10 +7,14 @@ case "$1" in
help_content_func () {
declare desc="return proxy plugin help content"
cat<<help_content
proxy <app>, Show proxy for app
proxy <app>, Show proxy settings for app
proxy:enable <app>, Enable proxy for app
proxy:disable <app>, Disable proxy for app
proxy:set <app> <proxy_type>, NOT IMPLEMENTED YET!!
proxy:ports <app>, List proxy port mappings for app
proxy:ports-clear <app>, Clear all proxy port mappings for app
proxy:ports-add <app> <scheme>:<host-port>:<container-port> [<scheme>:<host-port>:<container-port>...], Set proxy port mappings for app
proxy:ports-remove <app> <host-port> [<host-port>...], Unset proxy port mappings for app
proxy:set <app> <proxy-type>, Set proxy type for app
help_content
}

View File

@@ -18,7 +18,8 @@ is_app_proxy_enabled() {
get_app_proxy_type() {
declare desc="return app proxy type"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_TYPE="nginx"
local DOKKU_APP_PROXY_TYPE="$(config_get "$APP" DOKKU_APP_PROXY_TYPE || true)"
local APP_PROXY_TYPE="${DOKKU_APP_PROXY_TYPE:-nginx}"
echo $APP_PROXY_TYPE
echo "$APP_PROXY_TYPE"
}

24
plugins/proxy/subcommands/ports Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
proxy_ports_cmd() {
declare desc="list proxy port mappings for an app"
local cmd="proxy:ports"
local APP="$2"; verify_app_name "$APP"
local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)"
if [[ -n "$PROXY_PORT_MAP" ]]; then
dokku_log_info1_quiet "Port mappings for $APP"
dokku_col_log_info1_quiet "scheme" "host port" "container port"
local port_map
for port_map in $PROXY_PORT_MAP; do
dokku_col_log_msg "$(cut -d ':' -f1 <<< "$port_map")" "$(cut -d ':' -f2 <<< "$port_map")" "$(cut -d ':' -f3 <<< "$port_map")"
done
else
dokku_log_fail "No port mappings configured for app ($APP)"
fi
}
proxy_ports_cmd "$@"

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
proxy_ports_add_cmd() {
declare desc="add proxy port mappings from an app"
local cmd="proxy:add"
local APP="$2"; verify_app_name "$APP"
local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)"
shift 2
local INPUT_PORTS="$*"
if [[ -n "$INPUT_PORTS" ]]; then
PROXY_PORT_MAP="$(merge_dedupe_list "$PROXY_PORT_MAP $INPUT_PORTS" " ")"
config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP"
else
dokku proxy:help
dokku_log_fail "No port mapping specified. Exiting..."
fi
plugn trigger post-proxy-ports-update "$APP" "add"
}
proxy_ports_add_cmd "$@"

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
proxy_ports_clear_cmd() {
declare desc="clear all proxy port mappings for an app"
local cmd="proxy:clear"
local APP="$2"; verify_app_name "$APP"
config_unset --no-restart "$APP" DOKKU_PROXY_PORT_MAP
plugn trigger post-proxy-ports-update "$APP" "clear"
}
proxy_ports_clear_cmd "$@"

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
proxy_ports_remove_cmd() {
declare desc="remove specific proxy port mappings from an app"
local cmd="proxy:ports-remove"
local APP="$2"; verify_app_name "$APP"
local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)"
shift 2
local INPUT_PORTS="$*"
if [[ -n "$INPUT_PORTS" ]]; then
local port
for port in $INPUT_PORTS; do
PROXY_PORT_MAP="$(sed -r "s/[[:alnum:]]+:$port:[[:alnum:]]+//g" <<< "$PROXY_PORT_MAP")"
done
PROXY_PORT_MAP="$(echo "$PROXY_PORT_MAP" | xargs)"
PROXY_PORT_MAP="$(merge_dedupe_list "$PROXY_PORT_MAP" " ")"
if [[ -n "$PROXY_PORT_MAP" ]]; then
config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP"
else
config_unset --no-restart "$APP" DOKKU_PROXY_PORT_MAP
fi
plugn trigger post-proxy-ports-update "$APP" "remove"
else
dokku_log_warn "No port mapping specified. Please supply a valid configured host port"
dokku proxy:ports "$APP"
dokku_log_fail "exiting..."
fi
}
proxy_ports_remove_cmd "$@"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
proxy_set_cmd() {
declare desc="enable proxy for app via command line"
@@ -8,7 +9,13 @@ proxy_set_cmd() {
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
local APP="$2"; verify_app_name "$APP"
dokku_log_info1 "proxy:set not implemented"
local PROXY_TYPE="$3"
if [[ -n "$PROXY_TYPE" ]]; then
config_set --no-restart "$APP" DOKKU_APP_PROXY_TYPE="$PROXY_TYPE"
else
dokku_log_fail "Please specify a proxy type!"
fi
}
proxy_set_cmd "$@"

View File

@@ -21,8 +21,10 @@ teardown() {
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
NGINX_PORT="$(config_get $TEST_APP DOKKU_NGINX_PORT)"
assert_http_success http://${HOSTNAME}:${NGINX_PORT}
URLS=$(dokku --quiet urls "$TEST_APP")
for URL in $URLS; do
assert_http_success $URL
done
dokku domains:enable $TEST_APP
check_urls http://${TEST_APP}.dokku.me
@@ -59,8 +61,10 @@ teardown() {
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
NGINX_PORT="$(config_get $TEST_APP DOKKU_NGINX_PORT)"
assert_http_success http://${HOSTNAME}:${NGINX_PORT}
URLS=$(dokku --quiet urls "$TEST_APP")
for URL in $URLS; do
assert_http_success $URL
done
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST and IPv4 address set as HOSTNAME)" {
@@ -71,8 +75,10 @@ teardown() {
HOSTNAME=$(< "$DOKKU_ROOT/HOSTNAME")
check_urls http://${HOSTNAME}:[0-9]+
NGINX_PORT="$(config_get $TEST_APP DOKKU_NGINX_PORT)"
assert_http_success http://${HOSTNAME}:${NGINX_PORT}
URLS=$(dokku --quiet urls "$TEST_APP")
for URL in $URLS; do
assert_http_success $URL
done
}
@test "(nginx-vhosts) nginx:build-config (without global VHOST and IPv6 address set as HOSTNAME)" {
@@ -101,11 +107,11 @@ teardown() {
}
@test "(nginx-vhosts) nginx:build-config (xip.io style hostnames)" {
echo "127.0.0.1.xip.io" > "$DOKKU_ROOT/VHOST"
echo "127.0.0.1.xip.io.dokku.me" > "$DOKKU_ROOT/VHOST"
deploy_app
check_urls http://${TEST_APP}.127.0.0.1.xip.io
assert_http_success http://${TEST_APP}.127.0.0.1.xip.io
check_urls http://${TEST_APP}.127.0.0.1.xip.io.dokku.me
assert_http_success http://${TEST_APP}.127.0.0.1.xip.io.dokku.me
}
@test "(nginx-vhosts) nginx:build-config (dockerfile expose)" {

View File

@@ -91,7 +91,7 @@ assert_error_log() {
assert_http_success "https://${CUSTOM_TEMPLATE_SSL_DOMAIN}"
}
@test "(nginx-vhosts) nginx:build-config (custom nginx template - default path)" {
@test "(nginx-vhosts) nginx:build-config (custom nginx template - no ssl)" {
add_domain "www.test.app.dokku.me"
deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_nginx_template
assert_nonssl_domain "www.test.app.dokku.me"

View File

@@ -240,24 +240,31 @@ custom_ssl_nginx_template() {
echo "injecting custom_ssl_nginx_template -> $APP_REPO_DIR/nginx.conf.sigil"
cat<<EOF > "$APP_REPO_DIR/nginx.conf.sigil"
{{ range \$port_map := .PROXY_PORT_MAP | split " " }}
{{ \$port_map_list := \$port_map | split ":" }}
{{ \$scheme := index \$port_map_list 0 }}
{{ \$listen_port := index \$port_map_list 1 }}
{{ \$upstream_port := index \$port_map_list 2 }}
{{ if eq \$scheme "http" }}
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }} $CUSTOM_TEMPLATE_SSL_DOMAIN;
return 301 https://\$host:{{ .NGINX_SSL_PORT }}\$request_uri;
listen [::]:{{ \$listen_port }};
listen {{ \$listen_port }};
server_name {{ $.NOSSL_SERVER_NAME }} $CUSTOM_TEMPLATE_SSL_DOMAIN;
return 301 https://\$host:{{ $.NGINX_SSL_PORT }}\$request_uri;
}
{{ else if eq \$scheme "https"}}
server {
listen [::]:{{ .NGINX_SSL_PORT }} ssl spdy;
listen {{ .NGINX_SSL_PORT }} ssl spdy;
server_name \$SSL_SERVER_NAME $CUSTOM_TEMPLATE_SSL_DOMAIN;
ssl_certificate {{ .APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ .APP_SSL_PATH }}/server.key;
listen [::]:{{ $.NGINX_SSL_PORT }} ssl spdy;
listen {{ $.NGINX_SSL_PORT }} ssl spdy;
{{ if $.SSL_SERVER_NAME }}server_name {{ $.SSL_SERVER_NAME }} $CUSTOM_TEMPLATE_SSL_DOMAIN; {{ end }}
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }} $CUSTOM_TEMPLATE_SSL_DOMAIN; {{ end }}
ssl_certificate {{ $.APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key;
keepalive_timeout 70;
add_header Alternate-Protocol {{ .NGINX_SSL_PORT }}:npn-spdy/2;
add_header Alternate-Protocol {{ \$listen_port }}:npn-spdy/2;
location / {
proxy_pass http://{{ .APP }};
proxy_pass http://{{ $.APP }}-{{ \$upstream_port }};
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
@@ -267,18 +274,22 @@ server {
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
}
{{ if .DOKKU_APP_LISTENERS }}
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }} server {{ . }};
{{ end }}}
{{ else if .PASSED_LISTEN_IP_PORT }}
upstream {{ .APP }} {
server {{ .DOKKU_APP_LISTEN_IP }}:{{ .DOKKU_APP_LISTEN_PORT }};
{{ end }}{{ end }}
{{ if $.DOKKU_APP_LISTENERS }}
{{ range \$upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
upstream {{ $.APP }}-{{ \$upstream_port }} {
{{ range \$listeners := $.DOKKU_APP_LISTENERS | split " " }}
{{ \$listener_list := \$listeners | split ":" }}
{{ \$listener_ip := index \$listener_list 0 }}
{{ \$listener_port := index \$listener_list 1 }}
server {{ \$listener_ip }}:{{ \$upstream_port }};{{ end }}
}
{{ end }}
{{ end }}{{ end }}
EOF
cat "$APP_REPO_DIR/nginx.conf.sigil"
}
custom_nginx_template() {
@@ -288,13 +299,19 @@ custom_nginx_template() {
echo "injecting custom_nginx_template -> $APP_REPO_DIR/nginx.conf.sigil"
cat<<EOF > "$APP_REPO_DIR/nginx.conf.sigil"
{{ range \$port_map := .PROXY_PORT_MAP | split " " }}
{{ \$port_map_list := \$port_map | split ":" }}
{{ \$scheme := index \$port_map_list 0 }}
{{ \$listen_port := index \$port_map_list 1 }}
{{ \$upstream_port := index \$port_map_list 2 }}
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }} customtemplate.dokku.me;
listen [::]:{{ \$listen_port }};
listen {{ \$listen_port }};
server_name {{ $.NOSSL_SERVER_NAME }} customtemplate.dokku.me;
location / {
proxy_pass http://{{ .APP }};
proxy_pass http://{{ $.APP }}-{{ \$upstream_port }};
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
@@ -304,18 +321,22 @@ server {
proxy_set_header X-Forwarded-Port \$server_port;
proxy_set_header X-Request-Start \$msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
}
{{ if .DOKKU_APP_LISTENERS }}
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }} server {{ . }};
{{ end }}}
{{ else if .PASSED_LISTEN_IP_PORT }}
upstream {{ .APP }} {
server {{ .DOKKU_APP_LISTEN_IP }}:{{ .DOKKU_APP_LISTEN_PORT }};
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
}
{{ end }}
{{ if $.DOKKU_APP_LISTENERS }}
{{ range \$upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
upstream {{ $.APP }}-{{ \$upstream_port }} {
{{ range \$listeners := $.DOKKU_APP_LISTENERS | split " " }}
{{ \$listener_list := \$listeners | split ":" }}
{{ \$listener_ip := index \$listener_list 0 }}
{{ \$listener_port := index \$listener_list 1 }}
server {{ \$listener_ip }}:{{ \$upstream_port }};{{ end }}
}
{{ end }}{{ end }}
EOF
cat "$APP_REPO_DIR/nginx.conf.sigil"
}
bad_custom_nginx_template() {