nginx-vhosts rewrite

This commit is contained in:
Michael Hobbs
2016-02-14 18:43:40 -08:00
parent 4404e145c0
commit 9842d7498b
65 changed files with 1779 additions and 1123 deletions

View File

@@ -4,6 +4,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
case "$1" in
build)
@@ -35,8 +36,8 @@ case "$1" in
dockerfile)
# extract first port from Dockerfile
DOCKERFILE_PORT=$(get_dockerfile_exposed_port Dockerfile)
[[ -n "$DOCKERFILE_PORT" ]] && config_set --no-restart $APP DOKKU_DOCKERFILE_PORT=$DOCKERFILE_PORT
DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile)
[[ -n "$DOCKERFILE_PORTS" ]] && config_set --no-restart $APP DOKKU_DOCKERFILE_PORTS="$DOCKERFILE_PORTS"
plugn trigger pre-build-dockerfile "$APP"
[[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"
@@ -151,46 +152,7 @@ case "$1" in
url | urls)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$2"
eval "$(config_export app $APP)"
if [[ -s "$DOKKU_ROOT/$APP/URLS" ]]; then
case "$1" in
url)
grep "^http" "$DOKKU_ROOT/$APP/URLS" | head -1
;;
urls)
grep "^http" "$DOKKU_ROOT/$APP/URLS"
;;
esac
exit 0
fi
SCHEME="http"; SSL="$DOKKU_ROOT/$APP/tls"; WILDCARD_SSL="$DOKKU_ROOT/tls"
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]] || [[ -e "$WILDCARD_SSL/server.crt" && -e "$WILDCARD_SSL/server.key" ]]; then
SCHEME="https"
fi
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
shopt -s nullglob
for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
done
shopt -u nullglob
DOKKU_NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT || true)
DOKKU_NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT || true)
if [[ -n "$DOKKU_NGINX_PORT" ]]; then
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_PORT (nginx)"
fi
if [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
echo "https://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_SSL_PORT (nginx-ssl)"
fi
else
echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
fi
get_app_urls "$@"
;;
report)
@@ -201,6 +163,7 @@ case "$1" in
docker version
dokku_log_info1 "docker daemon info: "
docker -D info
dokku_log_info1 "sigil version: $(sigil -v)"
dokku_log_info1 "herokuish version: "
docker run --rm -ti gliderlabs/herokuish:latest herokuish version
dokku_log_info1 "dokku version: $(dokku version)"

View File

@@ -57,3 +57,5 @@ if [ ! -f "/home/dokku/HOSTNAME" ]; then
fi
EOF
chmod +x /etc/update-motd.d/99-dokku
chown dokku:dokku "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/VHOST"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core standard plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -7,13 +7,8 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
is_ssl_enabled() {
local APP=$1; verify_app_name $APP
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
if [[ -e "$APP_SSL_PATH/server.crt" ]] && [[ -e "$APP_SSL_PATH/server.key" ]]; then
echo app
return 0
elif [[ -e "$WILDCARD_SSL_PATH/server.crt" ]] && [[ -e "$WILDCARD_SSL_PATH/server.key" ]]; then
echo global
return 0
else
return 1
@@ -22,22 +17,14 @@ is_ssl_enabled() {
get_ssl_hostnames() {
local APP=$1; verify_app_name $APP
case "$(is_ssl_enabled $APP)" in
app)
SSL_PATH="$DOKKU_ROOT/$APP/tls"
;;
local SSL_PATH="$DOKKU_ROOT/$APP/tls"
global)
SSL_PATH="$DOKKU_ROOT/tls"
;;
esac
SSL_HOSTNAME=$(openssl x509 -in $SSL_PATH/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
SSL_HOSTNAME_ALT=$(openssl x509 -in $SSL_PATH/server.crt -noout -text | grep --after-context=1 '509v3 Subject Alternative Name:' | tail -n 1 | sed -e "s/[[:space:]]*DNS://g" | tr ',' '\n' || true)
local SSL_HOSTNAME=$(openssl x509 -in $SSL_PATH/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
local SSL_HOSTNAME_ALT=$(openssl x509 -in $SSL_PATH/server.crt -noout -text | grep --after-context=1 '509v3 Subject Alternative Name:' | tail -n 1 | sed -e "s/[[:space:]]*DNS://g" | tr ',' '\n' || true)
if [[ -n "$SSL_HOSTNAME_ALT" ]]; then
SSL_HOSTNAMES="${SSL_HOSTNAME}\n${SSL_HOSTNAME_ALT}"
local SSL_HOSTNAMES="${SSL_HOSTNAME}\n${SSL_HOSTNAME_ALT}"
else
SSL_HOSTNAMES=$SSL_HOSTNAME
local SSL_HOSTNAMES=$SSL_HOSTNAME
fi
echo -e $SSL_HOSTNAMES
return 0

View File

@@ -36,6 +36,7 @@
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"
APP="$1"; DOKKU_APP_CONTAINER_ID="$2"; DOKKU_APP_CONTAINER_TYPE="$3"; DOKKU_APP_LISTEN_PORT="$4"; DOKKU_APP_LISTEN_IP="$5"
@@ -55,6 +56,11 @@ fi
eval "$(config_export global)"
eval "$(config_export app $APP)"
if [[ "$(is_app_checks_enabled $APP)" == "false" ]];then
dokku_log_info2_quiet "Zero downtime checks for app ($APP) have been disabled. moving on..."
exit 0
fi
# Wait this many seconds (default 5) for server to start before running checks.
WAIT="${DOKKU_CHECKS_WAIT:-5}"
# Wait this many seconds (default 30) for each response.
@@ -80,11 +86,6 @@ cleanup() {
trap cleanup EXIT
if [[ ! -s "${TMPDIR}/CHECKS" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then
if [[ "$DOKKU_SKIP_DEFAULT_CHECKS" = "true" ]]; then
dokku_log_verbose "Skipping default check..."
exit 0
fi
# We allow custom check for web instances only
if [[ "$DOKKU_APP_CONTAINER_TYPE" == "web" ]]; then
dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS."

75
plugins/checks/commands Executable file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
[[ " checks checks:enable checks:disable help ps:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
checks_main() {
local desc="displays app zero-downtime status"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Zero-Downtime Status"
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(is_app_checks_enabled $app)"
done
}
checks_enable() {
local desc="enable zero-downtime for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled $APP)" == "false" ]]; then
dokku_log_info1 "Enabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=1
else
dokku_log_info1 "zero downtime is already enabled for app ($APP)"
fi
}
checks_disable() {
local desc="disable zero-downtime for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled $APP)" == "true" ]]; then
dokku_log_info1 "Disabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=0
else
dokku_log_info1 "zero downtime is already disable for app ($APP)"
fi
}
case "$1" in
checks)
checks_main $2
;;
checks:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
checks_enable $2 --no-restart
;;
checks:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
checks_disable $2 --no-restart
;;
help | ps:help)
cat<<EOF
checks <app>, Show zero-downtime status
checks:enable <app>, Enable zero-downtime checks
checks:disable <app>, Disable zero-downtime checks
EOF
;;
*)
exit $DOKKU_NOT_IMPLEMENTED_EXIT
;;
esac

18
plugins/checks/functions Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
is_app_checks_enabled() {
local desc="return app zero-downtime checks status"
local APP="$1"; verify_app_name "$APP"
local DOKKU_CHECKS_ENABLED=$(config_get $APP DOKKU_CHECKS_ENABLED)
if [[ -z "$DOKKU_CHECKS_ENABLED" ]] || [[ "$DOKKU_CHECKS_ENABLED" == "1" ]];then
local status=true
else
local status=false
fi
echo $status
}

40
plugins/checks/install Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
migrate_checks_vars() {
local APPS="$(dokku_apps)"
local GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true)
local GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true)
local app
dokku_log_info1 "Migrating zero downtime env variables. The following variables have been deprecated"
dokku_log_info2 "DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS"
dokku_log_info2 "Please use dokku checks:[disable|enable] <app> to control zero downtime functionality"
for app in $APPS; do
local APP_SKIP_ALL_CHECKS=$(dokku config:get $app DOKKU_SKIP_ALL_CHECKS || true)
local APP_SKIP_DEFAULT_CHECKS=$(dokku config:get $app DOKKU_SKIP_DEFAULT_CHECKS || true)
if [[ "$APP_SKIP_ALL_CHECKS" == "true" ]] || [[ "$APP_SKIP_DEFAULT_CHECKS" == "true" ]] || \
[[ "$GLOBAL_SKIP_ALL_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_DEFAULT_CHECKS" == "true" ]]; then
dokku_log_info2 ""
dokku_log_info2 "zero downtime disabled for app ($app)"
config_set --no-restart $app DOKKU_CHECKS_ENABLED=0
fi
if [[ -n "$APP_SKIP_ALL_CHECKS" ]] || [[ -n "$APP_SKIP_DEFAULT_CHECKS" ]]; then
config_unset --no-restart $app DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS
fi
dokku_log_info2 "Migration complete"
dokku_log_info2 ""
done
if [[ -n "$GLOBAL_SKIP_ALL_CHECKS" ]] || [[ -n "$GLOBAL_SKIP_DEFAULT_CHECKS" ]]; then
dokku_log_info1 "Removing global zero downtime settings"
config_unset --global DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS
fi
}
migrate_checks_vars "$@"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core checks plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -258,11 +258,6 @@ get_app_container_ids() {
echo $DOKKU_CIDS
}
get_dockerfile_exposed_port() {
local DOCKERFILE_PORT=$(grep "^EXPOSE \+[[:digit:]]\+\(\/tcp\)\? *$" $1 | head -1 | sed 's/EXPOSE \+\([[:digit:]]\+\)\(\/tcp\)\?.*/\1/' || true)
echo "$DOCKERFILE_PORT"
}
get_app_running_container_ids() {
local APP=$1
verify_app_name $APP
@@ -441,3 +436,166 @@ get_ipv6_regex() {
# Fixes using a wildcard dns service such as xip.io which allows for *.<ip address>.xip.io
echo "${RE_IPV6}\$"
}
get_global_vhost() {
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
echo $GLOBAL_VHOST
}
is_global_vhost_enabled() {
local desc="returns true if we have a valid global vhost set; otherwise returns false"
local GLOBAL_VHOST=$(get_global_vhost)
local GLOBAL_VHOST_ENABLED=true
local RE_IPV4="$(get_ipv4_regex)"
local RE_IPV6="$(get_ipv6_regex)"
if [[ -z "$GLOBAL_VHOST" ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
local GLOBAL_VHOST_ENABLED=false
fi
echo $GLOBAL_VHOST_ENABLED
}
is_app_vhost_enabled() {
local desc="returns true or false if vhost support is enabled for a given application"
local APP=$1; verify_app_name $APP
local NO_VHOST=$(config_get $APP NO_VHOST)
local APP_VHOST_ENABLED=true
if [[ "$NO_VHOST" == "1" ]]; then
local APP_VHOST_ENABLED=false
fi
echo $APP_VHOST_ENABLED
}
disable_app_vhost() {
local desc="disable vhost support for given application"
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)
if [[ -f "$APP_VHOST_FILE" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/VHOST"
rm "$APP_VHOST_FILE"
fi
if [[ -f "$APP_URLS_FILE" ]]; then
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
config_set $CONFIG_SET_ARGS $APP NO_VHOST=1
}
enable_app_vhost() {
local desc="enable vhost support for given application"
local APP=$1; verify_app_name $APP
config_unset --no-restart $APP DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP NO_VHOST=0
}
get_dockerfile_exposed_ports() {
local DOCKERFILE_PORTS=$(egrep "^EXPOSE " $1 | awk '{ print $2 }' | xargs) || true
echo "$DOCKERFILE_PORTS"
}
get_app_raw_tcp_ports() {
local APP="$1"; verify_app_name "$APP"
local DOCKERFILE_PORTS="$(config_get $APP DOKKU_DOCKERFILE_PORTS)"
for p in $DOCKERFILE_PORTS; do
if [[ ! "$p" =~ .*udp.* ]]; then
p=${p//\/tcp}
raw_tcp_ports+="$p "
fi
done
raw_tcp_ports="$(echo $raw_tcp_ports| xargs)"
echo "$raw_tcp_ports"
}
get_container_ports() {
local APP="$1"; verify_app_name "$APP"
local APP_CIDS="$(get_app_container_ids $APP)"
local cid
for cid in $APP_CIDS; do
local container_ports="$(docker port $cid | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')"
done
echo $container_ports
}
get_app_urls() {
local APP="$2"; verify_app_name "$APP"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports $APP)"
local URLS_FILE="$DOKKU_ROOT/$APP/URLS"
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 "
done
done
local port_urls="$(echo $port_urls| xargs)"
fi
local URLS=${port_urls:=$app_urls}
case "$1" in
url)
echo "$URLS" | tr ' ' '\n' | head -n1
;;
urls)
echo "$URLS" | tr ' ' '\n'
;;
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
if [[ "$(is_app_proxy_enabled $APP)" == "false" ]]; then
if [[ -n "$RAW_TCP_PORTS" ]]; then
local APP_CONTAINER_PORTS="$(get_container_ports $APP)"
local app_port
for app_port in $APP_CONTAINER_PORTS; do
echo "$(< "$DOKKU_ROOT/HOSTNAME"):$app_port (container)"
done
else
shopt -s nullglob
for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
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 "$RAW_TCP_PORTS" ]]; then
for p in $RAW_TCP_PORTS; do
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$p"
done
else
echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
fi
fi
}

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core common plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -7,16 +7,17 @@ config_export() {
local APP="$2"
local ENV_FILE="$DOKKU_ROOT/$APP/ENV"
[[ $CONFIG_TYPE == "global" ]] && ENV_FILE="$DOKKU_ROOT/ENV"
[[ $CONFIG_TYPE == "global" ]] && local ENV_FILE="$DOKKU_ROOT/ENV"
[[ ! -f $ENV_FILE ]] && return 0
[[ ! -s $ENV_FILE ]] && return 0
VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
local VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
echo "$VARS" | awk '{print "export " $0}'
return 0
}
config_parse_args() {
unset APP ENV_FILE DOKKU_CONFIG_TYPE DOKKU_CONFIG_RESTART
case "$2" in
--global)
ENV_FILE="$DOKKU_ROOT/ENV"
@@ -57,21 +58,21 @@ config_styled_hash () {
local longest=""
while read -r word; do
KEY=$(echo $word | cut -d"=" -f1)
local KEY=$(echo $word | cut -d"=" -f1)
if [[ ${#KEY} -gt ${#longest} ]]; then
longest=$KEY
local longest=$KEY
fi
done <<< "$vars"
while read -r word; do
KEY=$(echo $word | cut -d"=" -f1)
VALUE=$(echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" -e "s/\$$//g")
local KEY=$(echo $word | cut -d"=" -f1)
local VALUE=$(echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" -e "s/\$$//g")
num_zeros=$((${#longest} - ${#KEY}))
zeros=" "
local num_zeros=$((${#longest} - ${#KEY}))
local zeros=" "
while [[ $num_zeros -gt 0 ]]; do
zeros="$zeros "
num_zeros=$((num_zeros - 1))
local zeros="$zeros "
local num_zeros=$((num_zeros - 1))
done
echo "$prefix$KEY:$zeros$VALUE"
done <<< "$vars"
@@ -101,13 +102,14 @@ is_config_export() {
config_all() {
[[ "$1" == "config" ]] || set -- "config" "$@"
config_parse_args "$@"
config_create "$ENV_FILE"
is_config_export "$@" && config_export "$DOKKU_CONFIG_TYPE" "$APP" && return 0
[[ "$APP" ]] && DOKKU_CONFIG_TYPE=$APP
[[ "$APP" ]] && local DOKKU_CONFIG_TYPE=$APP
[[ ! -s $ENV_FILE ]] && dokku_log_fail "no config vars for $DOKKU_CONFIG_TYPE"
VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
local VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-)
for var in "$@"; do
if [[ "$var" == "--shell" ]]; then
@@ -135,7 +137,7 @@ config_get() {
return 0
fi
KEY="$3"
local KEY="$3"
grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | grep "^export $KEY=" | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//"
}
@@ -153,9 +155,9 @@ config_set() {
fi
config_create "$ENV_FILE"
ENV_ADD=""
ENV_TEMP=$(cat "${ENV_FILE}")
RESTART_APP=false
local ENV_ADD=""
local ENV_TEMP=$(cat "${ENV_FILE}")
local RESTART_APP=false
shift 2
for var; do
@@ -168,20 +170,20 @@ config_set() {
done
for var; do
KEY=$(echo ${var} | cut -d"=" -f1)
VALUE=$(echo ${var} | cut -d"=" -f2-)
local KEY=$(echo ${var} | cut -d"=" -f1)
local VALUE=$(echo ${var} | cut -d"=" -f2-)
if [[ $KEY =~ [a-zA-Z_][a-zA-Z0-9_]* ]]; then
RESTART_APP=true
ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $KEY=/ d")
ENV_TEMP="${ENV_TEMP}
local RESTART_APP=true
local ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $KEY=/ d")
local ENV_TEMP="${ENV_TEMP}
export $KEY='$VALUE'"
ENV_ADD=$(echo -e "${ENV_ADD}" | sed "/^$KEY=/ d")
ENV_ADD="${ENV_ADD}$
local ENV_ADD=$(echo -e "${ENV_ADD}" | sed "/^$KEY=/ d")
local ENV_ADD="${ENV_ADD}$
${var}"
fi
done
ENV_ADD=$(echo "$ENV_ADD" | tail -n +2) #remove first empty line
local ENV_ADD=$(echo "$ENV_ADD" | tail -n +2) #remove first empty line
if [[ $RESTART_APP ]]; then
dokku_log_info1 "Setting config vars"
@@ -209,15 +211,14 @@ config_unset() {
fi
config_create "$ENV_FILE"
ENV_TEMP=$(cat "${ENV_FILE}")
VARS="${*:3}"
local ENV_TEMP=$(cat "${ENV_FILE}")
local VARS="${*:3}"
for var in $VARS; do
dokku_log_info1 "Unsetting $var"
ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $var=/ d")
local ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $var=/ d")
config_write "$ENV_TEMP"
[[ "$var" == "NO_VHOST" ]] && config_set --no-restart $APP NO_VHOST=0 && DOKKU_CONFIG_RESTART=true
done
plugn trigger post-config-update $APP "unset" "$@"

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
[[ " domains domains:setup domains:add domains:clear domains:remove help domains:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
[[ " domains domains:setup domains:add domains:clear domains:remove domains:disable domains:enable domains:set-global help domains:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
@@ -7,122 +7,68 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
case "$1" in
domains)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
dokku domains:setup $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi
domains_main "$2"
;;
domains:setup)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"; VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
RE_IPV4="$(get_ipv4_regex)"; RE_IPV6="$(get_ipv6_regex)"
if [[ ! -f $VHOST_PATH ]]; then
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
VHOST=$(< "$DOKKU_ROOT/VHOST")
else
VHOST=$(< "$DOKKU_ROOT/HOSTNAME")
fi
if [[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]]; then
dokku_log_info2 "unsupported vhost config found. disabling vhost support"
disable_app_vhost $APP --no-restart $APP
else
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
dokku_log_info1 "Creating new $VHOST_PATH..."
SUBDOMAIN=${APP/%\.${VHOST}/}
hostname=$(: | plugn trigger nginx-hostname $APP $SUBDOMAIN $VHOST)
if [[ ! -n $hostname ]]; then
if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
hostname="${APP/\//-}"
else
hostname="${APP/\//-}.$VHOST"
fi
fi
echo "$hostname" > $VHOST_PATH
fi
fi
fi
domains_setup "$2"
;;
domains:add)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $APP DOMAIN [DOMAIN ...]"
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
if [[ $(egrep -w "^{$3}$" "$DOKKU_ROOT/$APP/VHOST" > /dev/null 2>&1; echo $?) -eq 0 ]]; then
echo "$3 is already defined for $APP"
exit 1
fi
shift 2
dokku domains:setup $APP
for DOMAIN in "$@"; do
echo "$DOMAIN" >> "$DOKKU_ROOT/$APP/VHOST"
done
plugn trigger post-domains-update $APP "add" "$@"
for DOMAIN in "$@"; do
dokku_log_info1 "Added $DOMAIN to $APP"
done
shift 1
domains_add "$@"
;;
domains:clear)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
rm -f "$DOKKU_ROOT/$APP/VHOST"
dokku domains:setup $APP
plugn trigger post-domains-update $APP "clear"
dokku_log_info1 "Cleared domains in $APP"
domains_clear "$2"
;;
domains:remove)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $APP DOMAIN [DOMAIN ...]"
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
shift 2
dokku domains:setup $APP
for DOMAIN in "$@"; do
sed -i "/^$DOMAIN$/d" "$DOKKU_ROOT/$APP/VHOST"
done
plugn trigger post-domains-update $APP "remove" "$@"
for DOMAIN in "$@"; do
dokku_log_info1 "Removed $DOMAIN from $APP"
done
shift 1
domains_remove "$@"
;;
domains:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_disable "$2"
;;
domains:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_enable "$2"
;;
domains:set-global)
[[ -z $2 ]] && dokku_log_fail "Please specify a global domain name"
domains_set_global "$2"
;;
help | domains:help)
cat<<EOF
domains <app>, List custom domains for app
domains:add <app> DOMAIN, Add a custom domain to app
domains:clear <app>, Clear all custom domains for app
domains:remove <app> DOMAIN, Remove a custom domain from app
domains [<app>], List domains
domains:add <app> DOMAIN, Add a domain to app
domains:clear <app>, Clear all domains for app
domains:disable <app>, Disable VHOST support
domains:enable <app>, Enable VHOST support
domains:remove <app> DOMAIN, Remove a domain from app
domains:set-global <domain>, Set global domain name
EOF
;;

View File

@@ -3,9 +3,168 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
get_app_domains() {
local desc="return app domains"
verify_app_name $1
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
verify_app_name $APP
if [[ -f "$APP_VHOST_FILE" ]];then
cat "$APP_VHOST_FILE"
local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
local GLOBAL_HOSTNAME_PATH="$DOKKU_ROOT/HOSTNAME"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
if [[ -f "$APP_VHOST_FILE" ]]; then
cat "$APP_VHOST_FILE"
elif [[ -f "$GLOBAL_VHOST_PATH" ]]; then
cat "$GLOBAL_VHOST_PATH"
elif [[ -f "$GLOBAL_HOSTNAME_PATH" ]]; then
cat "$GLOBAL_HOSTNAME_PATH"
fi
fi
}
get_default_vhost() {
local desc="return default vhost"
verify_app_name "$1"
local APP="$1"; local RE_IPV4="$(get_ipv4_regex)"; local RE_IPV6="$(get_ipv6_regex)"
if [[ "$(is_global_vhost_enabled)" == "true" ]]; then
local VHOST=$(get_global_vhost)
if ! ([[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]]); then
local SUBDOMAIN=${APP/%\.${VHOST}/}
local hostname=$(: | plugn trigger nginx-hostname $APP $SUBDOMAIN $VHOST)
if [[ ! -n $hostname ]]; then
if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
local hostname="${APP/\//-}"
else
local hostname="${APP/\//-}.$VHOST"
fi
fi
local DEFAULT_VHOST="$hostname"
fi
fi
echo "$DEFAULT_VHOST"
}
domains_setup() {
local desc="setup domains to default state"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"; local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
local RE_IPV4="$(get_ipv4_regex)"; local RE_IPV6="$(get_ipv6_regex)"
local DEFAULT_VHOST="$(get_default_vhost $APP)"
if [[ ! -f $APP_VHOST_PATH ]]; then
if [[ -n "$DEFAULT_VHOST" ]]; then
dokku_log_info1 "Creating new $APP_VHOST_PATH..."
echo "$DEFAULT_VHOST" > $APP_VHOST_PATH
else
dokku_log_info2 "no global VHOST set. disabling vhost support"
disable_app_vhost $APP --no-restart
fi
fi
}
domains_main() {
local desc="print app domains"
local APP="$1"
if [[ "$(is_global_vhost_enabled)" == "true" ]]; then
dokku_log_info2_quiet "Global Domain Name"
get_global_vhost
fi
if [[ -n "$APP" ]]; then
verify_app_name $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi
fi
}
domains_add() {
local desc="add list of domains to app"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
if [[ $(egrep -w "^${2}$" "$APP_VHOST_PATH" > /dev/null 2>&1; echo $?) -eq 0 ]]; then
dokku_log_fail "$2 is already defined for $APP"
exit 1
fi
shift 1
for DOMAIN in "$@"; do
echo "$DOMAIN" >> "$APP_VHOST_PATH"
dokku_log_info1 "Added $DOMAIN to $APP"
done
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]];then
domains_enable "$APP" --no-restart
fi
plugn trigger post-domains-update $APP "add" "$@"
}
domains_clear() {
local desc="clear all app domains"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
rm -f "$APP_VHOST_PATH"
domains_setup "$APP"
plugn trigger post-domains-update $APP "clear"
dokku_log_info1 "Cleared domains in $APP"
}
domains_remove() {
local desc="remove list of app domains"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
local DEFAULT_VHOST="$(get_default_vhost $APP)"
shift 1
for DOMAIN in "$@"; do
sed -i "/^$DOMAIN$/d" "$DOKKU_ROOT/$APP/VHOST"
dokku_log_info1 "Removed $DOMAIN from $APP"
done
plugn trigger post-domains-update $APP "remove" "$@"
}
domains_disable() {
local desc="disable domains/VHOST support"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]];then
disable_app_vhost "$APP"
else
dokku_log_info1 "domains (VHOST) support is already disabled for app ($APP)"
fi
}
domains_enable() {
local desc="enable domains/VHOST support"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
local DEFAULT_VHOST="$(get_default_vhost $APP)"
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]];then
if [[ -n "$DEFAULT_VHOST" ]]; then
echo "$DEFAULT_VHOST" > "$APP_VHOST_PATH"
fi
[[ "$2" == "--no-restart" ]] && local ENABLE_APP_VHOST_ARGS=$2
enable_app_vhost "$APP" "$ENABLE_APP_VHOST_ARGS"
else
dokku_log_info1 "domains (VHOST) support is already enabled for app ($APP)"
fi
}
domains_set_global() {
local desc="set global domain name"
local NEW_GLOBAL_VHOST="$1"; local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
if [[ -n "$NEW_GLOBAL_VHOST" ]]; then
echo "$NEW_GLOBAL_VHOST" > $GLOBAL_VHOST_PATH
dokku_log_info1 "Set global domain to $NEW_GLOBAL_VHOST"
else
dokku_log_fail "New global domain name must not be blank"
fi
}

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core domains plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
APP="$1"
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
echo true # bind to external ip. VHOST is disabled
elif [[ "$(is_global_vhost_enabled $APP)" == "false" ]] && [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
echo true # bind to external ip. no global vhost or global vhost is an ip
else
echo false
fi

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
[[ " nginx:build-config nginx:access-logs nginx:error-logs nginx:disable nginx:enable help nginx:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
[[ " nginx:build-config nginx:access-logs nginx:error-logs help nginx:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
@@ -7,58 +7,13 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
case "$1" in
nginx:build-config)
APP="$2"; DOKKU_APP_LISTEN_PORT="$3"; DOKKU_APP_LISTEN_IP="$4"
nginx_build_config $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
nginx_build_config $2
;;
nginx:access-logs|nginx:error-logs)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
APP="$2"
NGINX_LOGS_TYPE=${1#nginx:}
NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-logs}
NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log"
if [[ $3 == "-t" ]]; then
NGINX_LOGS_ARGS="-F"
else
NGINX_LOGS_ARGS="-n 20"
fi
tail "$NGINX_LOGS_ARGS" "$NGINX_LOGS_PATH"
;;
nginx:disable)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
APP="$2"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
config_set --no-restart $APP DOKKU_NO_NGINX=1
disable_app_vhost $APP
elif [[ "$(is_app_nginx_enabled $APP)" == "true" ]]; then
config_set --no-restart $APP DOKKU_NO_NGINX=1
nginx_build_config $APP
else
dokku_log_info1 "nginx is already disable for app ($APP)"
fi
;;
nginx:enable)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
APP="$2"
if [[ "$(is_app_nginx_enabled $APP)" == "false" ]]; then
config_unset --no-restart $APP DOKKU_NO_NGINX NO_VHOST
unset DOKKU_NO_NGINX NO_VHOST
nginx_build_config $APP
else
dokku_log_info1 "nginx is already enabled for app ($APP)"
fi
nginx_logs "$@"
;;
help | nginx:help)
@@ -66,8 +21,6 @@ case "$1" in
nginx:build-config <app>, (Re)builds nginx config for given app
nginx:access-logs <app> [-t], Show the nginx access logs for an application (-t follows)
nginx:error-logs <app> [-t], Show the nginx error logs for an application (-t follows)
nginx:disable <app>, Disable nginx for an application (forces container binding to external interface)
nginx:enable <app>, Enable nginx for an application
EOF
;;

View File

@@ -4,72 +4,13 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
is_app_nginx_enabled() {
local APP="$1"
verify_app_name "$APP"
local DOKKU_NO_NGINX=$(config_get $APP DOKKU_NO_NGINX)
if [[ -z "$DOKKU_NO_NGINX" ]]; then
echo true
else
echo false
fi
}
is_global_vhost_enabled() {
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
local GLOBAL_VHOST_ENABLED=true
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
# Ensure the ip address continues to the end of the line
# Fixes using a wildcard dns service such as xip.io which allows for *.<ip address>.xip.io
local RE_IPV4="$(get_ipv4_regex)"
local RE_IPV6="$(get_ipv6_regex)"
if [[ -z "$GLOBAL_VHOST" ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
local GLOBAL_VHOST_ENABLED=false
fi
echo $GLOBAL_VHOST_ENABLED
}
is_app_vhost_enabled() {
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
verify_app_name $APP
local NO_VHOST=$(config_get $APP NO_VHOST)
local APP_VHOST_ENABLED=true
if [[ "$NO_VHOST" == "1" ]]; then
local APP_VHOST_ENABLED=false
elif [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]] && [[ ! -f "$APP_VHOST_FILE" ]] && [[ "$NO_VHOST" != "0" ]]; then
local APP_VHOST_ENABLED=false
fi
echo $APP_VHOST_ENABLED
}
disable_app_vhost() {
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
verify_app_name $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/VHOST"
rm "$DOKKU_ROOT/$APP/VHOST"
fi
if [[ -f "$DOKKU_ROOT/$APP/URLS" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/URLS"
rm "$DOKKU_ROOT/$APP/URLS"
fi
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP NO_VHOST=1
}
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
validate_nginx() {
local desc="validate entire nginx config"
set +e
sudo /usr/sbin/nginx -t > /dev/null 2>&1
exit_code=$?
local exit_code=$?
set -e
if [[ "$exit_code" -ne "0" ]]; then
sudo /usr/sbin/nginx -t
@@ -78,6 +19,7 @@ validate_nginx() {
}
restart_nginx() {
local desc="restart nginx for given distros"
case "$DOKKU_DISTRO" in
debian)
sudo /usr/sbin/invoke-rc.d nginx reload > /dev/null
@@ -93,148 +35,166 @@ restart_nginx() {
esac
}
nginx_build_config() {
local APP="$1"; local DOKKU_APP_LISTEN_PORT="$2"; local DOKKU_APP_LISTEN_IP="$3"
verify_app_name "$APP"
VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
URLS_PATH="$DOKKU_ROOT/$APP/URLS"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
APP_NGINX_TEMPLATE="$DOKKU_ROOT/$APP/nginx.conf.template"
APP_NGINX_SSL_TEMPLATE="$DOKKU_ROOT/$APP/nginx.ssl.conf.template"
nginx_logs() {
local desc="display app nginx logs"
local APP="$2"; verify_app_name "$APP"
local NGINX_LOGS_TYPE=${1#nginx:}
local NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-logs}
local NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log"
eval "$(config_export global)"
eval "$(config_export app $APP)"
if [[ $3 == "-t" ]]; then
NGINX_LOGS_ARGS="-F"
else
NGINX_LOGS_ARGS="-n 20"
fi
if [[ ! -n "$DOKKU_NO_NGINX" ]]; then
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then
shopt -s nullglob
for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.web.*; do
DOKKU_APP_PORT_FILE="${DOKKU_APP_IP_FILE//IP/PORT}"
DOKKU_APP_LISTENER_IP=$(< $DOKKU_APP_IP_FILE)
DOKKU_APP_LISTENER_PORT=$(< $DOKKU_APP_PORT_FILE)
tail "$NGINX_LOGS_ARGS" "$NGINX_LOGS_PATH"
}
DOKKU_APP_LISTENERS+=" "
DOKKU_APP_LISTENERS+="$DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT"
DOKKU_APP_LISTENERS+=" "
done
shopt -u nullglob
fi
configure_nginx_ports() {
local desc="configure nginx listening ports"
local APP=$1; verify_app_name "$APP"
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 IS_APP_VHOST_ENABLED="$(is_app_vhost_enabled $APP)"
DOKKU_APP_CIDS=($(get_app_container_ids $APP))
for file in nginx.conf.template nginx.ssl.conf.template; do
docker cp "${DOKKU_APP_CIDS[0]}:/app/${file}" "$DOKKU_ROOT/$APP/" 2> /dev/null || true
done
[[ -f "$APP_NGINX_TEMPLATE" ]] && NGINX_TEMPLATE="$APP_NGINX_TEMPLATE" && NGINX_CUSTOM_TEMPLATE="true" && dokku_log_info1 'Overriding default nginx.conf with detected nginx.conf.template'
NGINX_CONF=$(mktemp -t "nginx.conf.XXXXXX")
SCHEME="http"
# if the app has is not vhost enabled then, let's make sure we're cleaned up
[[ "$(is_app_vhost_enabled $APP)" == "false" ]] && disable_app_vhost $APP --no-restart
if [[ -z "$DOKKU_NGINX_PORT" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
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
config_set --no-restart $APP DOKKU_NGINX_PORT=${NGINX_PORT}
fi
if [[ -n "$NGINX_PORT" ]]; then
config_set --no-restart $APP DOKKU_NGINX_PORT="${NGINX_PORT}"
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
NGINX_PORT=$DOKKU_NGINX_PORT
local NGINX_SSL_PORT=443
fi
config_set --no-restart $APP DOKKU_NGINX_SSL_PORT=${NGINX_SSL_PORT}
fi
}
NONSSL_VHOSTS=$(get_app_domains $APP)
if [[ -n "$(is_ssl_enabled $APP)" ]]; then
SSL_HOSTNAME=$(get_ssl_hostnames $APP)
SSL_INUSE=true
validate_ssl_domains() {
local desc="check configured domains against SSL cert contents and show warning if mismatched"
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
[[ -n "$SSL_HOSTNAME" ]] && SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
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:"
for domain in $(echo $NONSSL_VHOSTS| xargs); do
dokku_log_info2 "$domain"
done
[[ -n "$SSL_HOSTNAME" ]] && dokku_log_info1 "Domains found in SSL certificate:"
for domain in $(echo $SSL_HOSTNAME | xargs); do
dokku_log_info2 "$domain"
done
fi
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:"
for domain in $(echo $NONSSL_VHOSTS| xargs); do
dokku_log_info2 "$domain"
done
[[ -n "$SSL_HOSTNAME" ]] && dokku_log_info1 "Domains found in SSL certificate:"
for domain in $(echo $SSL_HOSTNAME | xargs); do
dokku_log_info2 "$domain"
done
fi
}
if [[ "$(is_ssl_enabled $APP)" == "app" ]]; then
SSL_DIRECTIVES=$(cat <<EOF
ssl_certificate $APP_SSL_PATH/server.crt;
ssl_certificate_key $APP_SSL_PATH/server.key;
EOF
)
elif [[ "$(is_ssl_enabled $APP)" == "global" ]]; then
SSL_DIRECTIVES=""
fi
fi
get_custom_nginx_template() {
local APP="$1"; verify_app_name "$APP"
local DESTINATION="$2"
local IMAGE_TAG="$(get_running_image_tag $APP)"
local IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
local NGINX_TEMPLATE_NAME="nginx.conf.sigil"
if [[ -n "$SSL_INUSE" ]]; then
SCHEME="https"
copy_from_image "$IMAGE" "$NGINX_TEMPLATE_NAME" "$DESTINATION" 2>/dev/null || true
}
[[ -f "$APP_NGINX_SSL_TEMPLATE" ]] && NGINX_SSL_TEMPLATE="$APP_NGINX_SSL_TEMPLATE" && dokku_log_info1 'Overriding default nginx.ssl.conf with detected nginx.ssl.conf.template'
[[ -z "$NGINX_SSL_TEMPLATE" ]] && NGINX_SSL_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.ssl.conf.template"
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
else
SSL_VHOSTS=$(< $DOKKU_ROOT/HOSTNAME)
fi
NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH 2> /dev/null || true)
nginx_build_config() {
local desc="build nginx config to proxy app containers using sigil"
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_LISTEN_PORT="$2"; local DOKKU_APP_LISTEN_IP="$3"
local VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"; local URLS_PATH="$DOKKU_ROOT/$APP/URLS"
local NGINX_TEMPLATE_NAME="nginx.conf.sigil"
local DEFAULT_NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/$NGINX_TEMPLATE_NAME"
local NGINX_TEMPLATE="$DEFAULT_NGINX_TEMPLATE"; local SCHEME=http
local NGINX_TEMPLATE_SOURCE="built-in"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports $APP)"
if [[ -z "$DOKKU_NGINX_SSL_PORT" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
local NGINX_SSL_PORT=$(get_available_port)
local DOKKU_DISABLE_PROXY=$(config_get $APP DOKKU_DISABLE_PROXY)
local IS_APP_VHOST_ENABLED=$(is_app_vhost_enabled $APP)
if [[ -z "$DOKKU_DISABLE_PROXY" ]]; then
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then
shopt -s nullglob
local DOKKU_APP_IP_FILE
for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.web.*; do
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
NGINX_SSL_PORT=443
local DOKKU_APP_LISTENERS+=" $DOKKU_APP_LISTENER_IP "
fi
config_set --no-restart $APP DOKKU_NGINX_SSL_PORT=${NGINX_SSL_PORT}
else
local NGINX_SSL_PORT=$DOKKU_NGINX_SSL_PORT
fi
while read -r line; do
[[ -z "$line" ]] && continue
dokku_log_info1 "Configuring SSL for $line...(using $NGINX_SSL_TEMPLATE)"
SSL_SERVER_NAME=$line
NOSSL_SERVER_NAME=$line
eval "cat <<< \"$(< $NGINX_SSL_TEMPLATE)\" >> $NGINX_CONF"
done <<< "$SSL_VHOSTS"
fi
if [[ -n "$DOKKU_SSL_TERMINATED" ]] && [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.conf.ssl_terminated.template"
elif [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.conf.template"
fi
if [[ -n "$NONSSL_VHOSTS" ]]; then
NOSSL_SERVER_NAME=$(echo $NONSSL_VHOSTS | tr '\n' ' ')
xargs -i echo "-----> Configuring {}...(using $NGINX_TEMPLATE)" <<< "$NONSSL_VHOSTS"
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
fi
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]] || ([[ -z "$NONSSL_VHOSTS" ]] && [[ -z "$SSL_VHOSTS" ]]); then
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
sed --in-place -n -e '/^.*server_name.*$/!p' $NGINX_CONF
fi
if [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
echo "upstream $APP { server $DOKKU_APP_LISTEN_IP:$DOKKU_APP_LISTEN_PORT; }" >> $NGINX_CONF
elif [[ -n "$DOKKU_APP_LISTENERS" ]]; then
echo "upstream $APP { " >> $NGINX_CONF
for listener in $DOKKU_APP_LISTENERS; do
echo " server $listener;" >> $NGINX_CONF
local DOKKU_APP_LISTENERS=$(echo $DOKKU_APP_LISTENERS | xargs)
done
echo "}" >> $NGINX_CONF
shopt -u nullglob
elif [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
local PASSED_LISTEN_IP_PORT=true
fi
local TMPDIR=$(mktemp -d /tmp/nginx_template.XXXXX)
local NGINX_CONF=$(mktemp -p ${TMPDIR} -t "nginx.conf.XXXXXX")
local CUSTOM_NGINX_TEMPLATE="$TMPDIR/$NGINX_TEMPLATE_NAME"
trap 'rm -rf "$NGINX_CONF $TMPDIR" > /dev/null' RETURN
get_custom_nginx_template "$APP" "$CUSTOM_NGINX_TEMPLATE"
if [[ -f "$CUSTOM_NGINX_TEMPLATE" ]]; then
dokku_log_info1 'Overriding default nginx.conf with detected nginx.conf.sigil'
local NGINX_TEMPLATE="$CUSTOM_NGINX_TEMPLATE"
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
local SSL_INUSE=true; local SCHEME=https
validate_ssl_domains "$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')
if [[ "$IS_APP_VHOST_ENABLED" == "true" ]]; then
local SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
else
local SSL_VHOSTS=$(< $DOKKU_ROOT/HOSTNAME)
fi
local SSL_SERVER_NAME=$(echo $SSL_VHOSTS | xargs)
fi
local SIGIL_PARAMS=(-f $NGINX_TEMPLATE APP="$APP" DOKKU_ROOT="$DOKKU_ROOT"
NOSSL_SERVER_NAME="$NOSSL_SERVER_NAME"
DOKKU_APP_LISTENERS="$DOKKU_APP_LISTENERS"
PASSED_LISTEN_IP_PORT="$PASSED_LISTEN_IP_PORT"
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")
# 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
if is_deployed "$APP"; then
dokku_log_info1 "Creating $SCHEME nginx.conf"
mv $NGINX_CONF "$DOKKU_ROOT/$APP/nginx.conf"
@@ -251,13 +211,12 @@ EOF
validate_nginx && restart_nginx
fi
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
if ([[ -n "$NONSSL_VHOSTS" ]] || [[ -n "$SSL_VHOSTS" ]]) && [[ "$IS_APP_VHOST_ENABLED" == "true" ]]; then
echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" > $URLS_PATH
xargs -i echo "https://{}" <<< "${SSL_VHOSTS}" >> $URLS_PATH
xargs -i echo "http://{}" <<< "${NONSSL_VHOSTS}" >> $URLS_PATH
xargs -i echo "$SCHEME://{}" <<< "$(echo ${SSL_VHOSTS} ${NONSSL_VHOSTS} | tr ' ' '\n' | sort -u)" >> $URLS_PATH
fi
else
# note because this clause is long. if $DOKKU_NO_NGINX is set:
# note because this clause is long. if $DOKKU_DISABLE_PROXY is set:
dokku_log_info1 "nginx support is disabled for app ($APP)."
if [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]]; then
dokku_log_info1 "deleting nginx.conf"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core nginx-vhosts plugin"
version = "0.4.0"
version = "0.5.0"
[plugin.config]

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
case "$DOKKU_DISTRO" in
debian)

View File

@@ -1,15 +1,23 @@
#!/usr/bin/env bash
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"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
dokku_log_info1 "VHOST support disabled. Skipping domains setup"
elif [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku domains:setup $APP
nginx_post_deploy() {
local APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
dokku_log_info1 "VHOST support disabled. Skipping domains setup"
elif [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
domains_setup $APP
fi
nginx_build_config $APP
fi
}
nginx_build_config $APP
if [[ "$(get_app_proxy_type $1)" == "nginx" ]]; then
nginx_post_deploy "$@"
fi

View File

@@ -2,7 +2,8 @@
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"
APP="$1"
nginx_build_config $APP
if [[ "$(get_app_proxy_type $1)" == "nginx" ]]; then
nginx_build_config $1
fi

View File

@@ -0,0 +1,17 @@
#!/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_CORE_AVAILABLE_PATH/ps/functions"
nginx_disable() {
local desc="disable nginx proxy"
local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type $APP)" == "nginx" ]]; then
disable_app_vhost $APP --no-restart
ps_restart $APP
fi
}
nginx_disable "$@"

View File

@@ -0,0 +1,17 @@
#!/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_CORE_AVAILABLE_PATH/ps/functions"
nginx_enable() {
local desc="enable nginx proxy"
local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type $APP)" == "nginx" ]]; then
enable_app_vhost $APP --no-restart
ps_restart $APP
fi
}
nginx_enable "$@"

View File

@@ -0,0 +1,20 @@
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

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

View File

@@ -0,0 +1,10 @@
{{ if .RAW_TCP_PORTS }}
{{ include "tcp.server.config" . }}
{{ else if .SSL_INUSE }}
{{ include "nossl.server.config" . }}
{{ include "ssl.server.config" . }}
{{ include "upstream.config" . }}
{{ else }}
{{ include "nossl.server.config" . }}
{{ include "upstream.config" . }}
{{ end }}

View File

@@ -1,19 +0,0 @@
# Nginx configuration when running behind a load balancer that terminates SSL
# connections (e.g. AWS ELB)
server {
listen [::]:$NGINX_PORT;
listen $NGINX_PORT;
server_name $NOSSL_SERVER_NAME;
location / {
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 \$http_x_forwarded_proto;
proxy_set_header X-Forwarded-For \$http_x_forwarded_for;
proxy_set_header X-Forwarded-Port \$http_x_forwarded_port;
proxy_set_header X-Request-Start \$msec;
}
include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
}

View File

@@ -1,28 +0,0 @@
server {
listen [::]:$NGINX_PORT;
listen $NGINX_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;
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,40 +0,0 @@
server {
listen [::]:$NGINX_PORT;
listen $NGINX_PORT;
server_name $NOSSL_SERVER_NAME;
access_log /var/log/nginx/${APP}-access.log;
error_log /var/log/nginx/${APP}-error.log;
return 301 https://\$host:$NGINX_SSL_PORT\$request_uri;
}
server {
listen [::]:$NGINX_SSL_PORT ssl spdy;
listen $NGINX_SSL_PORT ssl spdy;
server_name $SSL_SERVER_NAME;
access_log /var/log/nginx/${APP}-access.log;
error_log /var/log/nginx/${APP}-error.log;
$SSL_DIRECTIVES
keepalive_timeout 70;
add_header Alternate-Protocol $NGINX_SSL_PORT:npn-spdy/2;
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

@@ -0,0 +1,11 @@
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

@@ -0,0 +1,12 @@
server {
listen [::]:{{ .NGINX_SSL_PORT }} ssl spdy;
listen {{ .NGINX_SSL_PORT }} ssl spdy;
{{ if .SSL_SERVER_NAME }}server_name {{ .SSL_SERVER_NAME }}; {{ end }}
{{ include "log.config" . }}
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;
{{ include "location.config" . }}
}

View File

@@ -0,0 +1,35 @@
{{ 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

@@ -0,0 +1,9 @@
{{ 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 }}

40
plugins/proxy/commands Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
[[ " proxy proxy:set proxy:enable proxy:disable help proxy:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
case "$1" in
proxy)
proxy_main $2
;;
proxy:set)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_set $2
;;
proxy:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_enable $2 --no-restart
;;
proxy:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_disable $2 --no-restart
;;
help | proxy:help)
cat<<EOF
proxy <app>, Show proxy for app
proxy:enable <app>, Enable proxy for app
proxy:disable <app>, Disable proxy for app
proxy:set <app> <proxy_type>, NOT IMPLEMENTED YET!!
EOF
;;
*)
exit $DOKKU_NOT_IMPLEMENTED_EXIT
;;
esac

74
plugins/proxy/functions Executable file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
is_app_proxy_enabled() {
local desc="return true if proxy is enabled; otherwise return false"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_ENABLED=true
local DOKKU_DISABLE_PROXY=$(config_get $APP DOKKU_DISABLE_PROXY)
if [[ -n "$DOKKU_DISABLE_PROXY" ]]; then
local APP_PROXY_ENABLED=false
fi
echo $APP_PROXY_ENABLED
}
get_app_proxy_type() {
local desc="return app proxy type"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_TYPE="nginx"
echo $APP_PROXY_TYPE
}
proxy_main() {
local desc="displays app proxy implementation"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Proxy Type"
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(get_app_proxy_type $app)"
done
}
proxy_set() {
local desc="enable proxy for app"
local APP="$1"; verify_app_name "$APP"
dokku_log_info1 "proxy:set not implemented"
}
proxy_enable() {
local desc="enable proxy for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_proxy_enabled $APP)" == "false" ]]; then
dokku_log_info1 "Enabling proxy for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_unset $CONFIG_SET_ARGS $APP DOKKU_DISABLE_PROXY
plugn trigger proxy-enable "$APP"
else
dokku_log_info1 "proxy is already enabled for app ($APP)"
fi
}
proxy_disable() {
local desc="disable proxy for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_proxy_enabled $APP)" == "true" ]]; then
dokku_log_info1 "Disabling proxy for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
config_set $CONFIG_SET_ARGS $APP DOKKU_DISABLE_PROXY=1
plugn trigger proxy-disable "$APP"
else
dokku_log_info1 "proxy is already disable for app ($APP)"
fi
}

View File

@@ -0,0 +1,4 @@
[plugin]
description = "dokku core proxy plugin"
version = "0.5.0"
[plugin.config]

View File

@@ -7,72 +7,38 @@ source "$PLUGIN_AVAILABLE_PATH/ps/functions"
case "$1" in
ps)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$APP"; DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do
has_tty && DOKKU_RUN_OPTS="-i -t"
dokku_log_info1_quiet "running processes in container: $CID"
docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww"
done
ps_main $2
;;
ps:start)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP);
verify_app_name "$APP"
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if ! (is_app_running $APP); then
release_and_deploy "$APP" "$IMAGE_TAG"
else
echo "App $APP already running"
fi
ps_start $2
;;
ps:stop)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
verify_app_name "$APP"
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if [[ -n "$DOKKU_APP_RUNNING_CONTAINER_IDS" ]]; then
echo "Stopping $APP ..."
docker stop $DOKKU_APP_RUNNING_CONTAINER_IDS > /dev/null || true
plugn trigger post-stop $APP
else
echo "App $APP already stopped"
fi
ps_stop $2
;;
ps:rebuild)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$APP"
plugn trigger receive-app $APP
ps_rebuild $2
;;
ps:rebuildall)
for app in $(dokku_apps); do
is_deployed $app && dokku ps:rebuild $app
is_deployed $app && ps_rebuild $app
done
;;
ps:restart)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP)
verify_app_name "$APP"
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
release_and_deploy "$APP" "$IMAGE_TAG"
ps_restart $2
;;
ps:restartall)
for app in $(dokku_apps); do
dokku ps:restart $app
ps_restart $app
done
;;
@@ -81,34 +47,15 @@ case "$1" in
DOKKU_APP_RESTORE=$(dokku config:get $app DOKKU_APP_RESTORE || true)
if [[ $DOKKU_APP_RESTORE != 0 ]]; then
echo "Restoring app $app ..."
dokku ps:start $app
ps_start $app
fi
done
;;
ps:scale)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP)
verify_app_name "$APP"
DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
shift 2
[[ ! -e $DOKKU_SCALE_FILE ]] && generate_scale_file "$APP" "$IMAGE_TAG"
if [[ -z "$@" ]];then
dokku_log_info1_quiet "Scaling for $APP"
dokku_col_log_info1_quiet "proctype" "qty"
dokku_col_log_info1_quiet "--------" "---"
while read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
PROC_NAME=${line%%=*}
PROC_COUNT=${line#*=}
dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT"
done < "$DOKKU_SCALE_FILE"
else
set_scale "$APP" "$@"
release_and_deploy "$APP" "$IMAGE_TAG"
fi
shift 1
ps_scale "$@"
;;
help | ps:help)

View File

@@ -79,3 +79,82 @@ set_scale() {
fi
done
}
ps_main() {
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do
has_tty && DOKKU_RUN_OPTS="-i -t"
dokku_log_info1_quiet "running processes in container: $CID"
docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww"
done
}
ps_start() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag $APP);
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if ! (is_app_running $APP); then
release_and_deploy "$APP" "$IMAGE_TAG"
else
echo "App $APP already running"
fi
}
ps_stop() {
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
if [[ -n "$DOKKU_APP_RUNNING_CONTAINER_IDS" ]]; then
echo "Stopping $APP ..."
docker stop $DOKKU_APP_RUNNING_CONTAINER_IDS > /dev/null || true
plugn trigger post-stop $APP
else
echo "App $APP already stopped"
fi
}
ps_rebuild() {
local APP="$1"; verify_app_name "$APP"
plugn trigger receive-app $APP
}
ps_restart() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag $APP)
! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0
release_and_deploy "$APP" "$IMAGE_TAG"
}
ps_scale() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag $APP)
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
shift 1
[[ ! -e $DOKKU_SCALE_FILE ]] && generate_scale_file "$APP" "$IMAGE_TAG"
if [[ -z "$@" ]];then
dokku_log_info1_quiet "Scaling for $APP"
dokku_col_log_info1_quiet "proctype" "qty"
dokku_col_log_info1_quiet "--------" "---"
while read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
PROC_NAME=${line%%=*}
PROC_COUNT=${line#*=}
dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT"
done < "$DOKKU_SCALE_FILE"
else
set_scale "$APP" "$@"
release_and_deploy "$APP" "$IMAGE_TAG"
fi
}