diff --git a/.github/workflows/test_buildx_and_publish.yml b/.github/workflows/test_buildx_and_publish.yml index 1a6b0a8..64c8e14 100644 --- a/.github/workflows/test_buildx_and_publish.yml +++ b/.github/workflows/test_buildx_and_publish.yml @@ -24,9 +24,15 @@ jobs: - name: Run tests run: | - docker run --name test0 -d -p 8000:80 -v $PWD/tests/fixtures:/var/www/html moodle-php-apache + docker run --name test0 -d -p 8000:80 \ + -v $PWD/tests/fixtures:/var/www/html \ + -v $PWD/tests/docker-entrypoint.d:/docker-entrypoint.d \ + moodle-php-apache docker exec test0 php /var/www/html/test.php + docker exec test0 php /var/www/html/check-ini.php + docker exec test0 php /var/www/html/check-entrypoint-scripts.php curl --fail http://127.0.0.1:8000/test.php + curl --fail http://127.0.0.1:8000/check-ini.php - name: Display container logs on failure if: failure() diff --git a/Dockerfile b/Dockerfile index ad3d20a..2b41996 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,10 +5,6 @@ ARG TARGETPLATFORM ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} RUN echo "Building for ${TARGETPLATFORM}" -ADD root/ / -# Fix the original permissions of /tmp, the PHP default upload tmp dir. -RUN chmod 777 /tmp && chmod +t /tmp - # Install some packages that are useful within the images. RUN apt-get update && apt-get install -y \ git \ @@ -30,11 +26,27 @@ RUN apt-get update && apt-get install -y \ # Setup the required extensions. ARG DEBIAN_FRONTEND=noninteractive +ADD root/tmp/setup/php-extensions.sh /tmp/setup/php-extensions.sh RUN /tmp/setup/php-extensions.sh + +# Install Oracle Instantclient +ADD root/tmp/setup/oci8-extension.sh /tmp/setup/oci8-extension.sh RUN /tmp/setup/oci8-extension.sh ENV LD_LIBRARY_PATH /usr/local/instantclient +# Install Microsoft sqlsrv. +ADD root/tmp/setup/sqlsrv-extension.sh /tmp/setup/sqlsrv-extension.sh +RUN /tmp/setup/sqlsrv-extension.sh + RUN mkdir /var/www/moodledata && chown www-data /var/www/moodledata && \ mkdir /var/www/phpunitdata && chown www-data /var/www/phpunitdata && \ mkdir /var/www/behatdata && chown www-data /var/www/behatdata && \ mkdir /var/www/behatfaildumps && chown www-data /var/www/behatfaildumps + +ADD root/usr /usr + +# Fix the original permissions of /tmp, the PHP default upload tmp dir. +RUN chmod 777 /tmp && chmod +t /tmp + +CMD ["apache2-foreground"] +ENTRYPOINT ["moodle-docker-php-entrypoint"] diff --git a/README.md b/README.md index f0e986b..dba7d9e 100644 --- a/README.md +++ b/README.md @@ -39,15 +39,40 @@ $ docker run --name web0 -p 8080:80 -v $PWD:/var/www/html moodlehq/moodle-php-a * For PHP 7.3 and up, both `linux/amd64` and `linux/arm64` images are being built. Note that `linux/arm64` doesn't support the sqlsrv and oci extensions yet. Other than that, both architectures work exactly the same. * Verified by [automated tests](https://travis-ci.com/moodlehq/moodle-php-apache). * Autobuilt from GHA, on push. +* Support for entrypoint scripts and PHP Configuration ## Directories -To faciliate testing and easy setup the following directories are created and owned by www-data by default: +To facilitate testing and easy setup the following directories are created and owned by www-data by default: * `/var/www/moodledata` * `/var/www/phpunitdata` * `/var/www/behatdata` * `/var/www/behatfaildumps` +## Initialisation scripts + +If you would like to do additional initialization, you can add one or more `*.sh`, or `*.ini` scripts under `/docker-entrypoint.d` (creating the directory if necessary). When the entrypoint script is called, it will run any executable `*.sh` script, source any non-executable `*.sh` scripts found in that directory, and will copy any `*.ini` scripts into the PHP Configuration directory (`/usr/local/etc/php/conf.d`). + +For example, to configure PHP to support a higher `upload_max_filesize` option you might add the following to a `config/10-uploads.ini` file: + +``` +; Specify a max filesize of 200M for uploads. +upload_max_filesize = 200M +post_max_size = 210M +``` + +When starting your container you could do so passing in the config directory: + +``` +docker run \ + --name web0 \ + -p 8080:80 \ + -v $PWD/moodle:/var/www/html + -v $PWD/config:/docker-entrypoint.d \ + moodle-php-apache:latest +``` + +These initialization files will be executed in sorted name order as defined by the current locale, which defaults to en_US.utf8. ## See also This container is part of a set of containers for Moodle development, see also: diff --git a/root/tmp/setup/php-extensions.sh b/root/tmp/setup/php-extensions.sh index cf56e5d..38c9ff1 100755 --- a/root/tmp/setup/php-extensions.sh +++ b/root/tmp/setup/php-extensions.sh @@ -5,9 +5,9 @@ set -e echo "Installing apt dependencies" # Build packages will be added during the build, but will be removed at the end. -BUILD_PACKAGES="gettext gnupg libcurl4-openssl-dev libfreetype6-dev libicu-dev libjpeg62-turbo-dev \ +BUILD_PACKAGES="gettext libcurl4-openssl-dev libfreetype6-dev libicu-dev libjpeg62-turbo-dev \ libldap2-dev libmariadb-dev libmemcached-dev libpng-dev libpq-dev libxml2-dev libxslt-dev \ - unixodbc-dev uuid-dev" + uuid-dev" # Packages for Postgres. PACKAGES_POSTGRES="libpq5" @@ -17,7 +17,7 @@ PACKAGES_MYMARIA="libmariadb3" # Packages for other Moodle runtime dependenices. PACKAGES_RUNTIME="ghostscript libaio1 libcurl4 libgss3 libicu67 libmcrypt-dev libxml2 libxslt1.1 \ - libzip-dev locales sassc unixodbc unzip zip" + libzip-dev locales sassc unzip zip" # Packages for Memcached. PACKAGES_MEMCACHED="libmemcached11 libmemcachedutil2" @@ -74,15 +74,6 @@ echo "pcov.exclude='~\/(tests|coverage|vendor|node_modules)\/~'" >> /usr/local/e echo "pcov.directory=." >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini echo "pcov.initial.files=1024" >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini -# Install Microsoft dependencies for sqlsrv. -# (kept apart for clarity, still need to be run here -# before some build packages are deleted) -if [[ ${TARGETPLATFORM} == "linux/amd64" ]]; then - /tmp/setup/sqlsrv-extension.sh -else - echo "sqlsrv extension not available for ${TARGETPLATFORM} architecture, skipping" -fi - # Keep our image size down.. pecl clear-cache apt-get remove --purge -y $BUILD_PACKAGES diff --git a/root/tmp/setup/sqlsrv-extension.sh b/root/tmp/setup/sqlsrv-extension.sh index 4911851..f00385f 100755 --- a/root/tmp/setup/sqlsrv-extension.sh +++ b/root/tmp/setup/sqlsrv-extension.sh @@ -2,6 +2,25 @@ set -e +if [[ ${TARGETPLATFORM} != "linux/amd64" ]]; then + echo "sqlsrv extension not available for ${TARGETPLATFORM} architecture, skipping" + exit 0 +fi + +# Packages for build. +BUILD_PACKAGES="gnupg unixodbc-dev" + +# Packages for sqlsrv runtime. +PACKAGES_SQLSRV="unixodbc" + +# Note: These dependencies must be installed before installing the Microsoft source because there is a package in there +# which breaks the install. +echo "Installing apt dependencies" +apt-get update +apt-get install -y --no-install-recommends apt-transport-https \ + $BUILD_PACKAGES \ + $PACKAGES_SQLSRV + # Install Microsoft dependencies for sqlsrv echo "Downloading sqlsrv files" curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - @@ -17,3 +36,10 @@ ln -fsv /opt/mssql-tools/bin/* /usr/bin # Need 5.10.1 (or later) for PHP 8.2 support pecl install sqlsrv-5.10.1 docker-php-ext-enable sqlsrv + +# Keep our image size down.. +pecl clear-cache +apt-get remove --purge -y $BUILD_PACKAGES +apt-get autoremove -y +apt-get clean +rm -rf /var/lib/apt/lists/* diff --git a/root/usr/local/bin/moodle-docker-php-entrypoint b/root/usr/local/bin/moodle-docker-php-entrypoint new file mode 100755 index 0000000..3abc465 --- /dev/null +++ b/root/usr/local/bin/moodle-docker-php-entrypoint @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -Eeo pipefail + +docker_process_init_files() { + local f + for f; do + case "$f" in + *.sh) + # Note: This hack is required for MacOS because the exeute bit is not checked for bind mounts. + # The executable bit is stored, but the test -x flag does not return corretly. + # Copying the file to an alternate file system allows it to be respected. + rm -f /tmp/testscript + cp "$f" /tmp/testscript + if [ -x "/tmp/testscript" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.ini) + echo "$0: copying $f into /usr/local/etc/php/conf.d/" + cp "$f" /usr/local/etc/php/conf.d/ + ;; + esac + done +} + +echo "Running entrypoint files from /docker-entrypoint.d/*" +docker_process_init_files /docker-entrypoint.d/* +echo + +echo "Starting docker-php-entrypoint with $@" +source /usr/local/bin/docker-php-entrypoint +echo diff --git a/tests/docker-entrypoint.d/20-example.ini b/tests/docker-entrypoint.d/20-example.ini new file mode 100644 index 0000000..ec45086 --- /dev/null +++ b/tests/docker-entrypoint.d/20-example.ini @@ -0,0 +1,2 @@ +; Test file which disable file uploads. +file_uploads = Off diff --git a/tests/docker-entrypoint.d/30-sourced.sh b/tests/docker-entrypoint.d/30-sourced.sh new file mode 100644 index 0000000..86a6286 --- /dev/null +++ b/tests/docker-entrypoint.d/30-sourced.sh @@ -0,0 +1,10 @@ +# This file should not have a shbang! as it is expected to be sourced. +# It should not be executable either. + +mkdir -p /var/www/data + +(return 0 2>/dev/null) && sourced=1 || sourced=0 + +if [[ $sourced -eq 1 ]]; then + echo "Sourced" >> /var/www/data/sourced.txt +fi diff --git a/tests/docker-entrypoint.d/40-exec.sh b/tests/docker-entrypoint.d/40-exec.sh new file mode 100755 index 0000000..d924fc6 --- /dev/null +++ b/tests/docker-entrypoint.d/40-exec.sh @@ -0,0 +1,10 @@ +# This file should not have a shbang! as it is expected to be sourced. +# It should not be executable either. + +mkdir -p /var/www/data + +(return 0 2>/dev/null) && sourced=1 || sourced=0 + +if [[ $sourced -eq 0 ]]; then + echo "Executed" >> /var/www/data/executed.txt +fi diff --git a/tests/fixtures/check-entrypoint-scripts.php b/tests/fixtures/check-entrypoint-scripts.php new file mode 100644 index 0000000..aa06d16 --- /dev/null +++ b/tests/fixtures/check-entrypoint-scripts.php @@ -0,0 +1,27 @@ +