|
1 | 1 | #!/bin/bash |
2 | | -set -euo pipefail |
| 2 | +set -eo pipefail |
3 | 3 |
|
4 | | -dockerize -template /kool/kool.tmpl:/usr/local/etc/php/conf.d/kool.ini -template /kool/zz-docker.tmpl:/usr/local/etc/php-fpm.d/zz-docker.conf -template /kool/default.tmpl:/etc/nginx/conf.d/default.conf |
| 4 | +# Nginx server config |
| 5 | +dockerize -template /kool/default.tmpl:/etc/nginx/conf.d/default.conf |
5 | 6 |
|
6 | | -# usage: file_env VAR [DEFAULT] |
7 | | -# ie: file_env 'XYZ_DB_PASSWORD' 'example' |
8 | | -# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of |
9 | | -# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) |
10 | | -file_env() { |
11 | | - local var="$1" |
12 | | - local fileVar="${var}_FILE" |
13 | | - local def="${2:-}" |
14 | | - if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then |
15 | | - echo >&2 "error: both $var and $fileVar are set (but are exclusive)" |
16 | | - exit 1 |
17 | | - fi |
18 | | - local val="$def" |
19 | | - if [ "${!var:-}" ]; then |
20 | | - val="${!var}" |
21 | | - elif [ "${!fileVar:-}" ]; then |
22 | | - val="$(< "${!fileVar}")" |
23 | | - fi |
24 | | - export "$var"="$val" |
25 | | - unset "$fileVar" |
26 | | -} |
| 7 | +# Run as current user |
| 8 | +CURRENT_USER=${ASUSER:-${UID:-0}} |
27 | 9 |
|
28 | | -if [ "$1" == php-fpm ] || [ "$1" == supervisord ]; then |
29 | | - if [ "$(id -u)" = '0' ]; then |
30 | | - user='kool' |
31 | | - group='kool' |
32 | | - else |
33 | | - user="$(id -u)" |
34 | | - group="$(id -g)" |
35 | | - fi |
36 | | - |
37 | | - if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then |
38 | | - # if the directory exists and WordPress doesn't appear to be installed AND the permissions of it are root:root, let's chown it (likely a Docker-created directory) |
39 | | - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then |
40 | | - chown "$user:$group" . |
41 | | - fi |
42 | | - |
43 | | - echo >&2 "WordPress not found in $PWD - copying now..." |
44 | | - if [ -n "$(find -mindepth 1 -maxdepth 1 -not -name wp-content)" ]; then |
45 | | - echo >&2 "WARNING: $PWD is not empty! (copying anyhow)" |
46 | | - fi |
47 | | - sourceTarArgs=( |
48 | | - --create |
49 | | - --file - |
50 | | - --directory /kool/wordpress |
51 | | - --owner "$user" --group "$group" |
52 | | - ) |
53 | | - targetTarArgs=( |
54 | | - --extract |
55 | | - --file - |
56 | | - ) |
57 | | - if [ "$user" != '0' ]; then |
58 | | - # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" |
59 | | - targetTarArgs+=( --no-overwrite-dir ) |
60 | | - fi |
61 | | - # loop over "pluggable" content in the source, and if it already exists in the destination, skip it |
62 | | - # https://github.com/docker-library/wordpress/issues/506 ("wp-content" persisted, "akismet" updated, WordPress container restarted/recreated, "akismet" downgraded) |
63 | | - for contentDir in /kool/wordpress/wp-content/*/*/; do |
64 | | - contentDir="${contentDir%/}" |
65 | | - [ -d "$contentDir" ] || continue |
66 | | - contentPath="${contentDir#/kool/wordpress/}" # "wp-content/plugins/akismet", etc. |
67 | | - if [ -d "$PWD/$contentPath" ]; then |
68 | | - echo >&2 "WARNING: '$PWD/$contentPath' exists! (not copying the WordPress version)" |
69 | | - sourceTarArgs+=( --exclude "./$contentPath" ) |
70 | | - fi |
71 | | - done |
72 | | - tar "${sourceTarArgs[@]}" . | tar "${targetTarArgs[@]}" |
73 | | - echo >&2 "Complete! WordPress has been successfully copied to $PWD" |
74 | | - if [ ! -e .htaccess ]; then |
75 | | - # NOTE: The "Indexes" option is disabled in the php:apache base image |
76 | | - cat > .htaccess <<-'EOF' |
77 | | - # BEGIN WordPress |
78 | | - <IfModule mod_rewrite.c> |
79 | | - RewriteEngine On |
80 | | - RewriteBase / |
81 | | - RewriteRule ^index\.php$ - [L] |
82 | | - RewriteCond %{REQUEST_FILENAME} !-f |
83 | | - RewriteCond %{REQUEST_FILENAME} !-d |
84 | | - RewriteRule . /index.php [L] |
85 | | - </IfModule> |
86 | | - # END WordPress |
87 | | - EOF |
88 | | - chown "$user:$group" .htaccess |
89 | | - fi |
90 | | - fi |
91 | | - |
92 | | - # allow any of these "Authentication Unique Keys and Salts." to be specified via |
93 | | - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") |
94 | | - uniqueEnvs=( |
95 | | - AUTH_KEY |
96 | | - SECURE_AUTH_KEY |
97 | | - LOGGED_IN_KEY |
98 | | - NONCE_KEY |
99 | | - AUTH_SALT |
100 | | - SECURE_AUTH_SALT |
101 | | - LOGGED_IN_SALT |
102 | | - NONCE_SALT |
103 | | - ) |
104 | | - envs=( |
105 | | - WORDPRESS_DB_HOST |
106 | | - WORDPRESS_DB_USER |
107 | | - WORDPRESS_DB_PASSWORD |
108 | | - WORDPRESS_DB_NAME |
109 | | - WORDPRESS_DB_CHARSET |
110 | | - WORDPRESS_DB_COLLATE |
111 | | - "${uniqueEnvs[@]/#/WORDPRESS_}" |
112 | | - WORDPRESS_TABLE_PREFIX |
113 | | - WORDPRESS_DEBUG |
114 | | - WORDPRESS_CONFIG_EXTRA |
115 | | - ) |
116 | | - haveConfig= |
117 | | - for e in "${envs[@]}"; do |
118 | | - file_env "$e" |
119 | | - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then |
120 | | - haveConfig=1 |
121 | | - fi |
122 | | - done |
123 | | - |
124 | | - # linking backwards-compatibility |
125 | | - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then |
126 | | - haveConfig=1 |
127 | | - # host defaults to "mysql" below if unspecified |
128 | | - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" |
129 | | - if [ "$WORDPRESS_DB_USER" = 'root' ]; then |
130 | | - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" |
131 | | - else |
132 | | - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" |
133 | | - fi |
134 | | - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" |
135 | | - fi |
136 | | - |
137 | | - # only touch "wp-config.php" if we have environment-supplied configuration values |
138 | | - if [ "$haveConfig" ]; then |
139 | | - : "${WORDPRESS_DB_HOST:=mysql}" |
140 | | - : "${WORDPRESS_DB_USER:=root}" |
141 | | - : "${WORDPRESS_DB_PASSWORD:=}" |
142 | | - : "${WORDPRESS_DB_NAME:=wordpress}" |
143 | | - : "${WORDPRESS_DB_CHARSET:=utf8}" |
144 | | - : "${WORDPRESS_DB_COLLATE:=}" |
145 | | - |
146 | | - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks |
147 | | - # https://github.com/docker-library/wordpress/issues/116 |
148 | | - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 |
149 | | - sed -ri -e 's/\r$//' wp-config* |
150 | | - |
151 | | - if [ ! -e wp-config.php ]; then |
152 | | - awk ' |
153 | | - /^\/\*.*stop editing.*\*\/$/ && c == 0 { |
154 | | - c = 1 |
155 | | - system("cat") |
156 | | - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { |
157 | | - print "// WORDPRESS_CONFIG_EXTRA" |
158 | | - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" |
159 | | - } |
160 | | - } |
161 | | - { print } |
162 | | - ' wp-config-sample.php > wp-config.php <<'EOPHP' |
163 | | -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact |
164 | | -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy |
165 | | -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { |
166 | | - $_SERVER['HTTPS'] = 'on'; |
167 | | -} |
168 | | -
|
169 | | -EOPHP |
170 | | - chown "$user:$group" wp-config.php |
171 | | - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then |
172 | | - # (if the config file already contains the requested PHP code, don't print a warning) |
173 | | - echo >&2 |
174 | | - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' |
175 | | - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' |
176 | | - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' |
177 | | - echo >&2 |
178 | | - fi |
179 | | - |
180 | | - # see http://stackoverflow.com/a/2705678/433558 |
181 | | - sed_escape_lhs() { |
182 | | - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' |
183 | | - } |
184 | | - sed_escape_rhs() { |
185 | | - echo "$@" | sed -e 's/[\/&]/\\&/g' |
186 | | - } |
187 | | - php_escape() { |
188 | | - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" |
189 | | - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then |
190 | | - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" |
191 | | - fi |
192 | | - echo "$escaped" |
193 | | - } |
194 | | - set_config() { |
195 | | - key="$1" |
196 | | - value="$2" |
197 | | - var_type="${3:-string}" |
198 | | - start="(['\"])$(sed_escape_lhs "$key")\2\s*," |
199 | | - end="\);" |
200 | | - if [ "${key:0:1}" = '$' ]; then |
201 | | - start="^(\s*)$(sed_escape_lhs "$key")\s*=" |
202 | | - end=";" |
203 | | - fi |
204 | | - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php |
205 | | - } |
206 | | - |
207 | | - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" |
208 | | - set_config 'DB_USER' "$WORDPRESS_DB_USER" |
209 | | - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" |
210 | | - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" |
211 | | - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" |
212 | | - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" |
213 | | - |
214 | | - for unique in "${uniqueEnvs[@]}"; do |
215 | | - uniqVar="WORDPRESS_$unique" |
216 | | - if [ -n "${!uniqVar}" ]; then |
217 | | - set_config "$unique" "${!uniqVar}" |
218 | | - else |
219 | | - # if not specified, let's generate a random value |
220 | | - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" |
221 | | - if [ "$currentVal" = 'put your unique phrase here' ]; then |
222 | | - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" |
223 | | - fi |
224 | | - fi |
225 | | - done |
226 | | - |
227 | | - if [ "$WORDPRESS_TABLE_PREFIX" ]; then |
228 | | - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" |
229 | | - fi |
230 | | - |
231 | | - if [ "$WORDPRESS_DEBUG" ]; then |
232 | | - set_config 'WP_DEBUG' 1 boolean |
233 | | - fi |
234 | | - |
235 | | - if ! TERM=dumb php -- <<'EOPHP' |
236 | | -{!! '<?php' !!} |
237 | | -// database might not exist, so let's try creating it (just to be safe) |
238 | | -
|
239 | | -$stderr = fopen('php://stderr', 'w'); |
240 | | -
|
241 | | -// https://codex.wordpress.org/Editing_wp-config.php#MySQL_Alternate_Port |
242 | | -// "hostname:port" |
243 | | -// https://codex.wordpress.org/Editing_wp-config.php#MySQL_Sockets_or_Pipes |
244 | | -// "hostname:unix-socket-path" |
245 | | -list($host, $socket) = explode(':', getenv('WORDPRESS_DB_HOST'), 2); |
246 | | -$port = 0; |
247 | | -if (is_numeric($socket)) { |
248 | | - $port = (int) $socket; |
249 | | - $socket = null; |
250 | | -} |
251 | | -$user = getenv('WORDPRESS_DB_USER'); |
252 | | -$pass = getenv('WORDPRESS_DB_PASSWORD'); |
253 | | -$dbName = getenv('WORDPRESS_DB_NAME'); |
254 | | -
|
255 | | -$maxTries = 10; |
256 | | -do { |
257 | | - $mysql = new mysqli($host, $user, $pass, '', $port, $socket); |
258 | | - if ($mysql->connect_error) { |
259 | | - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); |
260 | | - --$maxTries; |
261 | | - if ($maxTries <= 0) { |
262 | | - exit(1); |
263 | | - } |
264 | | - sleep(3); |
265 | | - } |
266 | | -} while ($mysql->connect_error); |
267 | | -
|
268 | | -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { |
269 | | - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); |
270 | | - $mysql->close(); |
271 | | - exit(1); |
272 | | -} |
273 | | -
|
274 | | -$mysql->close(); |
275 | | -EOPHP |
276 | | - then |
277 | | - echo >&2 |
278 | | - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" |
279 | | - echo >&2 ' continuing anyways (which might have unexpected results)' |
280 | | - echo >&2 |
281 | | - fi |
282 | | - fi |
| 10 | +if [ ! -z "$CURRENT_USER" ] && [ "$CURRENT_USER" != "0" ]; then |
| 11 | + usermod -u $CURRENT_USER kool |
| 12 | +fi |
283 | 13 |
|
284 | | - # now that we're definitely done writing configuration, let's clear out the relevant envrionment variables (so that stray "phpinfo()" calls don't leak secrets from our code) |
285 | | - for e in "${envs[@]}"; do |
286 | | - unset "$e" |
287 | | - done |
| 14 | +# user/group for Wordpress |
| 15 | +user=kool |
| 16 | +group=kool |
| 17 | +uid=$(id -u) |
| 18 | + |
| 19 | +if [ "$1" = "php-fpm" ] || [ "$1" = "supervisord" ]; then |
| 20 | + # Original Wordpress Entrypoint - fresh install if none exists |
| 21 | + if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then |
| 22 | + # if the directory exists and WordPress doesn't appear to be installed AND the permissions of it are root:root, let's chown it (likely a Docker-created directory) |
| 23 | + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then |
| 24 | + chown "$user:$group" . |
| 25 | + fi |
| 26 | + |
| 27 | + echo >&2 "WordPress not found in $PWD - copying now..." |
| 28 | + if [ -n "$(find -mindepth 1 -maxdepth 1 -not -name wp-content)" ]; then |
| 29 | + echo >&2 "WARNING: $PWD is not empty! (copying anyhow)" |
| 30 | + fi |
| 31 | + sourceTarArgs=( |
| 32 | + --create |
| 33 | + --file - |
| 34 | + --directory /kool/wordpress |
| 35 | + --owner "$user" --group "$group" |
| 36 | + ) |
| 37 | + targetTarArgs=( |
| 38 | + --extract |
| 39 | + --file - |
| 40 | + ) |
| 41 | + if [ "$uid" != '0' ]; then |
| 42 | + # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" |
| 43 | + targetTarArgs+=( --no-overwrite-dir ) |
| 44 | + fi |
| 45 | + # loop over "pluggable" content in the source, and if it already exists in the destination, skip it |
| 46 | + # https://github.com/docker-library/wordpress/issues/506 ("wp-content" persisted, "akismet" updated, WordPress container restarted/recreated, "akismet" downgraded) |
| 47 | + for contentPath in \ |
| 48 | + /kool/wordpress/.htaccess \ |
| 49 | + /kool/wordpress/wp-content/*/*/ \ |
| 50 | + ; do |
| 51 | + contentPath="${contentPath%/}" |
| 52 | + [ -e "$contentPath" ] || continue |
| 53 | + contentPath="${contentPath#/kool/wordpress/}" # "wp-content/plugins/akismet", etc. |
| 54 | + if [ -e "$PWD/$contentPath" ]; then |
| 55 | + echo >&2 "WARNING: '$PWD/$contentPath' exists! (not copying the WordPress version)" |
| 56 | + sourceTarArgs+=( --exclude "./$contentPath" ) |
| 57 | + fi |
| 58 | + done |
| 59 | + tar "${sourceTarArgs[@]}" . | tar "${targetTarArgs[@]}" |
| 60 | + chown -R "$user:$group" /app |
| 61 | + echo >&2 "Complete! WordPress has been successfully copied to $PWD" |
| 62 | + fi |
| 63 | + |
| 64 | + wpEnvs=( "${!WORDPRESS_@}" ) |
| 65 | + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then |
| 66 | + for wpConfigDocker in \ |
| 67 | + wp-config-docker.php \ |
| 68 | + /kool/wordpress/wp-config-docker.php \ |
| 69 | + ; do |
| 70 | + if [ -s "$wpConfigDocker" ]; then |
| 71 | + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" |
| 72 | + # using "awk" to replace all instances of "put your unique phrase here" with a properly unique string (for AUTH_KEY and friends to have safe defaults if they aren't specified with environment variables) |
| 73 | + awk ' |
| 74 | + /put your unique phrase here/ { |
| 75 | + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" |
| 76 | + cmd | getline str |
| 77 | + close(cmd) |
| 78 | + gsub("put your unique phrase here", str) |
| 79 | + } |
| 80 | + { print } |
| 81 | + ' "$wpConfigDocker" > wp-config.php |
| 82 | + if [ "$uid" = '0' ]; then |
| 83 | + # attempt to ensure that wp-config.php is owned by the run user |
| 84 | + # could be on a filesystem that doesn't allow chown (like some NFS setups) |
| 85 | + chown "$user:$group" wp-config.php || true |
| 86 | + fi |
| 87 | + break |
| 88 | + fi |
| 89 | + done |
| 90 | + fi |
288 | 91 | fi |
289 | 92 |
|
290 | | -exec "$@" |
| 93 | +exec /kool/entrypoint "$@" |
0 commit comments