-
Notifications
You must be signed in to change notification settings - Fork 26
/
post-deploy
executable file
·127 lines (107 loc) · 5.33 KB
/
post-deploy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
set -a #export all subsequently defined variables for template access
# Bash templating snippet from: http://stackoverflow.com/a/2916159/66771
# NOTE: Template variables must be exported (done with set -a above) and placed
# in brackets (like ${...}) for the regex to process it.
shopt -s expand_aliases
alias process_template="perl -p -e 's/\\$\{([^}]+)\}/defined \$ENV{\$1} ? \$ENV{\$1} : \$&/eg'"
echo "-----> Deploying nginx..."
APP="$1"; PORT="$2"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #this directory
APP_PATH="$DOKKU_ROOT/$APP"
VHOST_PATH="$APP_PATH/VHOST"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
APP_SSL_PATH="$APP_PATH/tls"
# Get list of VHOST domains. This will be overridden below if SSL for some
# domains are enabled. If VHOST does not exist, set to empty string.
NONSSL_VHOSTS=`cat $VHOST_PATH 2>&- || echo ''`
# Load app config variables such that the template can access them like:
# ${MY_VAR}.
source $APP_PATH/ENV || true
# Remove old nginx.conf if exists
rm -f $APP_PATH/nginx.conf #need -f to supress error if non-existent file
# Add once-off configuration options.
echo '-----> Configuring once-off options...'
NGINX_ONCE_CONF="$DIR/nginx.once.conf"
APP_NGINX_ONCE_TEMPLATE="$APP_PATH/nginx.once.tpl"
if [[ -e $APP_NGINX_ONCE_TEMPLATE ]]; then
echo '-----> Overriding default nginx.once.conf with detected nginx.once.tpl'
NGINX_ONCE_CONF=$APP_NGINX_ONCE_TEMPLATE
fi
cat $NGINX_ONCE_CONF | process_template >> $APP_PATH/nginx.conf
# Check if SSL should be enabled. If there are $DOKKU_ROOT/tls certificates,
# try to use those. If the app has an tls/ directory, these override the root
# ssl certificates.
SSL_PATH=$WILDCARD_SSL_PATH
if [[ -e "$APP_SSL_PATH/server.crt" ]] && [[ -e "$APP_SSL_PATH/server.key" ]]; then
SSL_PATH=$APP_SSL_PATH
fi
if [[ -e "$SSL_PATH/server.crt" ]] && [[ -e "$SSL_PATH/server.key" ]]; then
NGINX_CONF="$DIR/nginx.ssl.conf" #default SSL conf file
# Ability to override default configuration files
# (If a nginx.ssl.tpl file exists in the $APP_PATH directory, use that
# instead.)
APP_NGINX_SSL_TEMPLATE="$APP_PATH/nginx.ssl.tpl"
if [[ -e $APP_NGINX_SSL_TEMPLATE ]]; then
echo '-----> Overriding default SSL nginx.conf with detected nginx.ssl.tpl'
NGINX_CONF=$APP_NGINX_SSL_TEMPLATE
fi
# Get the SSL certificate domain name and prepare it so that it satisfies
# grep's regex syntax.
# e.g. mydomain.com -> mydomain\.com
# *.mydomain.com -> .*\.mydomain\.com
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'`
SSL_HOSTNAME=`echo "$SSL_HOSTNAME $SSL_HOSTNAME_ALT" | tr ' ', '\n' | sort | uniq`
SSL_HOSTNAME=`echo "$SSL_HOSTNAME" | sed 's|\.|\\.|g' | sed 's/\*/\.\*/g'`
# Only set up SSL for VHOST domains that the SSL certificate apply to.
# (If the SSL certificate is a wildcard subdomain, any VHOST domain that
# satisfies the wildcard is included.)
# grep -v flag means inverse
# || true prevents grep from throwing error, which exits the script
# when there is no match.
SSL_VHOSTS=`grep "$SSL_HOSTNAME" $VHOST_PATH || true`
NONSSL_VHOSTS=`grep -v "$SSL_HOSTNAME" $VHOST_PATH || true`
# For each domain that satisfies the SSL certificate, set up nginx under the
# SSL template.
while read line; do
if [[ -z $line ]]; then continue; fi #ignore blank lines
echo "-----> Configuring SSL for $line..."
SERVER_NAME=$line
cat $NGINX_CONF | process_template >> $APP_PATH/nginx.conf
# CRUDE HACK: Since the `URL` file only expects one app url, we keep
# overwriting the `URL` file with the last processed domain. The URL
# handling should be refactored.
echo "https://$line" > "$DOKKU_ROOT/$APP/URL"
done <<< "$SSL_VHOSTS"
fi
# Now handle non-SSL domains
NGINX_CONF="$DIR/nginx.conf" # default non-SSL conf file
# Ability to override default configuration files
# (If a nginx.tpl file exists in the $APP_PATH directory, use that instead.)
APP_NGINX_TEMPLATE="$APP_PATH/nginx.tpl"
if [[ -e $APP_NGINX_TEMPLATE ]]; then
echo '-----> Overriding default nginx.conf with detected nginx.tpl'
NGINX_CONF=$APP_NGINX_TEMPLATE
fi
if [[ ! -z "$NONSSL_VHOSTS" ]]; then
# The VHOST file can contain more than one custom domain. We add each as a
# single line to the server_name parameter of nginx instead of creating
# separate server_name entries for each.
echo $NONSSL_VHOSTS | xargs -i \
echo "-----> Configuring {}..."
# Combine all of the VHOST names into one line separated by at least a space.
# Then trim leading and trailing whitespace (xargs). If VHOST file is blank,
# xargs reduces any whitespace to a blank string.
SERVER_NAME=`echo $NONSSL_VHOSTS | tr '\n' ' ' | xargs`
cat $NGINX_CONF | process_template >> $APP_PATH/nginx.conf
fi
# CRUDE HACK: Since the `URL` file only expects one app url, we take the
# first `$NONSSL_VHOSTS` domain and write it to `URL`.
echo "http://$(echo $NONSSL_VHOSTS | head -n1)" > "$DOKKU_ROOT/$APP/URL"
echo "-----> Running nginx-pre-reload"
pluginhook nginx-pre-reload $APP $PORT
echo '-----> Reloading nginx...'
sudo /etc/init.d/nginx reload > /dev/null
cat #prints output from any plugins chained to this