Files
dokku/plugins/nginx-vhosts/commands

214 lines
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_PATH/common/functions"
source "$PLUGIN_PATH/certs/functions"
source "$PLUGIN_PATH/config/functions"
source "$PLUGIN_PATH/domains/functions"
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
ubuntu)
sudo /etc/init.d/nginx reload > /dev/null
;;
opensuse)
sudo /sbin/service nginx reload > /dev/null
;;
esac
}
case "$1" in
nginx:build-config)
APP="$2"; DOKKU_APP_LISTEN_PORT="$3"; DOKKU_APP_LISTEN_IP="${4}"
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"
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=$(echo $DOKKU_APP_IP_FILE | sed -e "s:IP:PORT:g")
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))
docker cp "${DOKKU_APP_CIDS[0]}:/app/nginx.conf.template" "$DOKKU_ROOT/$APP/" 2> /dev/null || true
eval "$(config_export global)"
eval "$(config_export app $APP)"
[[ -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'
if [[ ! -n "$NO_VHOST" ]] && [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
NONSSL_VHOSTS=$(get_app_domains $APP)
if [[ -n "$(is_ssl_enabled $APP)" ]];then
SSL_HOSTNAME=$(get_ssl_hostnames $APP)
[[ -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); then
SSL_INUSE=true
else
dokku_log_info1 "No matching configured domains for $APP found in SSL certificate. Your app will not be configured with an SSL endpoint"
dokku_log_info1 "Please add appropriate domains via the dokku domains command"
dokku_log_info1 "Configured domains for app:"
for domain in $(echo $NONSSL_VHOSTS| xargs); do
dokku_log_info2 "$domain"
done
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
NGINX_CONF=$(mktemp -t "nginx.conf.XXXXXX")
SCHEME="http"
if [[ -n "$SSL_INUSE" ]]; then
SCHEME="https"
[[ -z "$NGINX_TEMPLATE" ]] && NGINX_TEMPLATE="$PLUGIN_PATH/nginx-vhosts/templates/nginx.ssl.conf.template"
SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
while read line; do
[[ -z "$line" ]] && continue
dokku_log_info1 "Configuring SSL for $line..."
SSL_SERVER_NAME=$line
NOSSL_SERVER_NAME=$line
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
done <<< "$SSL_VHOSTS"
fi
if [[ -n "$NONSSL_VHOSTS" ]]; then
NOSSL_SERVER_NAME=$(echo $NONSSL_VHOSTS | tr '\n' ' ')
xargs -i echo "-----> Configuring {}..." <<< "$NONSSL_VHOSTS"
[[ -z "$NGINX_CUSTOM_TEMPLATE" ]] && NGINX_TEMPLATE="$PLUGIN_PATH/nginx-vhosts/templates/nginx.conf.template"
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $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
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"
pluginhook nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP
dokku_log_verbose "Reloading nginx"
validate_nginx && restart_nginx
fi
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
else
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
if [[ -f "$DOKKU_ROOT/$APP/nginx.conf" ]]; then
dokku_log_info1 "VHOST support disabled, deleting nginx.conf"
rm "$DOKKU_ROOT/$APP/nginx.conf"
if is_deployed "$APP"; then
dokku_log_info1 "VHOST support disabled, reloading nginx after nginx.conf deletion"
validate_nginx && restart_nginx
fi
fi
fi
;;
nginx:import-ssl)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
[[ -t 0 ]] && echo "Tar archive containing server.crt and server.key expected on stdin" && exit 1
APP="$2"
TEMP_DIR=$(mktemp -d)
cd $TEMP_DIR
tar xvf - <&0
CRT_FILE_SEARCH=$(find . -type f -name "*.crt")
CRT_FILE_COUNT=$(printf "%s" "$CRT_FILE_SEARCH" | grep -c '^')
if [[ $CRT_FILE_COUNT -lt 1 ]]; then
echo "Tar archive is missing .crt file" && exit 1
elif [[ $CRT_FILE_COUNT -gt 1 ]]; then
echo "Tar archive contains more than one .crt file" && exit 1
else
CRT_FILE=$CRT_FILE_SEARCH
fi
KEY_FILE_SEARCH=$(find . -type f -name "*.key")
KEY_FILE_COUNT=$(printf "%s" "$KEY_FILE_SEARCH" | grep -c '^')
if [[ $KEY_FILE_COUNT -lt 1 ]]; then
echo "Tar archive is missing .key file" && exit 1
elif [[ $KEY_FILE_COUNT -gt 1 ]]; then
echo "Tar archive contains more than one .key file" && exit 1
else
KEY_FILE=$KEY_FILE_SEARCH
fi
mkdir -p "$DOKKU_ROOT/$APP/tls"
mv "$CRT_FILE" "$DOKKU_ROOT/$APP/tls/server.crt"
mv "$KEY_FILE" "$DOKKU_ROOT/$APP/tls/server.key"
cd $DOKKU_ROOT
rm -rf $TEMP_DIR
dokku nginx:build-config $APP
;;
help | nginx:help)
cat && cat<<EOF
nginx:import-ssl <app>, Imports a tarball from stdin; should contain server.crt and server.key
nginx:build-config <app>, (Re)builds nginx config for given app
EOF
;;
*)
exit $DOKKU_NOT_IMPLEMENTED_EXIT
;;
esac