Merge pull request #2248 from dokku/2239_mh-proxy-ports

proxy port mapping
This commit is contained in:
Michael Hobbs
2016-06-16 19:48:45 -07:00
committed by GitHub
41 changed files with 680 additions and 220 deletions

View File

@@ -7,3 +7,7 @@
- `DOKKU_CHECKS_DISABLED` is now a thing
- The values for the above can be a comma-separated list of process-types or the literal string `_all_`
- See the [updated `checks`](/dokku/checks-examples/) docs for more info
## proxy port mapping
- You can now configure host -> container proxy port mappings
- The UI is handled by the [proxy](/dokku/proxy/) interface plugin by setting the `DOKKU_PROXY_PORT_MAP` config variable in the format of `scheme:host-port:container-port`. The default `nginx-vhosts` proxy plugin supports both the `http` and `https` schemes.

View File

@@ -400,6 +400,26 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
sudo service haproxy reload
```
### `post-proxy-ports-update`
- Description: Allows you to run commands once the proxy port mappings for an application have been updated. It also sends the invoking command. This can be "add", "clear" or "remove".
- Invoked by: `dokku proxy:ports-add`, `dokku proxy:ports-clear`, `dokku proxy:ports-remove`
- Arguments: `$APP` `action name`
- Example:
```shell
#!/usr/bin/env bash
# Rebuilds haproxy config for our imaginary haproxy plugin
# that replaces the nginx-vhosts plugin
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/haproxy/functions"
APP="$1"; verify_app_name "$APP"
haproxy-build-config "$APP"
```
### `post-release-buildpack`
- Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to applications using buildpacks.
@@ -602,6 +622,74 @@ verify_app_name "$APP"
# TODO
```
### `pre-disable-vhost`
- Description: Allows you to run commands before the VHOST feature is disabled
- Invoked by: `dokku domains:disable`
- Arguments: `$APP`
- Example:
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"
# TODO
```
### `pre-enable-vhost`
- Description: Allows you to run commands before the VHOST feature is enabled
- Invoked by: `dokku domains:enable`
- Arguments: `$APP`
- Example:
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"
# TODO
```
### `post-certs-update`
- Description: Allows you to run commands after a cert is added/updated
- Invoked by: `dokku certs:add`, `dokku certs:update`
- Arguments: `$APP`
- Example:
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"
# TODO
```
### `post-certs-remove`
- Description: Allows you to run commands after a cert is removed
- Invoked by: `dokku certs:remove`
- Arguments: `$APP`
- Example:
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"
# TODO
```
### `receive-app`
- Description: Allows you to customize what occurs when an app is received. Normally just triggers an application build.

View File

@@ -72,6 +72,8 @@ 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)
{{ .PROXY_UPSTREAM_PORTS }} List of configured upstream ports (derived from `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
@@ -127,6 +129,54 @@ upstream {{ .APP }} {
}
```
### Example using new proxy port mapping
```
{{ 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 [::]:{{ $listen_port }};
listen {{ $listen_port }};
server_name {{ $.NOSSL_SERVER_NAME }};
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 }}-{{ $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;
}
{{ 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 }}
```
### Customizing via configuration files included by the default templates
The default nginx.conf template will include everything from your apps `nginx.conf.d/` subdirectory in the main `server {}` block (see above):

View File

@@ -5,9 +5,14 @@
As of dokku 0.5.0, the proxy functionality has been decoupled from the nginx-vhosts plugin into the proxy plugin. In the future this will allow other proxy software (HAproxy for example) to be used instead of nginx.
```
proxy:disable <app> Disable proxy for app
proxy:enable <app> Enable proxy for app
proxy:set <app> <proxy_type> NOT IMPLEMENTED YET!!
proxy <app> Show proxy settings for app
proxy:disable <app> Disable proxy for app
proxy:enable <app> Enable proxy for app
proxy:ports <app> List 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-clear <app> Clear all 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
```
## Container network interface binding

View File

@@ -102,7 +102,7 @@ dokku_deploy_cmd() {
kill -9 $$
}
# run checks first, then post-deploy hooks, which switches Nginx traffic
# run checks first, then post-deploy hooks, which switches proxy traffic
trap 'kill_new $id' INT TERM EXIT
if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "false" ]]; then
dokku_log_info1 "Attempting pre-flight checks"

View File

@@ -1,10 +1,6 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
dokku_version_cmd() {
declare desc="prints dokku version"

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

@@ -2,7 +2,6 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
is_tar_import() {
declare desc="determines if we have STDIN open in an attempt to detect a streamed tar import"
@@ -70,7 +69,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

@@ -2,7 +2,6 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
certs_generate_cmd() {
declare desc="generates a self-signed SSL certificate/key combo"
@@ -26,7 +25,7 @@ certs_generate_cmd() {
mv -f "$CERTS_GENERATE_TMP_WORK_DIR/server.key" "$CERTS_GENERATE_TMP_WORK_DIR/server.crt" "$APP_SSL_PATH"
chmod 750 "$APP_SSL_PATH"
chmod 640 "$APP_SSL_PATH/server.key" "$APP_SSL_PATH/server.crt"
[[ -n "$DOMAIN" ]] && (domains_add "$APP" "$DOMAIN" || nginx_build_config "$APP")
[[ -n "$DOMAIN" ]] && (domains_add "$APP" "$DOMAIN" || plugn trigger post-domains-update "$APP")
dokku_log_info1 "The following is a certificate signing request that can be used"
dokku_log_info1 "to generate an 'officially' signed SSL certificate for $APP at $DOMAIN"
dokku_log_info1 "by a CA of your choosing."

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")"
local UPSTREAM_PORT="5000"
if [[ -z "$DOKKU_NGINX_PORT" ]]; then
if [[ -z "$RAW_TCP_PORTS" ]]; then
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
config_set --no-restart "$APP" DOKKU_NGINX_PORT="$NGINX_PORT"
fi
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 port set. setting to random open high port"
local NGINX_PORT=$(get_available_port)
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
local NGINX_SSL_PORT=$(get_available_port)
else
local NGINX_PORT=80
local NGINX_SSL_PORT=443
fi
fi
if [[ -n "$NGINX_PORT" ]]; then
config_set --no-restart "$APP" DOKKU_NGINX_PORT="${NGINX_PORT}"
fi
config_set --no-restart "$APP" DOKKU_NGINX_SSL_PORT="$NGINX_SSL_PORT"
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)
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_SSL_PORT=443
local NGINX_PORT=${NGINX_PORT:-$DOKKU_NGINX_PORT}
local NGINX_SSL_PORT=${NGINX_SSL_PORT:-$DOKKU_NGINX_SSL_PORT}
[[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]] && local UPSTREAM_PORT="$(< "$DOKKU_ROOT/$APP/PORT.web.1")"
if [[ -n "$NGINX_PORT" ]] && [[ -n "$NGINX_SSL_PORT" ]]; then
local PROXY_PORT_MAP+=" http:${NGINX_PORT}:$UPSTREAM_PORT https:${NGINX_SSL_PORT}:$UPSTREAM_PORT "
elif [[ -n "$NGINX_PORT" ]]; then
local PROXY_PORT_MAP+=" http:${NGINX_PORT}:$UPSTREAM_PORT "
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,86 @@
{{ 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 (and (eq $listen_port "80") ($.SSL_INUSE)) }}
return 301 https://$host:{{ $.NGINX_SSL_PORT }}$request_uri;
{{ else }}
{{ include "nossl.server.config" . }}
{{ include "upstream.config" . }}
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 }}
}
{{ 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,25 @@ 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"
}
list_app_proxy_ports() {
declare desc="list proxy port mappings for an app"
local APP="$1"; 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
}

15
plugins/proxy/subcommands/ports Executable file
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_CORE_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
proxy_ports_cmd() {
declare desc="cmd wrapper to list proxy port mappings for an app"
local cmd="proxy:ports"
local APP="$2"; verify_app_name "$APP"
list_app_proxy_ports "$APP"
}
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,35 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/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"
list_app_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

@@ -57,20 +57,20 @@ build_nginx_config() {
setup_test_tls
assert_urls "https://dokku.me"
build_nginx_config
assert_urls "https://${TEST_APP}.dokku.me"
assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me"
add_domain "test.dokku.me"
assert_urls "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
assert_urls "http://test.dokku.me" "http://${TEST_APP}.dokku.me" "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
}
@test "(core) urls (wildcard ssl)" {
setup_test_tls wildcard
assert_urls "https://dokku.me"
build_nginx_config
assert_urls "https://${TEST_APP}.dokku.me"
assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me"
add_domain "test.dokku.me"
assert_urls "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
assert_urls "http://test.dokku.me" "http://${TEST_APP}.dokku.me" "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
add_domain "dokku.example.com"
assert_urls "https://dokku.example.com" "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
assert_urls "http://dokku.example.com" "http://test.dokku.me" "http://${TEST_APP}.dokku.me" "https://dokku.example.com" "https://test.dokku.me" "https://${TEST_APP}.dokku.me"
}
@test "(core) git-remote (off-port)" {

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

@@ -62,3 +62,50 @@ assert_external_port() {
assert_external_port $(< $CID_FILE) failure
done
}
@test "(proxy) proxy:ports (list/add/remove/clear)" {
run dokku proxy:ports-add $TEST_APP http:8080:5000 https:8443:5000
echo "output: "$output
echo "status: "$status
assert_success
run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
echo "output: "$output
echo "status: "$status
assert_output "http 8080 5000 https 8443 5000"
run /bin/bash -c "dokku proxy:ports-remove $TEST_APP 8080"
echo "output: "$output
echo "status: "$status
assert_success
run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
echo "output: "$output
echo "status: "$status
assert_output "https 8443 5000"
run /bin/bash -c "dokku proxy:ports-clear $TEST_APP"
echo "output: "$output
echo "status: "$status
assert_success
run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs"
echo "output: "$output
echo "status: "$status
assert_output "http 80 5000"
}
@test "(proxy) proxy:ports (post-deploy add)" {
deploy_app
run dokku proxy:ports-add $TEST_APP http:8080:5000 http:8081:5000
echo "output: "$output
echo "status: "$status
assert_success
URLS="$(dokku --quiet urls "$TEST_APP")"
for URL in $URLS; do
assert_http_success $URL
done
assert_http_success "http://$TEST_APP.dokku.me:8080"
assert_http_success "http://$TEST_APP.dokku.me:8081"
}

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() {