From 3bf5b82235d12cdf8fd80ad442247ce9ab5ef422 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Fri, 18 Mar 2016 10:51:01 -0700 Subject: [PATCH] Convert all Dockerfiles to be template-based, and resync a few minor bits of Alpine and Debian (libedit in both, no recode in either, POSIX shell versions of docker-php-ext-* scripts for all) --- .travis.yml | 10 +++++ Dockerfile-alpine.template | 91 ++++++++++++++++++++++++++++++++++++++ Dockerfile-debian.template | 81 +++++++++++++++++++++++++++++++++ docker-php-ext-configure | 4 +- docker-php-ext-enable | 20 ++++----- docker-php-ext-install | 20 +++++---- update.sh | 39 +++++++++++----- 7 files changed, 233 insertions(+), 32 deletions(-) create mode 100644 Dockerfile-alpine.template create mode 100644 Dockerfile-debian.template diff --git a/.travis.yml b/.travis.yml index c67b3aaa..2e37a839 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,17 +3,26 @@ services: docker env: - VERSION=7.0 VARIANT= + - VERSION=7.0 VARIANT=alpine - VERSION=7.0 VARIANT=apache - VERSION=7.0 VARIANT=fpm + - VERSION=7.0 VARIANT=fpm/alpine - VERSION=7.0 VARIANT=zts + - VERSION=7.0 VARIANT=zts/alpine - VERSION=5.6 VARIANT= + - VERSION=5.6 VARIANT=alpine - VERSION=5.6 VARIANT=apache - VERSION=5.6 VARIANT=fpm + - VERSION=5.6 VARIANT=fpm/alpine - VERSION=5.6 VARIANT=zts + - VERSION=5.6 VARIANT=zts/alpine - VERSION=5.5 VARIANT= + - VERSION=5.5 VARIANT=alpine - VERSION=5.5 VARIANT=apache - VERSION=5.5 VARIANT=fpm + - VERSION=5.5 VARIANT=fpm/alpine - VERSION=5.5 VARIANT=zts + - VERSION=5.5 VARIANT=zts/alpine install: - git clone https://github.com/docker-library/official-images.git ~/official-images @@ -22,6 +31,7 @@ before_script: - env | sort - cd "$VERSION" - image="php:${VERSION}${VARIANT:+-$VARIANT}" + - image="${image//'/'/-}" script: - docker build -t "$image" "${VARIANT:-.}" diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template new file mode 100644 index 00000000..391f0fb9 --- /dev/null +++ b/Dockerfile-alpine.template @@ -0,0 +1,91 @@ +FROM alpine:3.3 + +# phpize deps +RUN apk add --no-cache --virtual .phpize-deps \ + autoconf \ + file \ + g++ \ + gcc \ + libc-dev \ + make \ + pkgconf \ + re2c + +# persistent / runtime deps +RUN apk add --no-cache --virtual .persistent-deps \ + ca-certificates \ + curl + +# ensure www-data user exists +RUN set -x \ + && addgroup -g 82 -S www-data \ + && adduser -u 82 -D -S -G www-data www-data +# 82 is the standard uid/gid for "www-data" in Alpine +# http://git.alpinelinux.org/cgit/aports/tree/main/apache2/apache2.pre-install?h=v3.3.2 +# http://git.alpinelinux.org/cgit/aports/tree/main/lighttpd/lighttpd.pre-install?h=v3.3.2 +# http://git.alpinelinux.org/cgit/aports/tree/main/nginx-initscripts/nginx-initscripts.pre-install?h=v3.3.2 + +ENV PHP_INI_DIR /usr/local/etc/php +RUN mkdir -p $PHP_INI_DIR/conf.d + +#### +#### + +ENV GPG_KEYS %%GPG_KEYS%% + +ENV PHP_VERSION %%PHP_VERSION%% +ENV PHP_FILENAME %%PHP_FILENAME%% +ENV PHP_SHA256 %%PHP_SHA256%% + +RUN set -xe \ + && apk add --no-cache --virtual .build-deps \ + curl-dev \ + gnupg \ + libedit-dev \ + libxml2-dev \ + openssl-dev \ + sqlite-dev \ + && curl -fSL "http://php.net/get/$PHP_FILENAME/from/this/mirror" -o "$PHP_FILENAME" \ + && echo "$PHP_SHA256 *$PHP_FILENAME" | sha256sum -c - \ + && curl -fSL "http://php.net/get/$PHP_FILENAME.asc/from/this/mirror" -o "$PHP_FILENAME.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && for key in $GPG_KEYS; do \ + gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ + done \ + && gpg --batch --verify "$PHP_FILENAME.asc" "$PHP_FILENAME" \ + && rm -r "$GNUPGHOME" "$PHP_FILENAME.asc" \ + && mkdir -p /usr/src \ + && tar -Jxf "$PHP_FILENAME" -C /usr/src \ + && mv "/usr/src/php-$PHP_VERSION" /usr/src/php \ + && rm "$PHP_FILENAME" \ + && cd /usr/src/php \ + && ./configure \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + $PHP_EXTRA_CONFIGURE_ARGS \ + --disable-cgi \ +# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself) + --enable-mysqlnd \ + --with-curl \ + --with-libedit \ + --with-openssl \ + --with-zlib \ + && make -j"$(getconf _NPROCESSORS_ONLN)" \ + && make install \ + && { find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; } \ + && make clean \ + && runDeps="$( \ + scanelf --needed --nobanner --recursive /usr/local \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u \ + )" \ + && apk add --virtual .php-rundeps $runDeps \ + && apk del .build-deps + +COPY docker-php-ext-* /usr/local/bin/ + +#### +CMD ["php", "-a"] +#### diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template new file mode 100644 index 00000000..4d453d98 --- /dev/null +++ b/Dockerfile-debian.template @@ -0,0 +1,81 @@ +FROM debian:jessie + +# phpize deps +RUN apt-get update && apt-get install -y \ + autoconf \ + file \ + g++ \ + gcc \ + libc-dev \ + make \ + pkg-config \ + re2c \ + --no-install-recommends && rm -r /var/lib/apt/lists/* + +# persistent / runtime deps +RUN apt-get update && apt-get install -y \ + ca-certificates \ + curl \ + libedit2 \ + libsqlite3-0 \ + libxml2 \ + --no-install-recommends && rm -r /var/lib/apt/lists/* + +ENV PHP_INI_DIR /usr/local/etc/php +RUN mkdir -p $PHP_INI_DIR/conf.d + +#### +#### + +ENV GPG_KEYS %%GPG_KEYS%% + +ENV PHP_VERSION %%PHP_VERSION%% +ENV PHP_FILENAME %%PHP_FILENAME%% +ENV PHP_SHA256 %%PHP_SHA256%% + +RUN set -xe \ + && buildDeps=" \ + $PHP_EXTRA_BUILD_DEPS \ + libcurl4-openssl-dev \ + libedit-dev \ + libsqlite3-dev \ + libssl-dev \ + libxml2-dev \ + xz-utils \ + " \ + && apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* \ + && curl -fSL "http://php.net/get/$PHP_FILENAME/from/this/mirror" -o "$PHP_FILENAME" \ + && echo "$PHP_SHA256 *$PHP_FILENAME" | sha256sum -c - \ + && curl -fSL "http://php.net/get/$PHP_FILENAME.asc/from/this/mirror" -o "$PHP_FILENAME.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && for key in $GPG_KEYS; do \ + gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ + done \ + && gpg --batch --verify "$PHP_FILENAME.asc" "$PHP_FILENAME" \ + && rm -r "$GNUPGHOME" "$PHP_FILENAME.asc" \ + && mkdir -p /usr/src/php \ + && tar -xf "$PHP_FILENAME" -C /usr/src/php --strip-components=1 \ + && rm "$PHP_FILENAME" \ + && cd /usr/src/php \ + && ./configure \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + $PHP_EXTRA_CONFIGURE_ARGS \ + --disable-cgi \ +# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself) + --enable-mysqlnd \ + --with-curl \ + --with-libedit \ + --with-openssl \ + --with-zlib \ + && make -j"$(nproc)" \ + && make install \ + && { find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; } \ + && make clean \ + && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false -o APT::AutoRemove::SuggestsImportant=false $buildDeps + +COPY docker-php-ext-* /usr/local/bin/ + +#### +CMD ["php", "-a"] +#### diff --git a/docker-php-ext-configure b/docker-php-ext-configure index 3d21b5bb..39947c8f 100755 --- a/docker-php-ext-configure +++ b/docker-php-ext-configure @@ -1,9 +1,9 @@ -#!/bin/bash +#!/bin/sh set -e ext="$1" extDir="/usr/src/php/ext/$ext" -if [ -z "$ext" -o ! -d "$extDir" ]; then +if [ -z "$ext" ] || ! [ -d "$extDir" ]; then echo >&2 "usage: $0 ext-name [configure flags]" echo >&2 " ie: $0 gd --with-jpeg-dir=/usr/local/something" echo >&2 diff --git a/docker-php-ext-enable b/docker-php-ext-enable index edb07ed8..367aaf2b 100755 --- a/docker-php-ext-enable +++ b/docker-php-ext-enable @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh set -e cd "$(php -r 'echo ini_get("extension_dir");')" @@ -34,32 +34,30 @@ while true; do esac done -modules=() -while [ $# -gt 0 ]; do - module="$1" - shift +modules= +for module; do if [ -z "$module" ]; then continue fi - if [ -f "$module.so" -a ! -f "$module" ]; then + if [ -f "$module.so" ] && ! [ -f "$module" ]; then # allow ".so" to be optional - module+='.so' + module="$module.so" fi - if [ ! -f "$module" ]; then + if ! [ -f "$module" ]; then echo >&2 "error: $(readlink -f "$module") does not exist" echo >&2 usage >&2 exit 1 fi - modules+=( "$module" ) + modules="$modules $module" done -if [ "${#modules[@]}" -eq 0 ]; then +if [ -z "$modules" ]; then usage >&2 exit 1 fi -for module in "${modules[@]}"; do +for module in $modules; do if nm -g "$module" | grep -q ' zend_extension_entry$'; then # https://wiki.php.net/internals/extensions#loading_zend_extensions line="zend_extension=$(readlink -f "$module")" diff --git a/docker-php-ext-install b/docker-php-ext-install index 2c488cce..67180a86 100755 --- a/docker-php-ext-install +++ b/docker-php-ext-install @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh set -e cd /usr/src/php/ext @@ -36,10 +36,8 @@ while true; do esac done -exts=() -while [ $# -gt 0 ]; do - ext="$1" - shift +exts= +for ext; do if [ -z "$ext" ]; then continue fi @@ -49,21 +47,25 @@ while [ $# -gt 0 ]; do usage >&2 exit 1 fi - exts+=( "$ext" ) + exts="$exts $ext" done -if [ "${#exts[@]}" -eq 0 ]; then +if [ -z "$exts" ]; then usage >&2 exit 1 fi -for ext in "${exts[@]}"; do +for ext in $exts; do ( cd "$ext" [ -e Makefile ] || docker-php-ext-configure "$ext" make -j"$j" make -j"$j" install - find modules -maxdepth 1 -name '*.so' -exec basename '{}' ';' | xargs --no-run-if-empty --verbose docker-php-ext-enable + find modules \ + -maxdepth 1 \ + -name '*.so' \ + -exec basename '{}' ';' \ + | xargs -r docker-php-ext-enable make -j"$j" clean ) done diff --git a/update.sh b/update.sh index 087c2f06..cd600f6d 100755 --- a/update.sh +++ b/update.sh @@ -63,18 +63,37 @@ for version in "${versions[@]}"; do exit 1 fi - ( set -x; cp docker-php-ext-* "$version/" ) + dockerfiles=() - for variant in apache fpm zts; do - echo "Generating $version/$variant/Dockerfile from $variant-Dockerfile-block-*" + cp -v Dockerfile-debian.template "$version/Dockerfile" + cp -v docker-php-ext-* "$version/" + dockerfiles+=( "$version/Dockerfile" ) + + if [ -d "$version/alpine" ]; then + cp -v Dockerfile-alpine.template "$version/alpine/Dockerfile" + cp -v docker-php-ext-* "$version/alpine/" + dockerfiles+=( "$version/alpine/Dockerfile" ) + fi + + for target in apache fpm zts fpm/alpine zts/alpine; do + [ -d "$version/$target" ] || continue + base="$version/Dockerfile" + variant="${target%%/*}" + if [ "$target" != "$variant" ]; then + variantVariant="${target#$variant/}" + [ -d "$version/$variantVariant" ] || continue + base="$version/$variantVariant/Dockerfile" + fi + echo "Generating $version/$target/Dockerfile from $base + $variant-Dockerfile-block-*" awk ' $1 == "####" { ia = 0 } !ia { print } $1 == "####" { ia = 1; ab++; ac = 0 } ia { ac++ } ia && ac == 1 { system("cat '$variant'-Dockerfile-block-" ab) } - ' "$version/Dockerfile" > "$version/$variant/Dockerfile" - ( set -x; cp docker-php-ext-* "$version/$variant/" ) + ' "$base" > "$version/$target/Dockerfile" + cp -v docker-php-ext-* "$version/$target/" + dockerfiles+=( "$version/$target/Dockerfile" ) done if [ -z "$fullVersion" ]; then @@ -85,10 +104,10 @@ for version in "${versions[@]}"; do ( set -x sed -ri ' - s/^(ENV PHP_VERSION) .*/\1 '"$fullVersion"'/; - s/^(ENV PHP_FILENAME) .*/\1 '"$filename"'/; - s/^(ENV PHP_SHA256) .*/\1 '"$sha256"'/; - s/^(ENV GPG_KEYS) [0-9a-fA-F ]*$/\1 '"$gpgKey"'/; - ' "$version/Dockerfile" "$version/"*/Dockerfile + s!%%PHP_VERSION%%!'"$fullVersion"'!; + s!%%PHP_FILENAME%%!'"$filename"'!; + s!%%PHP_SHA256%%!'"$sha256"'!; + s!%%GPG_KEYS%%!'"$gpgKey"'!; + ' "${dockerfiles[@]}" ) done