Merge pull request #1476 from progrium/1123_mh-nginx-novhost
nginx proxy without VHOST
This commit is contained in:
@@ -2,6 +2,14 @@
|
||||
|
||||
Dokku uses nginx as it's server for routing requests to specific applications. By default, access and error logs are written for each app to `/var/log/nginx/${APP}-access.log` and `/var/log/nginx/${APP}-error.log` respectively
|
||||
|
||||
```
|
||||
nginx:access-logs <app> [-t] Show the nginx access logs for an application (-t follows)
|
||||
nginx:build-config <app> (Re)builds nginx config for given app
|
||||
nginx:disable <app> disable nginx for an application (forces container binding to external interface)
|
||||
nginx:enable <app> enable nginx for an application
|
||||
nginx:error-logs <app> [-t] Show the nginx error logs for an application (-t follows)
|
||||
```
|
||||
|
||||
## TLS/SPDY support
|
||||
|
||||
Dokku provides easy TLS/SPDY support out of the box. This can be done app-by-app or for all subdomains at once. Note that whenever TLS support is enabled SPDY is also enabled.
|
||||
@@ -166,13 +174,13 @@ You can also use the built-in `domains` plugin to handle:
|
||||
|
||||
### Disabling VHOSTS
|
||||
|
||||
If desired, it is possible to disable vhosts by setting the `NO_VHOST` environment variable:
|
||||
If desired, it is possible to disable vhosts by setting the environment variable `NO_VHOST=1`:
|
||||
|
||||
```shell
|
||||
dokku config:set myapp NO_VHOST=1
|
||||
```
|
||||
|
||||
On subsequent deploys, the nginx virtualhost will be discarded. This is useful when deploying internal-facing services that should not be publicly routeable.
|
||||
On subsequent deploys, the nginx virtualhost will be discarded. This is useful when deploying internal-facing services that should not be publicly routeable. As of 0.4.0, nginx will still be configured to proxy your app on some random high port. This allows internal services to maintain the same port between deployments. You may change this port by setting `DOKKU_NGINX_PORT` and/or `DOKKU_NGINX_SSL_PORT` (for services configured to use SSL.)
|
||||
|
||||
### Domains plugin
|
||||
|
||||
|
||||
22
dokku
22
dokku
@@ -80,6 +80,16 @@ case "$1" in
|
||||
DOKKU_RESTART_LIMIT=$(dokku config:get $APP DOKKU_RESTART_LIMIT || echo 10)
|
||||
DOKKU_RESTART_LIMIT=${DOKKU_RESTART_LIMIT:=10}
|
||||
|
||||
DOKKU_APP_SKIP_ALL_CHECKS=$(dokku config:get $APP DOKKU_SKIP_ALL_CHECKS || true)
|
||||
DOKKU_APP_SKIP_DEFAULT_CHECKS=$(dokku config:get $APP DOKKU_SKIP_DEFAULT_CHECKS || true)
|
||||
DOKKU_GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true)
|
||||
DOKKU_GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true)
|
||||
|
||||
DOKKU_SKIP_ALL_CHECKS=${DOKKU_APP_SKIP_ALL_CHECKS:="$DOKKU_GLOBAL_SKIP_ALL_CHECKS"}
|
||||
DOKKU_SKIP_DEFAULT_CHECKS=${DOKKU_APP_SKIP_DEFAULT_CHECKS:="$DOKKU_GLOBAL_SKIP_DEFAULT_CHECKS"}
|
||||
|
||||
DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy $APP $IMAGE_TAG)
|
||||
|
||||
while read line || [[ -n "$line" ]]; do
|
||||
TRIM=${line%#*}
|
||||
PROC_TYPE=${TRIM%%=*}
|
||||
@@ -93,9 +103,9 @@ case "$1" in
|
||||
DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX"
|
||||
|
||||
# start the app
|
||||
DOCKER_ARGS=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' "
|
||||
DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS"
|
||||
DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' "
|
||||
DOCKER_ARGS+=" --restart=on-failure:$DOKKU_RESTART_LIMIT"
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-deploy $APP $IMAGE_TAG)
|
||||
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
|
||||
BIND_EXTERNAL=$(plugn trigger bind-external-ip $APP)
|
||||
|
||||
@@ -127,14 +137,6 @@ case "$1" in
|
||||
kill -9 $$
|
||||
}
|
||||
|
||||
DOKKU_APP_SKIP_ALL_CHECKS=$(dokku config:get $APP DOKKU_SKIP_ALL_CHECKS || true)
|
||||
DOKKU_APP_SKIP_DEFAULT_CHECKS=$(dokku config:get $APP DOKKU_SKIP_DEFAULT_CHECKS || true)
|
||||
DOKKU_GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true)
|
||||
DOKKU_GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true)
|
||||
|
||||
DOKKU_SKIP_ALL_CHECKS=${DOKKU_APP_SKIP_ALL_CHECKS:="$DOKKU_GLOBAL_SKIP_ALL_CHECKS"}
|
||||
DOKKU_SKIP_DEFAULT_CHECKS=${DOKKU_APP_SKIP_DEFAULT_CHECKS:="$DOKKU_GLOBAL_SKIP_DEFAULT_CHECKS"}
|
||||
|
||||
# run checks first, then post-deploy hooks, which switches Nginx traffic
|
||||
if [[ "$DOKKU_SKIP_ALL_CHECKS" = "true" ]]; then
|
||||
dokku_log_info1 "Skipping pre-flight checks"
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " build release trace delete ls logs run url urls version 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"
|
||||
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
|
||||
|
||||
case "$1" in
|
||||
build)
|
||||
@@ -189,12 +191,22 @@ case "$1" in
|
||||
SCHEME="https"
|
||||
fi
|
||||
|
||||
if [[ -f "$DOKKU_ROOT/VHOST" ]] && [[ "$NO_VHOST" != "1" ]]; then
|
||||
echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
|
||||
else
|
||||
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
|
||||
for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
|
||||
echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE")"
|
||||
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
|
||||
done
|
||||
|
||||
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
|
||||
;;
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " events events:on events:off events:list help events:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
PLUGIN_DIR="$(dirname $0)"
|
||||
|
||||
case "$1" in
|
||||
events)
|
||||
if [[ -f $DOKKU_EVENTS_LOGFILE ]]; then
|
||||
@@ -27,6 +26,7 @@ case "$1" in
|
||||
;;
|
||||
|
||||
events:list)
|
||||
PLUGIN_DIR="$(dirname $0)"
|
||||
if [[ "$DOKKU_EVENTS" ]]; then
|
||||
logged="$(find $PLUGIN_DIR -type l -printf '%f ' | sort)"
|
||||
dokku_col_log_info2_quiet "Events currently logged"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " apps apps:create apps:destroy help apps:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " backup:export backup:import help backup:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
CURRENT_BACKUP_VERSION=1
|
||||
|
||||
case "$1" in
|
||||
backup:export)
|
||||
CURRENT_BACKUP_VERSION=1
|
||||
OUTPUT_FILE="$2"
|
||||
BACKUP_DIR="$DOKKU_ROOT"
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " certs:add certs:generate certs:info certs:remove certs:update help certs: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/certs/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
|
||||
|
||||
is_tar_import() {
|
||||
[[ -t 0 ]] && return 1
|
||||
@@ -57,7 +59,7 @@ certs_set() {
|
||||
mv "$KEY_FILE" "$DOKKU_ROOT/$APP/tls/server.key"
|
||||
cd $DOKKU_ROOT
|
||||
rm -rf $TEMP_DIR
|
||||
dokku nginx:build-config $APP
|
||||
nginx_build_config $APP
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
@@ -84,7 +86,7 @@ case "$1" in
|
||||
mkdir -p "$DOKKU_ROOT/$APP/tls"
|
||||
dokku_log_info1 "Installing certificate and key..."
|
||||
mv -f $TMP_WORK_DIR/server.key $TMP_WORK_DIR/server.crt $SSL_PATH
|
||||
[[ -n "$DOMAIN" ]] && (dokku domains:add $APP $DOMAIN || dokku nginx:build-config $APP)
|
||||
[[ -n "$DOMAIN" ]] && (dokku domains:add $APP $DOMAIN || nginx_build_config $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."
|
||||
|
||||
@@ -330,3 +330,15 @@ docker_cleanup() {
|
||||
# shellcheck disable=SC2046
|
||||
docker rmi $(docker images -f 'dangling=true' -q) &> /dev/null &
|
||||
}
|
||||
|
||||
get_available_port() {
|
||||
while true; do
|
||||
local port=$(shuf -i 1025-65535 -n 1)
|
||||
if ! nc -z 0.0.0.0 $port; then
|
||||
echo $port
|
||||
return 0
|
||||
else
|
||||
continue
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " config config:get config:set config:unset help config: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"
|
||||
|
||||
@@ -214,6 +214,7 @@ config_unset() {
|
||||
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
|
||||
|
||||
if [[ "$DOKKU_CONFIG_RESTART" == "true" ]]; then
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " docker-options docker-options:add docker-options:remove help docker-options:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
PHASES=(build deploy run)
|
||||
|
||||
FILE_PREFIX="DOCKER_OPTIONS_"
|
||||
|
||||
get_app() {
|
||||
[[ -z $1 ]] && dokku_log_fail "Please specify an app to run the command on"
|
||||
verify_app_name "$1"
|
||||
@@ -25,17 +22,19 @@ get_phases() {
|
||||
|
||||
verify_phase() {
|
||||
local phase
|
||||
for phase in "${PHASES[@]}"; do
|
||||
local phases=(build deploy run)
|
||||
for phase in "${phases[@]}"; do
|
||||
if [[ "$phase" = "$1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
dokku_log_fail "Phase(s) must be one of [${PHASES[@]}]"
|
||||
dokku_log_fail "Phase(s) must be one of [${phases[@]}]"
|
||||
}
|
||||
|
||||
get_phase_file_path() {
|
||||
local phase=$1
|
||||
phase_file_path="${DOKKU_ROOT}/${APP}/${FILE_PREFIX}${phase^^}"
|
||||
local prefix="DOCKER_OPTIONS_"
|
||||
phase_file_path="${DOKKU_ROOT}/${APP}/${prefix}${phase^^}"
|
||||
}
|
||||
|
||||
create_phase_file_if_required() {
|
||||
@@ -53,7 +52,8 @@ display_phase_options() {
|
||||
}
|
||||
|
||||
display_all_phases_options() {
|
||||
for phase in "${PHASES[@]}"; do
|
||||
local phases=(build deploy run)
|
||||
for phase in "${phases[@]}"; do
|
||||
get_phase_file_path $phase
|
||||
if [[ -s $phase_file_path ]]; then
|
||||
display_phase_options $phase $phase_file_path
|
||||
@@ -139,7 +139,7 @@ case "$1" in
|
||||
;;
|
||||
|
||||
# Display usage help
|
||||
help)
|
||||
help | docker-options:help)
|
||||
cat<<EOF
|
||||
docker-options <app>, Display apps docker options for all phases
|
||||
docker-options <app> <phase(s)>, Display apps docker options for phase (comma separated phase list)
|
||||
|
||||
@@ -1,28 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " domains domains:setup domains:add domains:clear domains:remove 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/config/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
|
||||
|
||||
RE_IPV4="([0-9]{1,3}[\.]){3}[0-9]{1,3}"
|
||||
|
||||
RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
|
||||
|
||||
# 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
|
||||
RE_IPV4="${RE_IPV4}\$"
|
||||
RE_IPV6="${RE_IPV6}\$"
|
||||
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
|
||||
|
||||
case "$1" in
|
||||
domains)
|
||||
@@ -43,6 +24,7 @@ case "$1" in
|
||||
[[ -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
|
||||
@@ -52,7 +34,7 @@ case "$1" in
|
||||
fi
|
||||
if [[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]]; then
|
||||
dokku_log_info2 "unsupported vhost config found. disabling vhost support"
|
||||
config_set --no-restart $APP NO_VHOST=1
|
||||
disable_app_vhost $APP --no-restart $APP
|
||||
else
|
||||
if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
|
||||
dokku_log_info1 "Creating new $VHOST_PATH..."
|
||||
@@ -94,7 +76,7 @@ case "$1" in
|
||||
echo "$DOMAIN" >> "$DOKKU_ROOT/$APP/VHOST"
|
||||
done
|
||||
# we need to restart the app to make sure we're binding to the appropriate network interface
|
||||
dokku nginx:build-config $APP
|
||||
nginx_build_config $APP
|
||||
plugn trigger post-domains-update $APP
|
||||
for DOMAIN in "$@"; do
|
||||
dokku_log_info1 "Added $DOMAIN to $APP"
|
||||
|
||||
@@ -3,6 +3,9 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
get_app_domains() {
|
||||
local APP=$1; verify_app_name $APP
|
||||
cat "$DOKKU_ROOT/$APP/VHOST"
|
||||
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"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " enter help enter:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
|
||||
@@ -1,41 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
|
||||
|
||||
APP="$1"
|
||||
NO_VHOST=$(config_get $APP NO_VHOST || true)
|
||||
|
||||
RE_IPV4="([0-9]{1,3}[\.]){3}[0-9]{1,3}"
|
||||
|
||||
RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
|
||||
|
||||
|
||||
# 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
|
||||
RE_IPV4="${RE_IPV4}\$"
|
||||
RE_IPV6="${RE_IPV6}\$"
|
||||
|
||||
[[ -f "$DOKKU_ROOT/VHOST" ]] && GLOBAL_VHOST=$(< "$DOKKU_ROOT/VHOST")
|
||||
|
||||
if [[ -n "$NO_VHOST" ]]; then
|
||||
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
|
||||
echo true # bind to external ip. VHOST is disabled
|
||||
elif [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
|
||||
echo true # bind to external ip. GLOBAL_VHOST is somehow an IPv4 or IPv6 address
|
||||
elif [[ -z "$GLOBAL_VHOST" ]] && [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
echo true # bind to external ip. no GLOBAL_VHOST and no app vhost
|
||||
elif [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
|
||||
echo false # bind to docker ip. this app has a vhost defined
|
||||
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
|
||||
|
||||
@@ -1,168 +1,17 @@
|
||||
#!/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
|
||||
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"
|
||||
|
||||
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
|
||||
}
|
||||
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}"
|
||||
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="$2"; DOKKU_APP_LISTEN_PORT="$3"; DOKKU_APP_LISTEN_IP="$4"
|
||||
|
||||
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)
|
||||
nginx_build_config $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP
|
||||
|
||||
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="$(dirname $0)/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"
|
||||
if [[ -n "$DOKKU_SSL_TERMINATED" ]] && [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
|
||||
NGINX_TEMPLATE="$(dirname $0)/templates/nginx.conf.ssl_terminated.template"
|
||||
elif [[ -z "$NGINX_CUSTOM_TEMPLATE" ]]; then
|
||||
NGINX_TEMPLATE="$(dirname $0)/templates/nginx.conf.template"
|
||||
fi
|
||||
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"
|
||||
plugn trigger 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:access-logs|nginx:error-logs)
|
||||
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
|
||||
@@ -180,18 +29,50 @@ EOF
|
||||
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)" == "true" ]]; then
|
||||
config_unset --no-restart $APP DOKKU_NO_NGINX
|
||||
unset DOKKU_NO_NGINX
|
||||
nginx_build_config $APP
|
||||
else
|
||||
dokku_log_info1 "nginx is already enabled for app ($APP)"
|
||||
fi
|
||||
;;
|
||||
|
||||
help | nginx:help)
|
||||
cat<<EOF
|
||||
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
|
||||
;;
|
||||
;;
|
||||
|
||||
*)
|
||||
exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
;;
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
293
plugins/nginx-vhosts/functions
Executable file
293
plugins/nginx-vhosts/functions
Executable file
@@ -0,0 +1,293 @@
|
||||
#!/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"
|
||||
|
||||
_ipv4_regex() {
|
||||
echo "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
|
||||
}
|
||||
|
||||
_ipv6_regex() {
|
||||
local RE_IPV4="$(_ipv4_regex)"
|
||||
local RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
|
||||
echo "$RE_IPV6"
|
||||
}
|
||||
|
||||
get_ipv4_regex() {
|
||||
local RE_IPV4="$(_ipv4_regex)"
|
||||
# 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
|
||||
echo "${RE_IPV4}\$"
|
||||
}
|
||||
|
||||
get_ipv6_regex() {
|
||||
local RE_IPV6="$(_ipv4_regex)"
|
||||
# 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
|
||||
echo "${RE_IPV6}\$"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
eval "$(config_export global)"
|
||||
eval "$(config_export app $APP)"
|
||||
|
||||
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=$(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
|
||||
|
||||
[[ -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
|
||||
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}
|
||||
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"
|
||||
|
||||
[[ -z "$NGINX_TEMPLATE" ]] && NGINX_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)
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
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 "$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 {}..." <<< "$NONSSL_VHOSTS"
|
||||
fi
|
||||
eval "cat <<< \"$(< $NGINX_TEMPLATE)\" >> $NGINX_CONF"
|
||||
if [[ "$(is_app_vhost_enabled $APP)" == "false" ]] || ([[ -z "$NONSSL_VHOSTS" ]] && [[ -z "$SSL_VHOSTS" ]]); then
|
||||
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
|
||||
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
|
||||
|
||||
if [[ "$(is_app_vhost_enabled $APP)" == "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
|
||||
fi
|
||||
else
|
||||
# note because this clause is long. if $DOKKU_NO_NGINX 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"
|
||||
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
|
||||
}
|
||||
@@ -1,17 +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"
|
||||
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
|
||||
|
||||
APP="$1"
|
||||
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then
|
||||
NO_VHOST=$(config_get $APP NO_VHOST || true)
|
||||
|
||||
if [[ -n "$NO_VHOST" ]]; then
|
||||
dokku_log_info1 "NO_VHOST config detected"
|
||||
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
|
||||
fi
|
||||
|
||||
dokku nginx:build-config $APP
|
||||
nginx_build_config $APP
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/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"
|
||||
|
||||
APP="$1"
|
||||
|
||||
dokku nginx:build-config $APP
|
||||
nginx_build_config $APP
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Nginx configuration when running behind a load balancer that terminates SSL
|
||||
# connections (e.g. AWS ELB)
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
listen [::]:$NGINX_PORT;
|
||||
listen $NGINX_PORT;
|
||||
server_name $NOSSL_SERVER_NAME;
|
||||
location / {
|
||||
proxy_pass http://$APP;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
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;
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
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\$request_uri;
|
||||
return 301 https://\$host:$NGINX_SSL_PORT\$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen [::]:443 ssl spdy;
|
||||
listen 443 ssl spdy;
|
||||
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 443:npn-spdy/2;
|
||||
add_header Alternate-Protocol $NGINX_SSL_PORT:npn-spdy/2;
|
||||
location / {
|
||||
|
||||
gzip on;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " plugin plugin:install plugin:install-dependencies plugin:update plugin:disable plugin:enable plugin:uninstall help plugin: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/plugin/functions"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " ps ps:start ps:stop ps:rebuild ps:rebuildall ps:restart ps:restartall ps:scale 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/ps/functions"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " shell help shell:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
case "$1" in
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " tags tags:create tags:deploy tags:destroy help tags: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/tags/functions"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " tar-from tar:from tar-in tar:in tar-build tar-build-locked help tar:help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
@@ -57,7 +58,7 @@ case "$1" in
|
||||
fi
|
||||
;;
|
||||
|
||||
help)
|
||||
help | tar:help)
|
||||
cat && cat<<EOF
|
||||
tar:in <app>, Reads an tarball containing the app from stdin
|
||||
tar:from <app> <url>, Loads an app tarball from url.
|
||||
|
||||
@@ -142,16 +142,6 @@ check_urls() {
|
||||
check_urls http://www.test.app.dokku.me
|
||||
}
|
||||
|
||||
@test "(core) dockerfile port exposure" {
|
||||
deploy_app dockerfile
|
||||
run bash -c "grep -A1 upstream $DOKKU_ROOT/$TEST_APP/nginx.conf | grep -q 3000"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
|
||||
check_urls http://${TEST_APP}.dokku.me
|
||||
}
|
||||
|
||||
@test "(core) port exposure (xip.io style hostnames)" {
|
||||
echo "127.0.0.1.xip.io" > "$DOKKU_ROOT/VHOST"
|
||||
deploy_app
|
||||
@@ -164,6 +154,16 @@ check_urls() {
|
||||
check_urls http://my-cool-guy-test-app.127.0.0.1.xip.io
|
||||
}
|
||||
|
||||
@test "(core) dockerfile port exposure" {
|
||||
deploy_app dockerfile
|
||||
run bash -c "grep -A1 upstream $DOKKU_ROOT/$TEST_APP/nginx.conf | grep -q 3000"
|
||||
echo "output: "$output
|
||||
echo "status: "$status
|
||||
assert_success
|
||||
|
||||
check_urls http://${TEST_APP}.dokku.me
|
||||
}
|
||||
|
||||
@test "(core) port exposure (dockerfile raw port)" {
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
cat<<EOF > $DOCKERFILE
|
||||
|
||||
@@ -18,7 +18,7 @@ teardown() {
|
||||
assert_ssl_domain() {
|
||||
local domain=$1
|
||||
assert_app_domain "${domain}"
|
||||
assert_http_redirect "http://${domain}" "https://${domain}/"
|
||||
assert_http_redirect "http://${domain}" "https://${domain}:443/"
|
||||
assert_http_success "https://${domain}"
|
||||
}
|
||||
|
||||
|
||||
@@ -175,20 +175,20 @@ custom_ssl_nginx_template() {
|
||||
[[ -z "$APP" ]] && APP="$TEST_APP"
|
||||
cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf.template
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
listen [::]:\$NGINX_PORT;
|
||||
listen \$NGINX_PORT;
|
||||
server_name \$NOSSL_SERVER_NAME;
|
||||
return 301 https://\$SSL_SERVER_NAME\\\$request_uri;
|
||||
return 301 https://\\\$host:\$NGINX_SSL_PORT\\\$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen [::]:443 ssl spdy;
|
||||
listen 443 ssl spdy;
|
||||
listen [::]:\$NGINX_SSL_PORT ssl spdy;
|
||||
listen \$NGINX_SSL_PORT ssl spdy;
|
||||
server_name \$SSL_SERVER_NAME;
|
||||
\$SSL_DIRECTIVES
|
||||
|
||||
keepalive_timeout 70;
|
||||
add_header Alternate-Protocol 443:npn-spdy/2;
|
||||
add_header Alternate-Protocol \$NGINX_SSL_PORT:npn-spdy/2;
|
||||
location / {
|
||||
proxy_pass http://\$APP;
|
||||
proxy_http_version 1.1;
|
||||
@@ -210,8 +210,8 @@ custom_nginx_template() {
|
||||
[[ -z "$APP" ]] && APP="$TEST_APP"
|
||||
cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf.template
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
listen [::]:\$NGINX_PORT;
|
||||
listen \$NGINX_PORT;
|
||||
server_name \$NOSSL_SERVER_NAME;
|
||||
|
||||
location / {
|
||||
|
||||
Reference in New Issue
Block a user