Skip to content
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 support for entrypoint scripts #162

Merged
merged 2 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/test_buildx_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
20 changes: 16 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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"]
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
15 changes: 3 additions & 12 deletions root/tmp/setup/php-extensions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions root/tmp/setup/sqlsrv-extension.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 -
Expand All @@ -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/*
36 changes: 36 additions & 0 deletions root/usr/local/bin/moodle-docker-php-entrypoint
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions tests/docker-entrypoint.d/20-example.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
; Test file which disable file uploads.
file_uploads = Off
10 changes: 10 additions & 0 deletions tests/docker-entrypoint.d/30-sourced.sh
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions tests/docker-entrypoint.d/40-exec.sh
Original file line number Diff line number Diff line change
@@ -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
27 changes: 27 additions & 0 deletions tests/fixtures/check-entrypoint-scripts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

$sourced = file_exists('/var/www/data/sourced.txt');
$executed = file_exists('/var/www/data/executed.txt');

if (php_sapi_name() === 'cli') {
if ($sourced && $executed) {
echo "OK\n";
exit(0);
} else if ($sourced && !$executed) {
echo "Executable file was not executed";
} else {
echo "non-executable file was not sourced";
}
exit(1);
} else {
if ($sourced && $executed) {
header('HTTP/1.1 200 - OK');
exit(0);
} else if ($sourced && !$executed) {
$message = "Executable file was not executed";
} else {
$message = "non-executable file was not sourced";
}
header('HTTP/1.1 500 - ' . $message);
exit(1);
}
20 changes: 20 additions & 0 deletions tests/fixtures/check-ini.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

$uploadsEnabled = ini_get('file_uploads');

if (php_sapi_name() === 'cli') {
if (empty($uploadsEnabled)) {
echo "OK\n";
exit(0);
}
echo "Uploads are enabled and should be disabled.";
var_dump($uploadsEnabled);
exit(1);
} else {
if (empty($uploadsEnabled)) {
header('HTTP/1.1 200 - OK');
exit(0);
}
header('HTTP/1.1 500 - Uploads are enabled and should be disabled: ' . var_export($uploadsEnabled, true));
exit(1);
}