2015-09-17 19:09:29 -07:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
|
|
|
|
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"
|
|
|
|
|
|
2015-09-18 15:46:46 -07:00
|
|
|
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
|
2015-09-18 17:26:00 -07:00
|
|
|
local RE_IPV4="$(get_ipv4_regex)"
|
|
|
|
|
local RE_IPV6="$(get_ipv6_regex)"
|
2015-09-18 15:46:46 -07:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-17 19:09:29 -07:00
|
|
|
validate_nginx() {
|
|
|
|
|
set +e
|
|
|
|
|
sudo /usr/sbin/nginx -t > /dev/null 2>&1
|
|
|
|
|
exit_code=$?
|
|
|
|
|
set -e
|
|
|
|
|
if [[ "$exit_code" -ne "0" ]]; then
|
|
|
|
|
sudo /usr/sbin/nginx -t
|
|
|
|
|
exit "$exit_code"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
restart_nginx() {
|
|
|
|
|
case "$DOKKU_DISTRO" in
|
2015-10-24 23:12:38 -04:00
|
|
|
debian)
|
2015-10-25 22:56:48 -04:00
|
|
|
sudo /usr/sbin/invoke-rc.d nginx reload > /dev/null
|
2015-10-24 23:12:38 -04:00
|
|
|
;;
|
|
|
|
|
|
2015-09-17 19:09:29 -07:00
|
|
|
ubuntu)
|
|
|
|
|
sudo /etc/init.d/nginx reload > /dev/null
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
opensuse)
|
|
|
|
|
sudo /sbin/service nginx reload > /dev/null
|
|
|
|
|
;;
|
|
|
|
|
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"
|
2015-10-14 02:09:17 +03:00
|
|
|
APP_NGINX_SSL_TEMPLATE="$DOKKU_ROOT/$APP/nginx.ssl.conf.template"
|
2015-09-17 19:09:29 -07:00
|
|
|
|
|
|
|
|
eval "$(config_export global)"
|
|
|
|
|
eval "$(config_export app $APP)"
|
|
|
|
|
|
2015-09-18 15:46:46 -07:00
|
|
|
if [[ ! -n "$DOKKU_NO_NGINX" ]]; then
|
2015-09-17 19:09:29 -07:00
|
|
|
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
|
2015-11-02 19:42:16 -06:00
|
|
|
DOKKU_APP_PORT_FILE="${DOKKU_APP_IP_FILE//IP/PORT}"
|
2015-09-17 19:09:29 -07:00
|
|
|
DOKKU_APP_LISTENER_IP=$(< $DOKKU_APP_IP_FILE)
|
|
|
|
|
DOKKU_APP_LISTENER_PORT=$(< $DOKKU_APP_PORT_FILE)
|
|
|
|
|
|
|
|
|
|
DOKKU_APP_LISTENERS+=" "
|
|
|
|
|
DOKKU_APP_LISTENERS+="$DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT"
|
|
|
|
|
DOKKU_APP_LISTENERS+=" "
|
|
|
|
|
done
|
|
|
|
|
shopt -u nullglob
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
DOKKU_APP_CIDS=($(get_app_container_ids $APP))
|
2015-11-18 17:36:02 -05:00
|
|
|
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
|
2015-09-17 19:09:29 -07:00
|
|
|
|
|
|
|
|
[[ -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"
|
|
|
|
|
|
2015-09-18 15:46:46 -07:00
|
|
|
# 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
|
2015-09-17 19:09:29 -07:00
|
|
|
|
|
|
|
|
if [[ -z "$DOKKU_NGINX_PORT" ]]; then
|
2015-09-18 15:46:46 -07:00
|
|
|
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
|
2015-09-17 19:09:29 -07:00
|
|
|
dokku_log_info1 "no nginx port set. setting to random open high port"
|
2015-09-18 15:46:46 -07:00
|
|
|
local NGINX_PORT=$(get_available_port)
|
2015-09-17 19:09:29 -07:00
|
|
|
else
|
|
|
|
|
local NGINX_PORT=80
|
|
|
|
|
fi
|
|
|
|
|
config_set --no-restart $APP DOKKU_NGINX_PORT=${NGINX_PORT}
|
|
|
|
|
else
|
|
|
|
|
NGINX_PORT=$DOKKU_NGINX_PORT
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
NONSSL_VHOSTS=$(get_app_domains $APP)
|
|
|
|
|
if [[ -n "$(is_ssl_enabled $APP)" ]]; then
|
|
|
|
|
SSL_HOSTNAME=$(get_ssl_hostnames $APP)
|
|
|
|
|
SSL_INUSE=true
|
|
|
|
|
|
|
|
|
|
[[ -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 [[ "$(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
|
|
|
|
|
|
|
|
|
|
if [[ -n "$SSL_INUSE" ]]; then
|
|
|
|
|
SCHEME="https"
|
|
|
|
|
|
2015-10-14 02:09:17 +03:00
|
|
|
[[ -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"
|
2015-09-18 15:46:46 -07:00
|
|
|
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
|
2015-09-17 19:09:29 -07:00
|
|
|
SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
|
|
|
|
|
else
|
2015-09-17 22:46:58 -07:00
|
|
|
SSL_VHOSTS=$(< $DOKKU_ROOT/HOSTNAME)
|
2015-09-17 19:09:29 -07:00
|
|
|
fi
|
|
|
|
|
NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH 2> /dev/null || true)
|
|
|
|
|
|
|
|
|
|
if [[ -z "$DOKKU_NGINX_SSL_PORT" ]]; then
|
2015-09-18 15:46:46 -07:00
|
|
|
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
|
2015-09-17 19:09:29 -07:00
|
|
|
dokku_log_info1 "no nginx ssl port set. setting to random open high port"
|
2015-09-18 15:46:46 -07:00
|
|
|
local NGINX_SSL_PORT=$(get_available_port)
|
2015-09-17 19:09:29 -07:00
|
|
|
else
|
|
|
|
|
NGINX_SSL_PORT=443
|
|
|
|
|
fi
|
|
|
|
|
config_set --no-restart $APP DOKKU_NGINX_SSL_PORT=${NGINX_SSL_PORT}
|
|
|
|
|
else
|
|
|
|
|
local NGINX_SSL_PORT=$DOKKU_NGINX_SSL_PORT
|
|
|
|
|
fi
|
|
|
|
|
|
2015-11-02 17:13:44 -06:00
|
|
|
while read -r line; do
|
2015-09-17 19:09:29 -07:00
|
|
|
[[ -z "$line" ]] && continue
|
2015-11-18 17:36:02 -05:00
|
|
|
dokku_log_info1 "Configuring SSL for $line...(using $NGINX_SSL_TEMPLATE)"
|
2015-09-17 19:09:29 -07:00
|
|
|
SSL_SERVER_NAME=$line
|
|
|
|
|
NOSSL_SERVER_NAME=$line
|
2015-10-14 02:09:17 +03:00
|
|
|
eval "cat <<< \"$(< $NGINX_SSL_TEMPLATE)\" >> $NGINX_CONF"
|
2015-09-17 19:09:29 -07:00
|
|
|
done <<< "$SSL_VHOSTS"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ -n "$DOKKU_SSL_TERMINATED" ]] && [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
|
2015-09-17 21:54:37 -07:00
|
|
|
NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.conf.ssl_terminated.template"
|
2015-09-17 19:09:29 -07:00
|
|
|
elif [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
|
2015-09-17 21:54:37 -07:00
|
|
|
NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/nginx.conf.template"
|
2015-09-17 19:09:29 -07:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ -n "$NONSSL_VHOSTS" ]]; then
|
|
|
|
|
NOSSL_SERVER_NAME=$(echo $NONSSL_VHOSTS | tr '\n' ' ')
|
2015-11-18 17:36:02 -05:00
|
|
|
xargs -i echo "-----> Configuring {}...(using $NGINX_TEMPLATE)" <<< "$NONSSL_VHOSTS"
|
2015-10-06 23:12:24 +02:00
|
|
|
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
|
2015-09-17 19:09:29 -07:00
|
|
|
fi
|
2015-09-18 15:46:46 -07:00
|
|
|
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]] || ([[ -z "$NONSSL_VHOSTS" ]] && [[ -z "$SSL_VHOSTS" ]]); then
|
2015-11-02 19:08:41 +01:00
|
|
|
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
|
2015-09-17 21:40:34 -07:00
|
|
|
sed --in-place -n -e '/^.*server_name.*$/!p' $NGINX_CONF
|
|
|
|
|
fi
|
2015-09-17 19:09:29 -07:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
done
|
|
|
|
|
echo "}" >> $NGINX_CONF
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
dokku_log_info1 "Creating $SCHEME nginx.conf"
|
|
|
|
|
mv $NGINX_CONF "$DOKKU_ROOT/$APP/nginx.conf"
|
|
|
|
|
|
|
|
|
|
if is_deployed "$APP"; then
|
|
|
|
|
dokku_log_info1 "Running nginx-pre-reload"
|
|
|
|
|
plugn trigger nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP
|
|
|
|
|
|
|
|
|
|
dokku_log_verbose "Reloading nginx"
|
|
|
|
|
validate_nginx && restart_nginx
|
|
|
|
|
fi
|
|
|
|
|
|
2015-09-18 15:46:46 -07:00
|
|
|
if [[ "$(is_app_vhost_enabled $APP)" == "true" ]]; then
|
2015-09-17 19:09:29 -07:00
|
|
|
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
|
|
|
|
|
fi
|
|
|
|
|
else
|
2015-09-18 15:46:46 -07:00
|
|
|
# note because this clause is long. if $DOKKU_NO_NGINX is set:
|
2015-09-17 19:09:29 -07:00
|
|
|
dokku_log_info1 "nginx support is disabled for app ($APP)."
|
|
|
|
|
if [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]]; then
|
|
|
|
|
dokku_log_info1 "deleting nginx.conf"
|
|
|
|
|
rm "$DOKKU_ROOT/$APP/nginx.conf"
|
|
|
|
|
|
|
|
|
|
if is_deployed "$APP"; then
|
|
|
|
|
dokku_log_info1 "reloading nginx after nginx.conf deletion"
|
|
|
|
|
validate_nginx && restart_nginx
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
}
|