From d0f07310d3f40ab8353a47ee1d8757f7cd647191 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Mon, 22 Feb 2016 16:46:18 +0100 Subject: [PATCH 1/2] Add fpm-alpine variant --- fpm/alpine/Dockerfile | 49 +++++++++ fpm/alpine/docker-entrypoint.sh | 175 ++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 fpm/alpine/Dockerfile create mode 100755 fpm/alpine/docker-entrypoint.sh diff --git a/fpm/alpine/Dockerfile b/fpm/alpine/Dockerfile new file mode 100644 index 0000000000..6e20204f85 --- /dev/null +++ b/fpm/alpine/Dockerfile @@ -0,0 +1,49 @@ +FROM php:5.6-fpm-alpine + +# install the PHP extensions we need +RUN apk add --no-cache --virtual .build-deps \ + autoconf gcc libc-dev make \ + libpng-dev libjpeg-turbo-dev \ + && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ + && docker-php-ext-install gd mysqli opcache \ + && find /usr/local/lib/php/extensions -name '*.a' -delete \ + && find /usr/local/lib/php/extensions -name '*.so' -exec strip --strip-all '{}' \; \ + && runDeps="$( \ + scanelf --needed --nobanner --recursive \ + /usr/local/lib/php/extensions \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u \ + )" \ + && apk add --virtual .phpext-rundeps $runDeps \ + && apk del .build-deps + +# set recommended PHP.ini settings +# see https://secure.php.net/manual/en/opcache.installation.php +RUN { \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.interned_strings_buffer=8'; \ + echo 'opcache.max_accelerated_files=4000'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.fast_shutdown=1'; \ + echo 'opcache.enable_cli=1'; \ + } > /usr/local/etc/php/conf.d/opcache-recommended.ini + +VOLUME /var/www/html + +ENV WORDPRESS_VERSION 4.4.2 +ENV WORDPRESS_SHA1 7444099fec298b599eb026e83227462bcdf312a6 + +# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress +RUN curl -o wordpress.tar.gz -SL https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz \ + && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ + && tar -xzf wordpress.tar.gz -C /usr/src/ \ + && rm wordpress.tar.gz \ + && chown -R www-data:www-data /usr/src/wordpress + +COPY docker-entrypoint.sh /entrypoint.sh + +# grr, ENTRYPOINT resets CMD now +ENTRYPOINT ["/entrypoint.sh"] +CMD ["php-fpm"] diff --git a/fpm/alpine/docker-entrypoint.sh b/fpm/alpine/docker-entrypoint.sh new file mode 100755 index 0000000000..89ab13d086 --- /dev/null +++ b/fpm/alpine/docker-entrypoint.sh @@ -0,0 +1,175 @@ +#!/bin/sh +set -e + +if [ "${1#apache*}" != "$1" ] || [ "$1" = "php-fpm" ]; then + if [ -n "$MYSQL_PORT_3306_TCP" ]; then + if [ -z "$WORDPRESS_DB_HOST" ]; then + WORDPRESS_DB_HOST='mysql' + else + echo >&2 'warning: both WORDPRESS_DB_HOST and MYSQL_PORT_3306_TCP found' + echo >&2 " Connecting to WORDPRESS_DB_HOST ($WORDPRESS_DB_HOST)" + echo >&2 ' instead of the linked mysql container' + fi + fi + + if [ -z "$WORDPRESS_DB_HOST" ]; then + echo >&2 'error: missing WORDPRESS_DB_HOST and MYSQL_PORT_3306_TCP environment variables' + echo >&2 ' Did you forget to --link some_mysql_container:mysql or set an external db' + echo >&2 ' with -e WORDPRESS_DB_HOST=hostname:port?' + exit 1 + fi + + # if we're linked to MySQL and thus have credentials already, let's use them + : ${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}} + if [ "$WORDPRESS_DB_USER" = 'root' ]; then + : ${WORDPRESS_DB_PASSWORD:=$MYSQL_ENV_MYSQL_ROOT_PASSWORD} + fi + : ${WORDPRESS_DB_PASSWORD:=$MYSQL_ENV_MYSQL_PASSWORD} + : ${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-wordpress}} + + if [ -z "$WORDPRESS_DB_PASSWORD" ]; then + echo >&2 'error: missing required WORDPRESS_DB_PASSWORD environment variable' + echo >&2 ' Did you forget to -e WORDPRESS_DB_PASSWORD=... ?' + echo >&2 + echo >&2 ' (Also of interest might be WORDPRESS_DB_USER and WORDPRESS_DB_NAME.)' + exit 1 + fi + + if ! [ -e index.php -a -e wp-includes/version.php ]; then + echo >&2 "WordPress not found in $(pwd) - copying now..." + if [ "$(ls -A)" ]; then + echo >&2 "WARNING: $(pwd) is not empty - press Ctrl+C now if this is an error!" + ( set -x; ls -A; sleep 10 ) + fi + tar cf - -C /usr/src/wordpress . | tar xf - + echo >&2 "Complete! WordPress has been successfully copied to $(pwd)" + if [ ! -e .htaccess ]; then + # NOTE: The "Indexes" option is disabled in the php:apache base image + cat > .htaccess <<-'EOF' + # BEGIN WordPress + + RewriteEngine On + RewriteBase / + RewriteRule ^index\.php$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.php [L] + + # END WordPress + EOF + chown www-data:www-data .htaccess + fi + fi + + # TODO handle WordPress upgrades magically in the same way, but only if wp-includes/version.php's $wp_version is less than /usr/src/wordpress/wp-includes/version.php's $wp_version + + # 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 's/\r\n|\r/\n/g' wp-config* + + if [ ! -e wp-config.php ]; then + awk '/^\/\*.*stop editing.*\*\/$/ && c == 0 { c = 1; system("cat") } { 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 www-data:www-data wp-config.php + fi + + # see http://stackoverflow.com/a/2705678/433558 + sed_escape_lhs() { + echo "$@" | sed 's/[]\/$*.^|[]/\\&/g' + } + sed_escape_rhs() { + echo "$@" | sed 's/[\/&]/\\&/g' + } + php_escape() { + php -r 'var_export(('$2') $argv[1]);' "$1" + } + set_config() { + key="$1" + value="$2" + var_type="${3:-string}" + start="(['\"])$(sed_escape_lhs "$key")\2\s*," + end="\);" + if [ "${key#$}" != "$key" ]; then + start="^(\s*)$(sed_escape_lhs "$key")\s*=" + end=";" + fi + sed -ri "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" + + # allow any of these "Authentication Unique Keys and Salts." to be specified via + # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") + UNIQUES=" + AUTH_KEY + SECURE_AUTH_KEY + LOGGED_IN_KEY + NONCE_KEY + AUTH_SALT + SECURE_AUTH_SALT + LOGGED_IN_SALT + NONCE_SALT + " + for unique in ${UNIQUES}; do + eval unique_value=\$WORDPRESS_$unique + if [ "$unique_value" ]; then + set_config "$unique" "$unique_value" + else + # if not specified, let's generate a random value + current_set="$(sed -rn "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" + if [ "$current_set" = 'put your unique phrase here' ]; then + set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + fi + 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 + + TERM=dumb php -- "$WORDPRESS_DB_HOST" "$WORDPRESS_DB_USER" "$WORDPRESS_DB_PASSWORD" "$WORDPRESS_DB_NAME" <<'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($argv[4]) . '`')) { + fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); + $mysql->close(); + exit(1); +} + +$mysql->close(); +EOPHP +fi + +exec "$@" From 637afb53dc03b4af19149a0880e796346f97c137 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Sat, 10 Dec 2016 13:58:56 -0800 Subject: [PATCH 2/2] Refactoring for template usage and updates since the original PR --- .travis.yml | 2 + Dockerfile-alpine.template | 59 ++++++ ...ile.template => Dockerfile-debian.template | 29 ++- docker-entrypoint.sh | 4 +- fpm/alpine/Dockerfile | 49 ----- generate-stackbrew-library.sh | 2 +- php5.6/apache/Dockerfile | 29 ++- php5.6/apache/docker-entrypoint.sh | 4 +- php5.6/fpm-alpine/Dockerfile | 59 ++++++ .../fpm-alpine}/docker-entrypoint.sh | 98 +++++---- php5.6/fpm/Dockerfile | 29 ++- php5.6/fpm/docker-entrypoint.sh | 4 +- php7.0/apache/Dockerfile | 29 ++- php7.0/apache/docker-entrypoint.sh | 4 +- php7.0/fpm-alpine/Dockerfile | 59 ++++++ php7.0/fpm-alpine/docker-entrypoint.sh | 193 ++++++++++++++++++ php7.0/fpm/Dockerfile | 29 ++- php7.0/fpm/docker-entrypoint.sh | 4 +- update.sh | 12 +- 19 files changed, 541 insertions(+), 157 deletions(-) create mode 100644 Dockerfile-alpine.template rename Dockerfile.template => Dockerfile-debian.template (55%) delete mode 100644 fpm/alpine/Dockerfile create mode 100644 php5.6/fpm-alpine/Dockerfile rename {fpm/alpine => php5.6/fpm-alpine}/docker-entrypoint.sh (65%) create mode 100644 php7.0/fpm-alpine/Dockerfile create mode 100755 php7.0/fpm-alpine/docker-entrypoint.sh diff --git a/.travis.yml b/.travis.yml index 8b99430218..b95e631934 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,10 @@ services: docker env: - VARIANT=php5.6/apache - VARIANT=php5.6/fpm + - VARIANT=php5.6/fpm-alpine - VARIANT=php7.0/apache - VARIANT=php7.0/fpm + - VARIANT=php7.0/fpm-alpine install: - git clone https://github.com/docker-library/official-images.git ~/official-images diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template new file mode 100644 index 0000000000..25400de7ab --- /dev/null +++ b/Dockerfile-alpine.template @@ -0,0 +1,59 @@ +FROM php:%%PHP_VERSION%%-%%VARIANT%% + +# docker-entrypoint.sh dependencies +RUN apk add --no-cache \ +# in theory, docker-entrypoint.sh is POSIX-compliant, but priority is a working, consistent image + bash \ +# BusyBox sed is not sufficient for some of our sed expressions + sed + +# install the PHP extensions we need +RUN set -ex; \ + \ + apk add --no-cache --virtual .build-deps \ + libjpeg-turbo-dev \ + libpng-dev \ + ; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --recursive \ + /usr/local/lib/php/extensions \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u \ + )"; \ + apk add --virtual .wordpress-phpexts-rundeps $runDeps; \ + apk del .build-deps + +# set recommended PHP.ini settings +# see https://secure.php.net/manual/en/opcache.installation.php +RUN { \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.interned_strings_buffer=8'; \ + echo 'opcache.max_accelerated_files=4000'; \ + echo 'opcache.revalidate_freq=2'; \ + echo 'opcache.fast_shutdown=1'; \ + echo 'opcache.enable_cli=1'; \ + } > /usr/local/etc/php/conf.d/opcache-recommended.ini +%%VARIANT_EXTRAS%% +VOLUME /var/www/html + +ENV WORDPRESS_VERSION %%WORDPRESS_VERSION%% +ENV WORDPRESS_SHA1 %%WORDPRESS_SHA1%% + +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ +# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress + +COPY docker-entrypoint.sh /usr/local/bin/ + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["%%CMD%%"] diff --git a/Dockerfile.template b/Dockerfile-debian.template similarity index 55% rename from Dockerfile.template rename to Dockerfile-debian.template index 7857b84d4c..2b39553a0f 100644 --- a/Dockerfile.template +++ b/Dockerfile-debian.template @@ -1,9 +1,18 @@ FROM php:%%PHP_VERSION%%-%%VARIANT%% # install the PHP extensions we need -RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y \ + libjpeg-dev \ + libpng12-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache +# TODO consider removing the *-dev deps and only keeping the necessary lib* packages # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php @@ -21,17 +30,15 @@ VOLUME /var/www/html ENV WORDPRESS_VERSION %%WORDPRESS_VERSION%% ENV WORDPRESS_SHA1 %%WORDPRESS_SHA1%% -RUN set -x \ - && curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz" \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ # upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat -# ENTRYPOINT resets CMD ENTRYPOINT ["docker-entrypoint.sh"] CMD ["%%CMD%%"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index b8c8efb686..9ccfc8f309 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eu +set -euo pipefail # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' @@ -135,7 +135,7 @@ EOPHP # if not specified, let's generate a random value current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" if [ "$current_set" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" fi fi done diff --git a/fpm/alpine/Dockerfile b/fpm/alpine/Dockerfile deleted file mode 100644 index 6e20204f85..0000000000 --- a/fpm/alpine/Dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -FROM php:5.6-fpm-alpine - -# install the PHP extensions we need -RUN apk add --no-cache --virtual .build-deps \ - autoconf gcc libc-dev make \ - libpng-dev libjpeg-turbo-dev \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache \ - && find /usr/local/lib/php/extensions -name '*.a' -delete \ - && find /usr/local/lib/php/extensions -name '*.so' -exec strip --strip-all '{}' \; \ - && runDeps="$( \ - scanelf --needed --nobanner --recursive \ - /usr/local/lib/php/extensions \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --virtual .phpext-rundeps $runDeps \ - && apk del .build-deps - -# set recommended PHP.ini settings -# see https://secure.php.net/manual/en/opcache.installation.php -RUN { \ - echo 'opcache.memory_consumption=128'; \ - echo 'opcache.interned_strings_buffer=8'; \ - echo 'opcache.max_accelerated_files=4000'; \ - echo 'opcache.revalidate_freq=60'; \ - echo 'opcache.fast_shutdown=1'; \ - echo 'opcache.enable_cli=1'; \ - } > /usr/local/etc/php/conf.d/opcache-recommended.ini - -VOLUME /var/www/html - -ENV WORDPRESS_VERSION 4.4.2 -ENV WORDPRESS_SHA1 7444099fec298b599eb026e83227462bcdf312a6 - -# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress -RUN curl -o wordpress.tar.gz -SL https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress - -COPY docker-entrypoint.sh /entrypoint.sh - -# grr, ENTRYPOINT resets CMD now -ENTRYPOINT ["/entrypoint.sh"] -CMD ["php-fpm"] diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index 69262ec5ce..cf4959a707 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -48,7 +48,7 @@ join() { } for phpVersion in "${phpVersions[@]}"; do - for variant in apache fpm; do + for variant in apache fpm fpm-alpine; do dir="$phpVersion/$variant" [ -f "$dir/Dockerfile" ] || continue diff --git a/php5.6/apache/Dockerfile b/php5.6/apache/Dockerfile index 73f3cd29b0..6129c73b58 100644 --- a/php5.6/apache/Dockerfile +++ b/php5.6/apache/Dockerfile @@ -1,9 +1,18 @@ FROM php:5.6-apache # install the PHP extensions we need -RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y \ + libjpeg-dev \ + libpng12-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache +# TODO consider removing the *-dev deps and only keeping the necessary lib* packages # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php @@ -23,17 +32,15 @@ VOLUME /var/www/html ENV WORDPRESS_VERSION 4.7 ENV WORDPRESS_SHA1 1e14144c4db71421dc4ed22f94c3914dfc3b7020 -RUN set -x \ - && curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz" \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ # upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat -# ENTRYPOINT resets CMD ENTRYPOINT ["docker-entrypoint.sh"] CMD ["apache2-foreground"] diff --git a/php5.6/apache/docker-entrypoint.sh b/php5.6/apache/docker-entrypoint.sh index b8c8efb686..9ccfc8f309 100755 --- a/php5.6/apache/docker-entrypoint.sh +++ b/php5.6/apache/docker-entrypoint.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eu +set -euo pipefail # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' @@ -135,7 +135,7 @@ EOPHP # if not specified, let's generate a random value current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" if [ "$current_set" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" fi fi done diff --git a/php5.6/fpm-alpine/Dockerfile b/php5.6/fpm-alpine/Dockerfile new file mode 100644 index 0000000000..a9c71c2ced --- /dev/null +++ b/php5.6/fpm-alpine/Dockerfile @@ -0,0 +1,59 @@ +FROM php:5.6-fpm-alpine + +# docker-entrypoint.sh dependencies +RUN apk add --no-cache \ +# in theory, docker-entrypoint.sh is POSIX-compliant, but priority is a working, consistent image + bash \ +# BusyBox sed is not sufficient for some of our sed expressions + sed + +# install the PHP extensions we need +RUN set -ex; \ + \ + apk add --no-cache --virtual .build-deps \ + libjpeg-turbo-dev \ + libpng-dev \ + ; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --recursive \ + /usr/local/lib/php/extensions \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u \ + )"; \ + apk add --virtual .wordpress-phpexts-rundeps $runDeps; \ + apk del .build-deps + +# set recommended PHP.ini settings +# see https://secure.php.net/manual/en/opcache.installation.php +RUN { \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.interned_strings_buffer=8'; \ + echo 'opcache.max_accelerated_files=4000'; \ + echo 'opcache.revalidate_freq=2'; \ + echo 'opcache.fast_shutdown=1'; \ + echo 'opcache.enable_cli=1'; \ + } > /usr/local/etc/php/conf.d/opcache-recommended.ini + +VOLUME /var/www/html + +ENV WORDPRESS_VERSION 4.7 +ENV WORDPRESS_SHA1 1e14144c4db71421dc4ed22f94c3914dfc3b7020 + +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ +# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress + +COPY docker-entrypoint.sh /usr/local/bin/ + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["php-fpm"] diff --git a/fpm/alpine/docker-entrypoint.sh b/php5.6/fpm-alpine/docker-entrypoint.sh similarity index 65% rename from fpm/alpine/docker-entrypoint.sh rename to php5.6/fpm-alpine/docker-entrypoint.sh index 89ab13d086..9ccfc8f309 100755 --- a/fpm/alpine/docker-entrypoint.sh +++ b/php5.6/fpm-alpine/docker-entrypoint.sh @@ -1,32 +1,38 @@ -#!/bin/sh -set -e - -if [ "${1#apache*}" != "$1" ] || [ "$1" = "php-fpm" ]; then - if [ -n "$MYSQL_PORT_3306_TCP" ]; then - if [ -z "$WORDPRESS_DB_HOST" ]; then - WORDPRESS_DB_HOST='mysql' - else - echo >&2 'warning: both WORDPRESS_DB_HOST and MYSQL_PORT_3306_TCP found' - echo >&2 " Connecting to WORDPRESS_DB_HOST ($WORDPRESS_DB_HOST)" - echo >&2 ' instead of the linked mysql container' - fi - fi - - if [ -z "$WORDPRESS_DB_HOST" ]; then - echo >&2 'error: missing WORDPRESS_DB_HOST and MYSQL_PORT_3306_TCP environment variables' - echo >&2 ' Did you forget to --link some_mysql_container:mysql or set an external db' - echo >&2 ' with -e WORDPRESS_DB_HOST=hostname:port?' +#!/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" +} +if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then + file_env 'WORDPRESS_DB_HOST' 'mysql' # if we're linked to MySQL and thus have credentials already, let's use them - : ${WORDPRESS_DB_USER:=${MYSQL_ENV_MYSQL_USER:-root}} + file_env 'WORDPRESS_DB_USER' "${MYSQL_ENV_MYSQL_USER:-root}" if [ "$WORDPRESS_DB_USER" = 'root' ]; then - : ${WORDPRESS_DB_PASSWORD:=$MYSQL_ENV_MYSQL_ROOT_PASSWORD} + file_env 'WORDPRESS_DB_PASSWORD' "${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}" + else + file_env 'WORDPRESS_DB_PASSWORD' "${MYSQL_ENV_MYSQL_PASSWORD:-}" fi - : ${WORDPRESS_DB_PASSWORD:=$MYSQL_ENV_MYSQL_PASSWORD} - : ${WORDPRESS_DB_NAME:=${MYSQL_ENV_MYSQL_DATABASE:-wordpress}} - + file_env 'WORDPRESS_DB_NAME' "${MYSQL_ENV_MYSQL_DATABASE:-wordpress}" if [ -z "$WORDPRESS_DB_PASSWORD" ]; then echo >&2 'error: missing required WORDPRESS_DB_PASSWORD environment variable' echo >&2 ' Did you forget to -e WORDPRESS_DB_PASSWORD=... ?' @@ -41,7 +47,7 @@ if [ "${1#apache*}" != "$1" ] || [ "$1" = "php-fpm" ]; then echo >&2 "WARNING: $(pwd) is not empty - press Ctrl+C now if this is an error!" ( set -x; ls -A; sleep 10 ) fi - tar cf - -C /usr/src/wordpress . | tar xf - + tar cf - --one-file-system -C /usr/src/wordpress . | tar xf - echo >&2 "Complete! WordPress has been successfully copied to $(pwd)" if [ ! -e .htaccess ]; then # NOTE: The "Indexes" option is disabled in the php:apache base image @@ -66,7 +72,7 @@ if [ "${1#apache*}" != "$1" ] || [ "$1" = "php-fpm" ]; then # 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 's/\r\n|\r/\n/g' wp-config* + sed -ri -e 's/\r\n|\r/\n/g' wp-config* if [ ! -e wp-config.php ]; then awk '/^\/\*.*stop editing.*\*\/$/ && c == 0 { c = 1; system("cat") } { print }' wp-config-sample.php > wp-config.php <<'EOPHP' @@ -82,13 +88,13 @@ EOPHP # see http://stackoverflow.com/a/2705678/433558 sed_escape_lhs() { - echo "$@" | sed 's/[]\/$*.^|[]/\\&/g' + echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' } sed_escape_rhs() { - echo "$@" | sed 's/[\/&]/\\&/g' + echo "$@" | sed -e 's/[\/&]/\\&/g' } php_escape() { - php -r 'var_export(('$2') $argv[1]);' "$1" + php -r 'var_export(('$2') $argv[1]);' -- "$1" } set_config() { key="$1" @@ -96,11 +102,11 @@ EOPHP var_type="${3:-string}" start="(['\"])$(sed_escape_lhs "$key")\2\s*," end="\);" - if [ "${key#$}" != "$key" ]; then + if [ "${key:0:1}" = '$' ]; then start="^(\s*)$(sed_escape_lhs "$key")\s*=" end=";" fi - sed -ri "s/($start\s*).*($end)$/\1$(sed_escape_rhs "$(php_escape "$value" "$var_type")")\3/" wp-config.php + 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" @@ -110,7 +116,7 @@ EOPHP # allow any of these "Authentication Unique Keys and Salts." to be specified via # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") - UNIQUES=" + UNIQUES=( AUTH_KEY SECURE_AUTH_KEY LOGGED_IN_KEY @@ -119,24 +125,27 @@ EOPHP SECURE_AUTH_SALT LOGGED_IN_SALT NONCE_SALT - " - for unique in ${UNIQUES}; do - eval unique_value=\$WORDPRESS_$unique - if [ "$unique_value" ]; then - set_config "$unique" "$unique_value" + ) + for unique in "${UNIQUES[@]}"; do + uniqVar="WORDPRESS_$unique" + file_env "$uniqVar" + if [ "${!uniqVar}" ]; then + set_config "$unique" "${!uniqVar}" else # if not specified, let's generate a random value - current_set="$(sed -rn "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" + current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" if [ "$current_set" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" fi fi done + file_env 'WORDPRESS_TABLE_PREFIX' if [ "$WORDPRESS_TABLE_PREFIX" ]; then set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" fi + file_env 'WORDPRESS_DEBUG' if [ "$WORDPRESS_DEBUG" ]; then set_config 'WP_DEBUG' 1 boolean fi @@ -147,11 +156,20 @@ EOPHP $stderr = fopen('php://stderr', 'w'); -list($host, $port) = explode(':', $argv[1], 2); +// 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(':', $argv[1], 2); +$port = 0; +if (is_numeric($socket)) { + $port = (int) $socket; + $socket = null; +} $maxTries = 10; do { - $mysql = new mysqli($host, $argv[2], $argv[3], '', (int)$port); + $mysql = new mysqli($host, $argv[2], $argv[3], '', $port, $socket); if ($mysql->connect_error) { fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n"); --$maxTries; diff --git a/php5.6/fpm/Dockerfile b/php5.6/fpm/Dockerfile index 31d1cd1324..868bb1739f 100644 --- a/php5.6/fpm/Dockerfile +++ b/php5.6/fpm/Dockerfile @@ -1,9 +1,18 @@ FROM php:5.6-fpm # install the PHP extensions we need -RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y \ + libjpeg-dev \ + libpng12-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache +# TODO consider removing the *-dev deps and only keeping the necessary lib* packages # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php @@ -21,17 +30,15 @@ VOLUME /var/www/html ENV WORDPRESS_VERSION 4.7 ENV WORDPRESS_SHA1 1e14144c4db71421dc4ed22f94c3914dfc3b7020 -RUN set -x \ - && curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz" \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ # upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat -# ENTRYPOINT resets CMD ENTRYPOINT ["docker-entrypoint.sh"] CMD ["php-fpm"] diff --git a/php5.6/fpm/docker-entrypoint.sh b/php5.6/fpm/docker-entrypoint.sh index b8c8efb686..9ccfc8f309 100755 --- a/php5.6/fpm/docker-entrypoint.sh +++ b/php5.6/fpm/docker-entrypoint.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eu +set -euo pipefail # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' @@ -135,7 +135,7 @@ EOPHP # if not specified, let's generate a random value current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" if [ "$current_set" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" fi fi done diff --git a/php7.0/apache/Dockerfile b/php7.0/apache/Dockerfile index fbd84197a7..eb157671b1 100644 --- a/php7.0/apache/Dockerfile +++ b/php7.0/apache/Dockerfile @@ -1,9 +1,18 @@ FROM php:7.0-apache # install the PHP extensions we need -RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y \ + libjpeg-dev \ + libpng12-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache +# TODO consider removing the *-dev deps and only keeping the necessary lib* packages # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php @@ -23,17 +32,15 @@ VOLUME /var/www/html ENV WORDPRESS_VERSION 4.7 ENV WORDPRESS_SHA1 1e14144c4db71421dc4ed22f94c3914dfc3b7020 -RUN set -x \ - && curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz" \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ # upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat -# ENTRYPOINT resets CMD ENTRYPOINT ["docker-entrypoint.sh"] CMD ["apache2-foreground"] diff --git a/php7.0/apache/docker-entrypoint.sh b/php7.0/apache/docker-entrypoint.sh index b8c8efb686..9ccfc8f309 100755 --- a/php7.0/apache/docker-entrypoint.sh +++ b/php7.0/apache/docker-entrypoint.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eu +set -euo pipefail # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' @@ -135,7 +135,7 @@ EOPHP # if not specified, let's generate a random value current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" if [ "$current_set" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" fi fi done diff --git a/php7.0/fpm-alpine/Dockerfile b/php7.0/fpm-alpine/Dockerfile new file mode 100644 index 0000000000..ec387cc078 --- /dev/null +++ b/php7.0/fpm-alpine/Dockerfile @@ -0,0 +1,59 @@ +FROM php:7.0-fpm-alpine + +# docker-entrypoint.sh dependencies +RUN apk add --no-cache \ +# in theory, docker-entrypoint.sh is POSIX-compliant, but priority is a working, consistent image + bash \ +# BusyBox sed is not sufficient for some of our sed expressions + sed + +# install the PHP extensions we need +RUN set -ex; \ + \ + apk add --no-cache --virtual .build-deps \ + libjpeg-turbo-dev \ + libpng-dev \ + ; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --recursive \ + /usr/local/lib/php/extensions \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u \ + )"; \ + apk add --virtual .wordpress-phpexts-rundeps $runDeps; \ + apk del .build-deps + +# set recommended PHP.ini settings +# see https://secure.php.net/manual/en/opcache.installation.php +RUN { \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.interned_strings_buffer=8'; \ + echo 'opcache.max_accelerated_files=4000'; \ + echo 'opcache.revalidate_freq=2'; \ + echo 'opcache.fast_shutdown=1'; \ + echo 'opcache.enable_cli=1'; \ + } > /usr/local/etc/php/conf.d/opcache-recommended.ini + +VOLUME /var/www/html + +ENV WORDPRESS_VERSION 4.7 +ENV WORDPRESS_SHA1 1e14144c4db71421dc4ed22f94c3914dfc3b7020 + +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ +# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress + +COPY docker-entrypoint.sh /usr/local/bin/ + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["php-fpm"] diff --git a/php7.0/fpm-alpine/docker-entrypoint.sh b/php7.0/fpm-alpine/docker-entrypoint.sh new file mode 100755 index 0000000000..9ccfc8f309 --- /dev/null +++ b/php7.0/fpm-alpine/docker-entrypoint.sh @@ -0,0 +1,193 @@ +#!/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" +} + +if [[ "$1" == apache2* ]] || [ "$1" == php-fpm ]; then + file_env 'WORDPRESS_DB_HOST' 'mysql' + # if we're linked to MySQL and thus have credentials already, let's use them + file_env 'WORDPRESS_DB_USER' "${MYSQL_ENV_MYSQL_USER:-root}" + if [ "$WORDPRESS_DB_USER" = 'root' ]; then + file_env 'WORDPRESS_DB_PASSWORD' "${MYSQL_ENV_MYSQL_ROOT_PASSWORD:-}" + else + file_env 'WORDPRESS_DB_PASSWORD' "${MYSQL_ENV_MYSQL_PASSWORD:-}" + fi + file_env 'WORDPRESS_DB_NAME' "${MYSQL_ENV_MYSQL_DATABASE:-wordpress}" + if [ -z "$WORDPRESS_DB_PASSWORD" ]; then + echo >&2 'error: missing required WORDPRESS_DB_PASSWORD environment variable' + echo >&2 ' Did you forget to -e WORDPRESS_DB_PASSWORD=... ?' + echo >&2 + echo >&2 ' (Also of interest might be WORDPRESS_DB_USER and WORDPRESS_DB_NAME.)' + exit 1 + fi + + if ! [ -e index.php -a -e wp-includes/version.php ]; then + echo >&2 "WordPress not found in $(pwd) - copying now..." + if [ "$(ls -A)" ]; then + echo >&2 "WARNING: $(pwd) is not empty - press Ctrl+C now if this is an error!" + ( set -x; ls -A; sleep 10 ) + fi + tar cf - --one-file-system -C /usr/src/wordpress . | tar xf - + echo >&2 "Complete! WordPress has been successfully copied to $(pwd)" + if [ ! -e .htaccess ]; then + # NOTE: The "Indexes" option is disabled in the php:apache base image + cat > .htaccess <<-'EOF' + # BEGIN WordPress + + RewriteEngine On + RewriteBase / + RewriteRule ^index\.php$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.php [L] + + # END WordPress + EOF + chown www-data:www-data .htaccess + fi + fi + + # TODO handle WordPress upgrades magically in the same way, but only if wp-includes/version.php's $wp_version is less than /usr/src/wordpress/wp-includes/version.php's $wp_version + + # 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\n|\r/\n/g' wp-config* + + if [ ! -e wp-config.php ]; then + awk '/^\/\*.*stop editing.*\*\/$/ && c == 0 { c = 1; system("cat") } { 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 www-data:www-data wp-config.php + 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() { + php -r 'var_export(('$2') $argv[1]);' -- "$1" + } + 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" + + # allow any of these "Authentication Unique Keys and Salts." to be specified via + # environment variables with a "WORDPRESS_" prefix (ie, "WORDPRESS_AUTH_KEY") + UNIQUES=( + AUTH_KEY + SECURE_AUTH_KEY + LOGGED_IN_KEY + NONCE_KEY + AUTH_SALT + SECURE_AUTH_SALT + LOGGED_IN_SALT + NONCE_SALT + ) + for unique in "${UNIQUES[@]}"; do + uniqVar="WORDPRESS_$unique" + file_env "$uniqVar" + if [ "${!uniqVar}" ]; then + set_config "$unique" "${!uniqVar}" + else + # if not specified, let's generate a random value + current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" + if [ "$current_set" = 'put your unique phrase here' ]; then + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" + fi + fi + done + + file_env 'WORDPRESS_TABLE_PREFIX' + if [ "$WORDPRESS_TABLE_PREFIX" ]; then + set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX" + fi + + file_env 'WORDPRESS_DEBUG' + if [ "$WORDPRESS_DEBUG" ]; then + set_config 'WP_DEBUG' 1 boolean + fi + + TERM=dumb php -- "$WORDPRESS_DB_HOST" "$WORDPRESS_DB_USER" "$WORDPRESS_DB_PASSWORD" "$WORDPRESS_DB_NAME" <<'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($argv[4]) . '`')) { + fwrite($stderr, "\n" . 'MySQL "CREATE DATABASE" Error: ' . $mysql->error . "\n"); + $mysql->close(); + exit(1); +} + +$mysql->close(); +EOPHP +fi + +exec "$@" diff --git a/php7.0/fpm/Dockerfile b/php7.0/fpm/Dockerfile index 609579c796..88c46fd30a 100644 --- a/php7.0/fpm/Dockerfile +++ b/php7.0/fpm/Dockerfile @@ -1,9 +1,18 @@ FROM php:7.0-fpm # install the PHP extensions we need -RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y \ + libjpeg-dev \ + libpng12-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ + docker-php-ext-install gd mysqli opcache +# TODO consider removing the *-dev deps and only keeping the necessary lib* packages # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php @@ -21,17 +30,15 @@ VOLUME /var/www/html ENV WORDPRESS_VERSION 4.7 ENV WORDPRESS_SHA1 1e14144c4db71421dc4ed22f94c3914dfc3b7020 -RUN set -x \ - && curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz" \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ +RUN set -ex; \ + curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ + echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ # upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress + tar -xzf wordpress.tar.gz -C /usr/src/; \ + rm wordpress.tar.gz; \ + chown -R www-data:www-data /usr/src/wordpress COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat -# ENTRYPOINT resets CMD ENTRYPOINT ["docker-entrypoint.sh"] CMD ["php-fpm"] diff --git a/php7.0/fpm/docker-entrypoint.sh b/php7.0/fpm/docker-entrypoint.sh index b8c8efb686..9ccfc8f309 100755 --- a/php7.0/fpm/docker-entrypoint.sh +++ b/php7.0/fpm/docker-entrypoint.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eu +set -euo pipefail # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' @@ -135,7 +135,7 @@ EOPHP # if not specified, let's generate a random value current_set="$(sed -rn -e "s/define\((([\'\"])$unique\2\s*,\s*)(['\"])(.*)\3\);/\4/p" wp-config.php)" if [ "$current_set" = 'put your unique phrase here' ]; then - set_config "$unique" "$(head -c1M /dev/urandom | sha1sum | cut -d' ' -f1)" + set_config "$unique" "$(head -c1m /dev/urandom | sha1sum | cut -d' ' -f1)" fi fi done diff --git a/update.sh b/update.sh index ed8fc58eaf..a08e1b434f 100755 --- a/update.sh +++ b/update.sh @@ -15,10 +15,17 @@ sha1="$(curl -fsSL "https://wordpress.org/wordpress-$current.tar.gz.sha1")" declare -A variantExtras=( [apache]='\nRUN a2enmod rewrite expires\n' [fpm]='' + [fpm-alpine]='' ) declare -A variantCmds=( [apache]='apache2-foreground' [fpm]='php-fpm' + [fpm-alpine]='php-fpm' +) +declare -A variantBases=( + [apache]='debian' + [fpm]='debian' + [fpm-alpine]='alpine' ) travisEnv= @@ -26,12 +33,13 @@ for phpVersion in "${phpVersions[@]}"; do phpVersionDir="$phpVersion" phpVersion="${phpVersion#php}" - for variant in apache fpm; do + for variant in apache fpm fpm-alpine; do dir="$phpVersionDir/$variant" mkdir -p "$dir" extras="${variantExtras[$variant]}" cmd="${variantCmds[$variant]}" + base="${variantBases[$variant]}" ( set -x @@ -43,7 +51,7 @@ for phpVersion in "${phpVersions[@]}"; do -e 's!%%VARIANT%%!'"$variant"'!g' \ -e 's!%%VARIANT_EXTRAS%%!'"$extras"'!g' \ -e 's!%%CMD%%!'"$cmd"'!g' \ - Dockerfile.template > "$dir/Dockerfile" + "Dockerfile-${base}.template" > "$dir/Dockerfile" cp docker-entrypoint.sh "$dir/docker-entrypoint.sh" )