wp/docker-entrypoint.sh
author ymh <ymh.work@gmail.com>
Mon, 09 Dec 2019 11:32:18 +0100
changeset 8 5617a61bc790
parent 0 505fe5249d9c
permissions -rw-r--r--
Added tag 0.4 for changeset 81d22971b333

#!/bin/bash
set -euo 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"
}

generate_rnd() {
	head /dev/urandom | tr -dc A-Za-z0-9 | head -c 64
}

# 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

# 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

: "${WORDPRESS_DB_HOST:=mysql}"
: "${WORDPRESS_DB_USER:=root}"
: "${WORDPRESS_DB_PASSWORD:=}"
: "${WORDPRESS_DB_NAME:=wordpress}"
: "${WORDPRESS_DB_CHARSET:=utf8}"
: "${WORDPRESS_DB_COLLATE:=}"

# Wait 

until mysql -s -h ${WORDPRESS_DB_HOST} -u ${WORDPRESS_DB_USER} -p${WORDPRESS_DB_PASSWORD} -e"quit" ${WORDPRESS_DB_NAME}; do
  >&2 echo "Mysql is unavailable - sleeping"
  sleep 1
done

>&2 echo "Mysql is up - proceeding"

if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then
	if [ "$(id -u)" = '0' ]; then
		case "$1" in
			apache2*)
				user="${APACHE_RUN_USER:-www-data}"
				group="${APACHE_RUN_GROUP:-www-data}"

				# strip off any '#' symbol ('#1000' is valid syntax for Apache)
				pound='#'
				user="${user#$pound}"
				group="${group#$pound}"
				;;
			*) # php-fpm
				user='www-data'
				group='www-data'
				;;
		esac
	else
		user="$(id -u)"
		group="$(id -g)"
	fi

	# TODO : create .env file if needed
	if [ ! -e .env ] && [ "$haveConfig" ]; then
		cat > .env <<-EOF				
				DATABASE_URL=mysql://${WORDPRESS_DB_USER}:${WORDPRESS_DB_PASSWORD}@db:3306/${WORDPRESS_DB_NAME}
				WP_HOME=http://pharmakon.test:8080
				
				WP_SITEURL=\${WP_HOME}/wp
				WP_ENV=development
				
				AUTH_KEY='$(generate_rnd)'
				SECURE_AUTH_KEY='$(generate_rnd)'
				LOGGED_IN_KEY='$(generate_rnd)'
				NONCE_KEY='$(generate_rnd)'
				AUTH_SALT='$(generate_rnd)'
				SECURE_AUTH_SALT='$(generate_rnd)'
				LOGGED_IN_SALT='$(generate_rnd)'
				NONCE_SALT='$(generate_rnd)'
			EOF


			chown "$user:$group" .env


		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

# Always lauch composer to install or update dependencies
composer --no-interaction install

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
	set -- composer exec wp "$@"
fi

# if our command is a valid wp-cli subcommand, let's invoke it through wp-cli instead
# (this allows for "docker run wordpress:cli help", etc)
if composer exec wp --path=/dev/null help "$1" > /dev/null 2>&1; then
	set -- composer exec wp "$@"
fi


exec "$@"