diff --git a/.gitattributes b/.gitattributes index 9396a6bec9..3395257686 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ /*/**/Dockerfile linguist-generated /*/**/docker-entrypoint.sh linguist-generated +/*/**/wp-config-docker.php linguist-generated /Dockerfile.template linguist-language=Dockerfile diff --git a/Dockerfile.template b/Dockerfile.template index 705a21b462..a12053ced0 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -229,6 +229,9 @@ RUN set -ex; \ VOLUME /var/www/html +{{ if env.version == "beta" then ( -}} +COPY --chown=www-data:www-data wp-config-docker.php /usr/src/wordpress/ +{{ ) else "" end -}} COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/apply-templates.sh b/apply-templates.sh index ed3ad604ce..0d820fbdd6 100755 --- a/apply-templates.sh +++ b/apply-templates.sh @@ -52,6 +52,9 @@ for version; do if [ "$version" = 'cli' ]; then cp -a cli-entrypoint.sh "$dir/docker-entrypoint.sh" + elif [ "$version" = 'beta' ]; then + cp -a docker-entrypoint-ng.sh "$dir/docker-entrypoint.sh" + cp -a wp-config-docker.php "$dir/" else cp -a docker-entrypoint.sh "$dir/" fi diff --git a/beta/php7.3/apache/Dockerfile b/beta/php7.3/apache/Dockerfile index 76401c5b13..47783e7a9e 100644 --- a/beta/php7.3/apache/Dockerfile +++ b/beta/php7.3/apache/Dockerfile @@ -143,6 +143,7 @@ RUN set -eux; \ VOLUME /var/www/html +COPY --chown=www-data:www-data wp-config-docker.php /usr/src/wordpress/ COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/beta/php7.3/apache/docker-entrypoint.sh b/beta/php7.3/apache/docker-entrypoint.sh index 6a40c02b5f..0fca21c79d 100755 --- a/beta/php7.3/apache/docker-entrypoint.sh +++ b/beta/php7.3/apache/docker-entrypoint.sh @@ -1,30 +1,10 @@ -#!/bin/bash -set -euo pipefail +#!/usr/bin/env bash +set -Eeuo pipefail -# usage: file_env VAR [DEFAULT] -# ie: file_env 'XYZ_DB_PASSWORD' 'example' -# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of -# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) -file_env() { - local var="$1" - local fileVar="${var}_FILE" - local def="${2:-}" - if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then - echo >&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then - if [ "$(id -u)" = '0' ]; then +if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then case "$1" in apache2*) user="${APACHE_RUN_USER:-www-data}" @@ -41,13 +21,13 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then ;; esac else - user="$(id -u)" - group="$(id -g)" + user="$uid" + group="$gid" fi if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then # 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) - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then chown "$user:$group" . fi @@ -65,7 +45,7 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then --extract --file - ) - if [ "$user" != '0' ]; then + if [ "$uid" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi @@ -84,202 +64,28 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then echo >&2 "Complete! WordPress has been successfully copied to $PWD" fi - # allow any of these "Authentication Unique Keys and Salts." to be specified via - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - uniqueEnvs=( - AUTH_KEY - SECURE_AUTH_KEY - LOGGED_IN_KEY - NONCE_KEY - AUTH_SALT - SECURE_AUTH_SALT - LOGGED_IN_SALT - NONCE_SALT - ) - envs=( - WORDPRESS_DB_HOST - WORDPRESS_DB_USER - WORDPRESS_DB_PASSWORD - WORDPRESS_DB_NAME - WORDPRESS_DB_CHARSET - WORDPRESS_DB_COLLATE - "${uniqueEnvs[@]/#/WORDPRESS_}" - WORDPRESS_TABLE_PREFIX - WORDPRESS_DEBUG - WORDPRESS_CONFIG_EXTRA - ) - haveConfig= - for e in "${envs[@]}"; do - file_env "$e" - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then - haveConfig=1 - fi - done - - # linking backwards-compatibility - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then - haveConfig=1 - # host defaults to "mysql" below if unspecified - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" - if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - else - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" - fi - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" - fi - - # only touch "wp-config.php" if we have environment-supplied configuration values - if [ "$haveConfig" ]; then - : "${WORDPRESS_DB_HOST:=mysql}" - : "${WORDPRESS_DB_USER:=root}" - : "${WORDPRESS_DB_PASSWORD:=}" - : "${WORDPRESS_DB_NAME:=wordpress}" - : "${WORDPRESS_DB_CHARSET:=utf8}" - : "${WORDPRESS_DB_COLLATE:=}" - - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks - # https://github.com/docker-library/wordpress/issues/116 - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 - sed -ri -e 's/\r$//' wp-config* - - if [ ! -e wp-config.php ]; then - awk ' - /^\/\*.*stop editing.*\*\/$/ && c == 0 { - c = 1 - system("cat") - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { - print "// WORDPRESS_CONFIG_EXTRA" - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) } - } - { print } - ' wp-config-sample.php > wp-config.php <<'EOPHP' -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $_SERVER['HTTPS'] = 'on'; -} - -EOPHP - chown "$user:$group" wp-config.php - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then - # (if the config file already contains the requested PHP code, don't print a warning) - echo >&2 - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' - echo >&2 - fi - - # see http://stackoverflow.com/a/2705678/433558 - sed_escape_lhs() { - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' - } - sed_escape_rhs() { - echo "$@" | sed -e 's/[\/&]/\\&/g' - } - php_escape() { - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" - fi - echo "$escaped" - } - set_config() { - key="$1" - value="$2" - var_type="${3:-string}" - start="(['\"])$(sed_escape_lhs "$key")\2\s*," - end="\);" - if [ "${key:0:1}" = '$' ]; then - start="^(\s*)$(sed_escape_lhs "$key")\s*=" - end=";" - fi - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php - } - - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" - set_config 'DB_USER' "$WORDPRESS_DB_USER" - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" - - for unique in "${uniqueEnvs[@]}"; do - uniqVar="WORDPRESS_$unique" - if [ -n "${!uniqVar}" ]; then - set_config "$unique" "${!uniqVar}" - else - # if not specified, let's generate a random value - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" - if [ "$currentVal" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" - fi + { print } + ' "$wpConfigDocker" > wp-config.php + break fi done - - if [ "$WORDPRESS_TABLE_PREFIX" ]; then - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" - fi - - if [ "$WORDPRESS_DEBUG" ]; then - set_config 'WP_DEBUG' 1 boolean - fi - - if ! TERM=dumb php -- <<'EOPHP' -connect_error) { - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); - --$maxTries; - if ($maxTries <= 0) { - exit(1); - } - sleep(3); - } -} while ($mysql->connect_error); - -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); - $mysql->close(); - exit(1); -} - -$mysql->close(); -EOPHP - then - echo >&2 - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" - echo >&2 ' continuing anyways (which might have unexpected results)' - echo >&2 - fi fi - - # 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) - for e in "${envs[@]}"; do - unset "$e" - done fi exec "$@" diff --git a/beta/php7.3/apache/wp-config-docker.php b/beta/php7.3/apache/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/beta/php7.3/apache/wp-config-docker.php @@ -0,0 +1,120 @@ +&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then - if [ "$(id -u)" = '0' ]; then +if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then case "$1" in apache2*) user="${APACHE_RUN_USER:-www-data}" @@ -41,13 +21,13 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then ;; esac else - user="$(id -u)" - group="$(id -g)" + user="$uid" + group="$gid" fi if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then # 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) - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then chown "$user:$group" . fi @@ -65,7 +45,7 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then --extract --file - ) - if [ "$user" != '0' ]; then + if [ "$uid" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi @@ -84,202 +64,28 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then echo >&2 "Complete! WordPress has been successfully copied to $PWD" fi - # allow any of these "Authentication Unique Keys and Salts." to be specified via - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - uniqueEnvs=( - AUTH_KEY - SECURE_AUTH_KEY - LOGGED_IN_KEY - NONCE_KEY - AUTH_SALT - SECURE_AUTH_SALT - LOGGED_IN_SALT - NONCE_SALT - ) - envs=( - WORDPRESS_DB_HOST - WORDPRESS_DB_USER - WORDPRESS_DB_PASSWORD - WORDPRESS_DB_NAME - WORDPRESS_DB_CHARSET - WORDPRESS_DB_COLLATE - "${uniqueEnvs[@]/#/WORDPRESS_}" - WORDPRESS_TABLE_PREFIX - WORDPRESS_DEBUG - WORDPRESS_CONFIG_EXTRA - ) - haveConfig= - for e in "${envs[@]}"; do - file_env "$e" - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then - haveConfig=1 - fi - done - - # linking backwards-compatibility - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then - haveConfig=1 - # host defaults to "mysql" below if unspecified - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" - if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - else - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" - fi - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" - fi - - # only touch "wp-config.php" if we have environment-supplied configuration values - if [ "$haveConfig" ]; then - : "${WORDPRESS_DB_HOST:=mysql}" - : "${WORDPRESS_DB_USER:=root}" - : "${WORDPRESS_DB_PASSWORD:=}" - : "${WORDPRESS_DB_NAME:=wordpress}" - : "${WORDPRESS_DB_CHARSET:=utf8}" - : "${WORDPRESS_DB_COLLATE:=}" - - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks - # https://github.com/docker-library/wordpress/issues/116 - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 - sed -ri -e 's/\r$//' wp-config* - - if [ ! -e wp-config.php ]; then - awk ' - /^\/\*.*stop editing.*\*\/$/ && c == 0 { - c = 1 - system("cat") - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { - print "// WORDPRESS_CONFIG_EXTRA" - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) } - } - { print } - ' wp-config-sample.php > wp-config.php <<'EOPHP' -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $_SERVER['HTTPS'] = 'on'; -} - -EOPHP - chown "$user:$group" wp-config.php - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then - # (if the config file already contains the requested PHP code, don't print a warning) - echo >&2 - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' - echo >&2 - fi - - # see http://stackoverflow.com/a/2705678/433558 - sed_escape_lhs() { - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' - } - sed_escape_rhs() { - echo "$@" | sed -e 's/[\/&]/\\&/g' - } - php_escape() { - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" - fi - echo "$escaped" - } - set_config() { - key="$1" - value="$2" - var_type="${3:-string}" - start="(['\"])$(sed_escape_lhs "$key")\2\s*," - end="\);" - if [ "${key:0:1}" = '$' ]; then - start="^(\s*)$(sed_escape_lhs "$key")\s*=" - end=";" - fi - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php - } - - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" - set_config 'DB_USER' "$WORDPRESS_DB_USER" - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" - - for unique in "${uniqueEnvs[@]}"; do - uniqVar="WORDPRESS_$unique" - if [ -n "${!uniqVar}" ]; then - set_config "$unique" "${!uniqVar}" - else - # if not specified, let's generate a random value - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" - if [ "$currentVal" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" - fi + { print } + ' "$wpConfigDocker" > wp-config.php + break fi done - - if [ "$WORDPRESS_TABLE_PREFIX" ]; then - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" - fi - - if [ "$WORDPRESS_DEBUG" ]; then - set_config 'WP_DEBUG' 1 boolean - fi - - if ! TERM=dumb php -- <<'EOPHP' -connect_error) { - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); - --$maxTries; - if ($maxTries <= 0) { - exit(1); - } - sleep(3); - } -} while ($mysql->connect_error); - -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); - $mysql->close(); - exit(1); -} - -$mysql->close(); -EOPHP - then - echo >&2 - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" - echo >&2 ' continuing anyways (which might have unexpected results)' - echo >&2 - fi fi - - # 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) - for e in "${envs[@]}"; do - unset "$e" - done fi exec "$@" diff --git a/beta/php7.3/fpm-alpine/wp-config-docker.php b/beta/php7.3/fpm-alpine/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/beta/php7.3/fpm-alpine/wp-config-docker.php @@ -0,0 +1,120 @@ +&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then - if [ "$(id -u)" = '0' ]; then +if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then case "$1" in apache2*) user="${APACHE_RUN_USER:-www-data}" @@ -41,13 +21,13 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then ;; esac else - user="$(id -u)" - group="$(id -g)" + user="$uid" + group="$gid" fi if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then # 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) - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then chown "$user:$group" . fi @@ -65,7 +45,7 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then --extract --file - ) - if [ "$user" != '0' ]; then + if [ "$uid" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi @@ -84,202 +64,28 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then echo >&2 "Complete! WordPress has been successfully copied to $PWD" fi - # allow any of these "Authentication Unique Keys and Salts." to be specified via - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - uniqueEnvs=( - AUTH_KEY - SECURE_AUTH_KEY - LOGGED_IN_KEY - NONCE_KEY - AUTH_SALT - SECURE_AUTH_SALT - LOGGED_IN_SALT - NONCE_SALT - ) - envs=( - WORDPRESS_DB_HOST - WORDPRESS_DB_USER - WORDPRESS_DB_PASSWORD - WORDPRESS_DB_NAME - WORDPRESS_DB_CHARSET - WORDPRESS_DB_COLLATE - "${uniqueEnvs[@]/#/WORDPRESS_}" - WORDPRESS_TABLE_PREFIX - WORDPRESS_DEBUG - WORDPRESS_CONFIG_EXTRA - ) - haveConfig= - for e in "${envs[@]}"; do - file_env "$e" - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then - haveConfig=1 - fi - done - - # linking backwards-compatibility - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then - haveConfig=1 - # host defaults to "mysql" below if unspecified - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" - if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - else - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" - fi - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" - fi - - # only touch "wp-config.php" if we have environment-supplied configuration values - if [ "$haveConfig" ]; then - : "${WORDPRESS_DB_HOST:=mysql}" - : "${WORDPRESS_DB_USER:=root}" - : "${WORDPRESS_DB_PASSWORD:=}" - : "${WORDPRESS_DB_NAME:=wordpress}" - : "${WORDPRESS_DB_CHARSET:=utf8}" - : "${WORDPRESS_DB_COLLATE:=}" - - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks - # https://github.com/docker-library/wordpress/issues/116 - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 - sed -ri -e 's/\r$//' wp-config* - - if [ ! -e wp-config.php ]; then - awk ' - /^\/\*.*stop editing.*\*\/$/ && c == 0 { - c = 1 - system("cat") - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { - print "// WORDPRESS_CONFIG_EXTRA" - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) } - } - { print } - ' wp-config-sample.php > wp-config.php <<'EOPHP' -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $_SERVER['HTTPS'] = 'on'; -} - -EOPHP - chown "$user:$group" wp-config.php - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then - # (if the config file already contains the requested PHP code, don't print a warning) - echo >&2 - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' - echo >&2 - fi - - # see http://stackoverflow.com/a/2705678/433558 - sed_escape_lhs() { - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' - } - sed_escape_rhs() { - echo "$@" | sed -e 's/[\/&]/\\&/g' - } - php_escape() { - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" - fi - echo "$escaped" - } - set_config() { - key="$1" - value="$2" - var_type="${3:-string}" - start="(['\"])$(sed_escape_lhs "$key")\2\s*," - end="\);" - if [ "${key:0:1}" = '$' ]; then - start="^(\s*)$(sed_escape_lhs "$key")\s*=" - end=";" - fi - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php - } - - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" - set_config 'DB_USER' "$WORDPRESS_DB_USER" - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" - - for unique in "${uniqueEnvs[@]}"; do - uniqVar="WORDPRESS_$unique" - if [ -n "${!uniqVar}" ]; then - set_config "$unique" "${!uniqVar}" - else - # if not specified, let's generate a random value - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" - if [ "$currentVal" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" - fi + { print } + ' "$wpConfigDocker" > wp-config.php + break fi done - - if [ "$WORDPRESS_TABLE_PREFIX" ]; then - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" - fi - - if [ "$WORDPRESS_DEBUG" ]; then - set_config 'WP_DEBUG' 1 boolean - fi - - if ! TERM=dumb php -- <<'EOPHP' -connect_error) { - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); - --$maxTries; - if ($maxTries <= 0) { - exit(1); - } - sleep(3); - } -} while ($mysql->connect_error); - -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); - $mysql->close(); - exit(1); -} - -$mysql->close(); -EOPHP - then - echo >&2 - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" - echo >&2 ' continuing anyways (which might have unexpected results)' - echo >&2 - fi fi - - # 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) - for e in "${envs[@]}"; do - unset "$e" - done fi exec "$@" diff --git a/beta/php7.3/fpm/wp-config-docker.php b/beta/php7.3/fpm/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/beta/php7.3/fpm/wp-config-docker.php @@ -0,0 +1,120 @@ +&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then - if [ "$(id -u)" = '0' ]; then +if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then case "$1" in apache2*) user="${APACHE_RUN_USER:-www-data}" @@ -41,13 +21,13 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then ;; esac else - user="$(id -u)" - group="$(id -g)" + user="$uid" + group="$gid" fi if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then # 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) - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then chown "$user:$group" . fi @@ -65,7 +45,7 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then --extract --file - ) - if [ "$user" != '0' ]; then + if [ "$uid" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi @@ -84,202 +64,28 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then echo >&2 "Complete! WordPress has been successfully copied to $PWD" fi - # allow any of these "Authentication Unique Keys and Salts." to be specified via - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - uniqueEnvs=( - AUTH_KEY - SECURE_AUTH_KEY - LOGGED_IN_KEY - NONCE_KEY - AUTH_SALT - SECURE_AUTH_SALT - LOGGED_IN_SALT - NONCE_SALT - ) - envs=( - WORDPRESS_DB_HOST - WORDPRESS_DB_USER - WORDPRESS_DB_PASSWORD - WORDPRESS_DB_NAME - WORDPRESS_DB_CHARSET - WORDPRESS_DB_COLLATE - "${uniqueEnvs[@]/#/WORDPRESS_}" - WORDPRESS_TABLE_PREFIX - WORDPRESS_DEBUG - WORDPRESS_CONFIG_EXTRA - ) - haveConfig= - for e in "${envs[@]}"; do - file_env "$e" - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then - haveConfig=1 - fi - done - - # linking backwards-compatibility - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then - haveConfig=1 - # host defaults to "mysql" below if unspecified - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" - if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - else - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" - fi - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" - fi - - # only touch "wp-config.php" if we have environment-supplied configuration values - if [ "$haveConfig" ]; then - : "${WORDPRESS_DB_HOST:=mysql}" - : "${WORDPRESS_DB_USER:=root}" - : "${WORDPRESS_DB_PASSWORD:=}" - : "${WORDPRESS_DB_NAME:=wordpress}" - : "${WORDPRESS_DB_CHARSET:=utf8}" - : "${WORDPRESS_DB_COLLATE:=}" - - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks - # https://github.com/docker-library/wordpress/issues/116 - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 - sed -ri -e 's/\r$//' wp-config* - - if [ ! -e wp-config.php ]; then - awk ' - /^\/\*.*stop editing.*\*\/$/ && c == 0 { - c = 1 - system("cat") - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { - print "// WORDPRESS_CONFIG_EXTRA" - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) } - } - { print } - ' wp-config-sample.php > wp-config.php <<'EOPHP' -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $_SERVER['HTTPS'] = 'on'; -} - -EOPHP - chown "$user:$group" wp-config.php - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then - # (if the config file already contains the requested PHP code, don't print a warning) - echo >&2 - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' - echo >&2 - fi - - # see http://stackoverflow.com/a/2705678/433558 - sed_escape_lhs() { - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' - } - sed_escape_rhs() { - echo "$@" | sed -e 's/[\/&]/\\&/g' - } - php_escape() { - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" - fi - echo "$escaped" - } - set_config() { - key="$1" - value="$2" - var_type="${3:-string}" - start="(['\"])$(sed_escape_lhs "$key")\2\s*," - end="\);" - if [ "${key:0:1}" = '$' ]; then - start="^(\s*)$(sed_escape_lhs "$key")\s*=" - end=";" - fi - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php - } - - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" - set_config 'DB_USER' "$WORDPRESS_DB_USER" - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" - - for unique in "${uniqueEnvs[@]}"; do - uniqVar="WORDPRESS_$unique" - if [ -n "${!uniqVar}" ]; then - set_config "$unique" "${!uniqVar}" - else - # if not specified, let's generate a random value - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" - if [ "$currentVal" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" - fi + { print } + ' "$wpConfigDocker" > wp-config.php + break fi done - - if [ "$WORDPRESS_TABLE_PREFIX" ]; then - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" - fi - - if [ "$WORDPRESS_DEBUG" ]; then - set_config 'WP_DEBUG' 1 boolean - fi - - if ! TERM=dumb php -- <<'EOPHP' -connect_error) { - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); - --$maxTries; - if ($maxTries <= 0) { - exit(1); - } - sleep(3); - } -} while ($mysql->connect_error); - -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); - $mysql->close(); - exit(1); -} - -$mysql->close(); -EOPHP - then - echo >&2 - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" - echo >&2 ' continuing anyways (which might have unexpected results)' - echo >&2 - fi fi - - # 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) - for e in "${envs[@]}"; do - unset "$e" - done fi exec "$@" diff --git a/beta/php7.4/apache/wp-config-docker.php b/beta/php7.4/apache/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/beta/php7.4/apache/wp-config-docker.php @@ -0,0 +1,120 @@ +&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then - if [ "$(id -u)" = '0' ]; then +if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then case "$1" in apache2*) user="${APACHE_RUN_USER:-www-data}" @@ -41,13 +21,13 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then ;; esac else - user="$(id -u)" - group="$(id -g)" + user="$uid" + group="$gid" fi if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then # 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) - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then chown "$user:$group" . fi @@ -65,7 +45,7 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then --extract --file - ) - if [ "$user" != '0' ]; then + if [ "$uid" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi @@ -84,202 +64,28 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then echo >&2 "Complete! WordPress has been successfully copied to $PWD" fi - # allow any of these "Authentication Unique Keys and Salts." to be specified via - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - uniqueEnvs=( - AUTH_KEY - SECURE_AUTH_KEY - LOGGED_IN_KEY - NONCE_KEY - AUTH_SALT - SECURE_AUTH_SALT - LOGGED_IN_SALT - NONCE_SALT - ) - envs=( - WORDPRESS_DB_HOST - WORDPRESS_DB_USER - WORDPRESS_DB_PASSWORD - WORDPRESS_DB_NAME - WORDPRESS_DB_CHARSET - WORDPRESS_DB_COLLATE - "${uniqueEnvs[@]/#/WORDPRESS_}" - WORDPRESS_TABLE_PREFIX - WORDPRESS_DEBUG - WORDPRESS_CONFIG_EXTRA - ) - haveConfig= - for e in "${envs[@]}"; do - file_env "$e" - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then - haveConfig=1 - fi - done - - # linking backwards-compatibility - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then - haveConfig=1 - # host defaults to "mysql" below if unspecified - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" - if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - else - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" - fi - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" - fi - - # only touch "wp-config.php" if we have environment-supplied configuration values - if [ "$haveConfig" ]; then - : "${WORDPRESS_DB_HOST:=mysql}" - : "${WORDPRESS_DB_USER:=root}" - : "${WORDPRESS_DB_PASSWORD:=}" - : "${WORDPRESS_DB_NAME:=wordpress}" - : "${WORDPRESS_DB_CHARSET:=utf8}" - : "${WORDPRESS_DB_COLLATE:=}" - - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks - # https://github.com/docker-library/wordpress/issues/116 - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 - sed -ri -e 's/\r$//' wp-config* - - if [ ! -e wp-config.php ]; then - awk ' - /^\/\*.*stop editing.*\*\/$/ && c == 0 { - c = 1 - system("cat") - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { - print "// WORDPRESS_CONFIG_EXTRA" - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) } - } - { print } - ' wp-config-sample.php > wp-config.php <<'EOPHP' -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $_SERVER['HTTPS'] = 'on'; -} - -EOPHP - chown "$user:$group" wp-config.php - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then - # (if the config file already contains the requested PHP code, don't print a warning) - echo >&2 - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' - echo >&2 - fi - - # see http://stackoverflow.com/a/2705678/433558 - sed_escape_lhs() { - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' - } - sed_escape_rhs() { - echo "$@" | sed -e 's/[\/&]/\\&/g' - } - php_escape() { - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" - fi - echo "$escaped" - } - set_config() { - key="$1" - value="$2" - var_type="${3:-string}" - start="(['\"])$(sed_escape_lhs "$key")\2\s*," - end="\);" - if [ "${key:0:1}" = '$' ]; then - start="^(\s*)$(sed_escape_lhs "$key")\s*=" - end=";" - fi - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php - } - - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" - set_config 'DB_USER' "$WORDPRESS_DB_USER" - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" - - for unique in "${uniqueEnvs[@]}"; do - uniqVar="WORDPRESS_$unique" - if [ -n "${!uniqVar}" ]; then - set_config "$unique" "${!uniqVar}" - else - # if not specified, let's generate a random value - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" - if [ "$currentVal" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" - fi + { print } + ' "$wpConfigDocker" > wp-config.php + break fi done - - if [ "$WORDPRESS_TABLE_PREFIX" ]; then - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" - fi - - if [ "$WORDPRESS_DEBUG" ]; then - set_config 'WP_DEBUG' 1 boolean - fi - - if ! TERM=dumb php -- <<'EOPHP' -connect_error) { - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); - --$maxTries; - if ($maxTries <= 0) { - exit(1); - } - sleep(3); - } -} while ($mysql->connect_error); - -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); - $mysql->close(); - exit(1); -} - -$mysql->close(); -EOPHP - then - echo >&2 - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" - echo >&2 ' continuing anyways (which might have unexpected results)' - echo >&2 - fi fi - - # 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) - for e in "${envs[@]}"; do - unset "$e" - done fi exec "$@" diff --git a/beta/php7.4/fpm-alpine/wp-config-docker.php b/beta/php7.4/fpm-alpine/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/beta/php7.4/fpm-alpine/wp-config-docker.php @@ -0,0 +1,120 @@ +&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then - if [ "$(id -u)" = '0' ]; then +if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then case "$1" in apache2*) user="${APACHE_RUN_USER:-www-data}" @@ -41,13 +21,13 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then ;; esac else - user="$(id -u)" - group="$(id -g)" + user="$uid" + group="$gid" fi if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then # 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) - if [ "$(id -u)" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then + if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then chown "$user:$group" . fi @@ -65,7 +45,7 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then --extract --file - ) - if [ "$user" != '0' ]; then + if [ "$uid" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi @@ -84,202 +64,28 @@ if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then echo >&2 "Complete! WordPress has been successfully copied to $PWD" fi - # allow any of these "Authentication Unique Keys and Salts." to be specified via - # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - uniqueEnvs=( - AUTH_KEY - SECURE_AUTH_KEY - LOGGED_IN_KEY - NONCE_KEY - AUTH_SALT - SECURE_AUTH_SALT - LOGGED_IN_SALT - NONCE_SALT - ) - envs=( - WORDPRESS_DB_HOST - WORDPRESS_DB_USER - WORDPRESS_DB_PASSWORD - WORDPRESS_DB_NAME - WORDPRESS_DB_CHARSET - WORDPRESS_DB_COLLATE - "${uniqueEnvs[@]/#/WORDPRESS_}" - WORDPRESS_TABLE_PREFIX - WORDPRESS_DEBUG - WORDPRESS_CONFIG_EXTRA - ) - haveConfig= - for e in "${envs[@]}"; do - file_env "$e" - if [ -z "$haveConfig" ] && [ -n "${!e}" ]; then - haveConfig=1 - fi - done - - # linking backwards-compatibility - if [ -n "${!MYSQL_ENV_MYSQL_*}" ]; then - haveConfig=1 - # host defaults to "mysql" below if unspecified - : "${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}}" - if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}}" - else - : "${WORDPRESS_DB_PASSWORD:=${MYSQL_ENV_MYSQL_PASSWORD:-}}" - fi - : "${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-}}" - fi - - # only touch "wp-config.php" if we have environment-supplied configuration values - if [ "$haveConfig" ]; then - : "${WORDPRESS_DB_HOST:=mysql}" - : "${WORDPRESS_DB_USER:=root}" - : "${WORDPRESS_DB_PASSWORD:=}" - : "${WORDPRESS_DB_NAME:=wordpress}" - : "${WORDPRESS_DB_CHARSET:=utf8}" - : "${WORDPRESS_DB_COLLATE:=}" - - # version 4.4.1 decided to switch to windows line endings, that breaks our seds and awks - # https://github.com/docker-library/wordpress/issues/116 - # https://github.com/WordPress/WordPress/commit/1acedc542fba2482bab88ec70d4bea4b997a92e4 - sed -ri -e 's/\r$//' wp-config* - - if [ ! -e wp-config.php ]; then - awk ' - /^\/\*.*stop editing.*\*\/$/ && c == 0 { - c = 1 - system("cat") - if (ENVIRON["WORDPRESS_CONFIG_EXTRA"]) { - print "// WORDPRESS_CONFIG_EXTRA" - print ENVIRON["WORDPRESS_CONFIG_EXTRA"] "\n" + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) } - } - { print } - ' wp-config-sample.php > wp-config.php <<'EOPHP' -// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact -// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy -if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { - $_SERVER['HTTPS'] = 'on'; -} - -EOPHP - chown "$user:$group" wp-config.php - elif [ -e wp-config.php ] && [ -n "$WORDPRESS_CONFIG_EXTRA" ] && [[ "$(< wp-config.php)" != *"$WORDPRESS_CONFIG_EXTRA"* ]]; then - # (if the config file already contains the requested PHP code, don't print a warning) - echo >&2 - echo >&2 'WARNING: environment variable "WORDPRESS_CONFIG_EXTRA" is set, but "wp-config.php" already exists' - echo >&2 ' The contents of this variable will _not_ be inserted into the existing "wp-config.php" file.' - echo >&2 ' (see https://github.com/docker-library/wordpress/issues/333 for more details)' - echo >&2 - fi - - # see http://stackoverflow.com/a/2705678/433558 - sed_escape_lhs() { - echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' - } - sed_escape_rhs() { - echo "$@" | sed -e 's/[\/&]/\\&/g' - } - php_escape() { - local escaped="$(php -r 'var_export(('"$2"') $argv[1]);' -- "$1")" - if [ "$2" = 'string' ] && [ "${escaped:0:1}" = "'" ]; then - escaped="${escaped//$'\n'/"' + \"\\n\" + '"}" - fi - echo "$escaped" - } - set_config() { - key="$1" - value="$2" - var_type="${3:-string}" - start="(['\"])$(sed_escape_lhs "$key")\2\s*," - end="\);" - if [ "${key:0:1}" = '$' ]; then - start="^(\s*)$(sed_escape_lhs "$key")\s*=" - end=";" - fi - sed -ri -e "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php - } - - set_config 'DB_HOST' "$WORDPRESS_DB_HOST" - set_config 'DB_USER' "$WORDPRESS_DB_USER" - set_config 'DB_PASSWORD' "$WORDPRESS_DB_PASSWORD" - set_config 'DB_NAME' "$WORDPRESS_DB_NAME" - set_config 'DB_CHARSET' "$WORDPRESS_DB_CHARSET" - set_config 'DB_COLLATE' "$WORDPRESS_DB_COLLATE" - - for unique in "${uniqueEnvs[@]}"; do - uniqVar="WORDPRESS_$unique" - if [ -n "${!uniqVar}" ]; then - set_config "$unique" "${!uniqVar}" - else - # if not specified, let's generate a random value - currentVal="$(sed -rn -e "s/define\(\s*(([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\s*\);/\4/p" wp-config.php)" - if [ "$currentVal" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" - fi + { print } + ' "$wpConfigDocker" > wp-config.php + break fi done - - if [ "$WORDPRESS_TABLE_PREFIX" ]; then - set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" - fi - - if [ "$WORDPRESS_DEBUG" ]; then - set_config 'WP_DEBUG' 1 boolean - fi - - if ! TERM=dumb php -- <<'EOPHP' -connect_error) { - fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); - --$maxTries; - if ($maxTries <= 0) { - exit(1); - } - sleep(3); - } -} while ($mysql->connect_error); - -if (!$mysql->query('CREATE DATABASE IF NOT EXISTS `' . $mysql->real_escape_string($dbName) . '`')) { - fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); - $mysql->close(); - exit(1); -} - -$mysql->close(); -EOPHP - then - echo >&2 - echo >&2 "WARNING: unable to establish a database connection to '$WORDPRESS_DB_HOST'" - echo >&2 ' continuing anyways (which might have unexpected results)' - echo >&2 - fi fi - - # 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) - for e in "${envs[@]}"; do - unset "$e" - done fi exec "$@" diff --git a/beta/php7.4/fpm/wp-config-docker.php b/beta/php7.4/fpm/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/beta/php7.4/fpm/wp-config-docker.php @@ -0,0 +1,120 @@ +&2 "WordPress not found in $PWD - copying now..." + if [ -n "$(find -mindepth 1 -maxdepth 1 -not -name wp-content)" ]; then + echo >&2 "WARNING: $PWD is not empty! (copying anyhow)" + fi + sourceTarArgs=( + --create + --file - + --directory /usr/src/wordpress + --owner "$user" --group "$group" + ) + targetTarArgs=( + --extract + --file - + ) + if [ "$uid" != '0' ]; then + # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" + targetTarArgs+=( --no-overwrite-dir ) + fi + # loop over "pluggable" content in the source, and if it already exists in the destination, skip it + # https://github.com/docker-library/wordpress/issues/506 ("wp-content" persisted, "akismet" updated, WordPress container restarted/recreated, "akismet" downgraded) + for contentDir in /usr/src/wordpress/wp-content/*/*/; do + contentDir="${contentDir%/}" + [ -d "$contentDir" ] || continue + contentPath="${contentDir#/usr/src/wordpress/}" # "wp-content/plugins/akismet", etc. + if [ -d "$PWD/$contentPath" ]; then + echo >&2 "WARNING: '$PWD/$contentPath' exists! (not copying the WordPress version)" + sourceTarArgs+=( --exclude "./$contentPath" ) + fi + done + tar "${sourceTarArgs[@]}" . | tar "${targetTarArgs[@]}" + echo >&2 "Complete! WordPress has been successfully copied to $PWD" + fi + + wpEnvs=( "${!WORDPRESS_@}" ) + if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then + for wpConfigDocker in \ + wp-config-docker.php \ + /usr/src/wordpress/wp-config-docker.php \ + ; do + if [ -s "$wpConfigDocker" ]; then + echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})" + # 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) + awk ' + /put your unique phrase here/ { + cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1" + cmd | getline str + close(cmd) + gsub("put your unique phrase here", str) + } + { print } + ' "$wpConfigDocker" > wp-config.php + break + fi + done + fi +fi + +exec "$@" diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index 8ca2c547a4..1d6d1f087c 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -82,7 +82,7 @@ for version; do if [ "$version" = 'beta' ] && latestVersion="$(jq -r '.latest.version // ""' versions.json)" && [ "$latestVersion" = "$fullVersion" ]; then # "beta" channel even with release, skip it - continue + : #continue # TODO once something newer than 5.6 is released, this should be restored (explicit "beta" for allowing pre-release testing of "wp-config-docker.php") fi versionAliases=() diff --git a/wp-config-docker.php b/wp-config-docker.php new file mode 100644 index 0000000000..5a43e8e641 --- /dev/null +++ b/wp-config-docker.php @@ -0,0 +1,120 @@ +