-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new "wp-config-docker.php" that uses "getenv" for configuration #557
Conversation
1f593e7
to
63a18cd
Compare
* @package WordPress | ||
*/ | ||
|
||
// IMPORTANT: this file needs to stay in-sync with https://github.com/WordPress/WordPress/blob/master/wp-config-sample.php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://github.com/WordPress/WordPress/commits/master/wp-config-sample.php for why I don't think this is going to be a huge problem (also, WordPress itself has to support some amount of backwards compatibility here due to upgrades, so we're generally pretty safe).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a diff, so it's easy to see the delta:
Diff:
root@e87117dfccf0:/var/www/html# diff -u wp-config-sample.php wp-config-docker.php
--- wp-config-sample.php 2020-02-06 06:33:11.000000000 +0000
+++ wp-config-docker.php 2021-01-07 20:59:19.000000000 +0000
@@ -13,29 +13,47 @@
* * Database table prefix
* * ABSPATH
*
+ * This has been slightly modified (to read environment variables) for use in Docker.
+ *
* @link https://wordpress.org/support/article/editing-wp-config-php/
*
* @package WordPress
*/
+// IMPORTANT: this file needs to stay in-sync with https://github.com/WordPress/WordPress/blob/master/wp-config-sample.php
+// (it gets parsed by the upstream wizard in https://github.com/WordPress/WordPress/blob/f27cb65e1ef25d11b535695a660e7282b98eb742/wp-admin/setup-config.php#L356-L392)
+
+// a helper function to lookup "env_FILE", "env", then fallback
+function getenv_docker($env, $default) {
+ if ($fileEnv = getenv($env . '_FILE')) {
+ return file_get_contents($fileEnv);
+ }
+ else if ($val = getenv($env)) {
+ return $val;
+ }
+ else {
+ return $default;
+ }
+}
+
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
-define( 'DB_NAME', 'database_name_here' );
+define( 'DB_NAME', getenv_docker('WORDPRESS_DB_NAME', 'database_name_here') );
/** MySQL database username */
-define( 'DB_USER', 'username_here' );
+define( 'DB_USER', getenv_docker('WORDPRESS_DB_USER', 'username_here') );
/** MySQL database password */
-define( 'DB_PASSWORD', 'password_here' );
+define( 'DB_PASSWORD', getenv_docker('WORDPRESS_DB_PASSWORD', 'password_here') );
/** MySQL hostname */
-define( 'DB_HOST', 'localhost' );
+define( 'DB_HOST', getenv_docker('WORDPRESS_DB_HOST', 'mysql') );
/** Database Charset to use in creating database tables. */
-define( 'DB_CHARSET', 'utf8' );
+define( 'DB_CHARSET', getenv_docker('WORDPRESS_DB_CHARSET', 'utf8') );
/** The Database Collate type. Don't change this if in doubt. */
-define( 'DB_COLLATE', '' );
+define( 'DB_COLLATE', getenv_docker('WORDPRESS_DB_COLLATE', '') );
/**#@+
* Authentication Unique Keys and Salts.
@@ -46,14 +64,15 @@
*
* @since 2.6.0
*/
-define( 'AUTH_KEY', 'put your unique phrase here' );
-define( 'SECURE_AUTH_KEY', 'put your unique phrase here' );
-define( 'LOGGED_IN_KEY', 'put your unique phrase here' );
-define( 'NONCE_KEY', 'put your unique phrase here' );
-define( 'AUTH_SALT', 'put your unique phrase here' );
-define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
-define( 'LOGGED_IN_SALT', 'put your unique phrase here' );
-define( 'NONCE_SALT', 'put your unique phrase here' );
+define( 'AUTH_KEY', getenv_docker('WORDPRESS_AUTH_KEY', 'put your unique phrase here') );
+define( 'SECURE_AUTH_KEY', getenv_docker('WORDPRESS_SECURE_AUTH_KEY', 'put your unique phrase here') );
+define( 'LOGGED_IN_KEY', getenv_docker('WORDPRESS_LOGGED_IN_KEY', 'put your unique phrase here') );
+define( 'NONCE_KEY', getenv_docker('WORDPRESS_NONCE_KEY', 'put your unique phrase here') );
+define( 'AUTH_SALT', getenv_docker('WORDPRESS_AUTH_SALT', 'put your unique phrase here') );
+define( 'SECURE_AUTH_SALT', getenv_docker('WORDPRESS_SECURE_AUTH_SALT', 'put your unique phrase here') );
+define( 'LOGGED_IN_SALT', getenv_docker('WORDPRESS_LOGGED_IN_SALT', 'put your unique phrase here') );
+define( 'NONCE_SALT', getenv_docker('WORDPRESS_NONCE_SALT', 'put your unique phrase here') );
+// (See also https://wordpress.stackexchange.com/a/152905/199287)
/**#@-*/
@@ -63,7 +82,7 @@
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
-$table_prefix = 'wp_';
+$table_prefix = getenv_docker('WORDPRESS_TABLE_PREFIX', 'wp_');
/**
* For developers: WordPress debugging mode.
@@ -77,7 +96,18 @@
*
* @link https://wordpress.org/support/article/debugging-in-wordpress/
*/
-define( 'WP_DEBUG', false );
+define( 'WP_DEBUG', !!getenv_docker('WORDPRESS_DEBUG', '') );
+
+// 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';
+}
+// (we include this by default because reverse proxying is extremely common in container environments)
+
+if ($configExtra = getenv_docker('WORDPRESS_CONFIG_EXTRA', '')) {
+ eval($configExtra);
+}
/* That's all, stop editing! Happy publishing. */
And again, between wp-config-docker.php
and the actual generated copy of an instance:
Diff:
root@e87117dfccf0:/var/www/html# diff -u wp-config-docker.php wp-config.php
--- wp-config-docker.php 2021-01-07 20:59:19.000000000 +0000
+++ wp-config.php 2021-01-07 21:01:30.351675733 +0000
@@ -64,14 +64,14 @@
*
* @since 2.6.0
*/
-define( 'AUTH_KEY', getenv_docker('WORDPRESS_AUTH_KEY', 'put your unique phrase here') );
-define( 'SECURE_AUTH_KEY', getenv_docker('WORDPRESS_SECURE_AUTH_KEY', 'put your unique phrase here') );
-define( 'LOGGED_IN_KEY', getenv_docker('WORDPRESS_LOGGED_IN_KEY', 'put your unique phrase here') );
-define( 'NONCE_KEY', getenv_docker('WORDPRESS_NONCE_KEY', 'put your unique phrase here') );
-define( 'AUTH_SALT', getenv_docker('WORDPRESS_AUTH_SALT', 'put your unique phrase here') );
-define( 'SECURE_AUTH_SALT', getenv_docker('WORDPRESS_SECURE_AUTH_SALT', 'put your unique phrase here') );
-define( 'LOGGED_IN_SALT', getenv_docker('WORDPRESS_LOGGED_IN_SALT', 'put your unique phrase here') );
-define( 'NONCE_SALT', getenv_docker('WORDPRESS_NONCE_SALT', 'put your unique phrase here') );
+define( 'AUTH_KEY', getenv_docker('WORDPRESS_AUTH_KEY', '6e2282caef63f696b8da3636f1f5e434831105a9') );
+define( 'SECURE_AUTH_KEY', getenv_docker('WORDPRESS_SECURE_AUTH_KEY', '5ace3ecfd4a5457acfd07439a697078fabf0314b') );
+define( 'LOGGED_IN_KEY', getenv_docker('WORDPRESS_LOGGED_IN_KEY', '5ebf7073d2267f436db7a07aa79bfba46c26024f') );
+define( 'NONCE_KEY', getenv_docker('WORDPRESS_NONCE_KEY', '0fceb36b6edbe4a5a73f840b7842d45f6de2f734') );
+define( 'AUTH_SALT', getenv_docker('WORDPRESS_AUTH_SALT', '00604f3e6d6b936370c8e56cfd88d69aab4f19a7') );
+define( 'SECURE_AUTH_SALT', getenv_docker('WORDPRESS_SECURE_AUTH_SALT', '9ee71261f2bd3991c2459a4fe2cafae50a787d65') );
+define( 'LOGGED_IN_SALT', getenv_docker('WORDPRESS_LOGGED_IN_SALT', '0311e31af92e74193a10d6a3f01e4e511899d95a') );
+define( 'NONCE_SALT', getenv_docker('WORDPRESS_NONCE_SALT', 'd091304604230c499ebcb147ededf00454795a22') );
// (See also https://wordpress.stackexchange.com/a/152905/199287)
/**#@-*/
This new method of configuration allows us to stop modifying the user-supplied `wp-config.php` file on every container startup, and instead just let PHP itself read the values directly from the source. With this change, the "beta" tags are force-reenabled at the same version as the latest releases to allow users to test this before the next release of WordPress (where it is intended that this change will go live for all image variants).
63a18cd
to
8f5bcc1
Compare
@@ -0,0 +1,91 @@ | |||
#!/usr/bin/env bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose a diff
here is also useful... 😅
Diff:
$ diff -u docker-entrypoint.sh docker-entrypoint-ng.sh
--- docker-entrypoint.sh 2021-01-06 17:29:40.791709514 -0800
+++ docker-entrypoint-ng.sh 2021-01-07 13:08:41.967708300 -0800
@@ -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 @@
;;
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 @@
--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 @@
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'
-<?php
-// database might not exist, so let's try creating it (just to be safe)
-
-$stderr = fopen('php://stderr', 'w');
-
-// https://codex.wordpress.org/Editing_wp-config.php#MySQL_Alternate_Port
-// "hostname:port"
-// https://codex.wordpress.org/Editing_wp-config.php#MySQL_Sockets_or_Pipes
-// "hostname:unix-socket-path"
-list($host, $socket) = explode(':', getenv('WORDPRESS_DB_HOST'), 2);
-$port = 0;
-if (is_numeric($socket)) {
- $port = (int) $socket;
- $socket = null;
-}
-$user = getenv('WORDPRESS_DB_USER');
-$pass = getenv('WORDPRESS_DB_PASSWORD');
-$dbName = getenv('WORDPRESS_DB_NAME');
-
-$maxTries = 10;
-do {
- $mysql = new mysqli($host, $user, $pass, '', $port, $socket);
- if ($mysql->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 "$@"
(28 insertions(+), 222 deletions(-)
)
According to https://wordpress.org/about/roadmap/, WordPress 5.7 is scheduled for ~March 2021, so that would give a decent amount of time for folks to test this before it goes live (if we can get it to an acceptable state for merging soon). |
For users who are changing |
Changes: - docker-library/wordpress@e7f2ca6: Merge pull request docker-library/wordpress#557 from infosiftr/wp-config-docker.php - docker-library/wordpress@8f5bcc1: Add new "wp-config-docker.php" that uses "getenv" for configuration
This new method of configuration allows us to stop modifying the user-supplied
wp-config.php
file on every container startup, and instead just let PHP itself read the values directly from the source.With this change, the "beta" tags are force-reenabled at the same version as the latest releases to allow users to test this before the next release of WordPress (where it is intended that this change will go live for all image variants).
Closes #242
Closes #496
Closes #522
Closes #544