#!/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 <> $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<, Imports a tarball from stdin; should contain server.crt and server.key nginx:build-config , (Re)builds nginx config for given app EOF ;; *) exit $DOKKU_NOT_IMPLEMENTED_EXIT ;; esac