diff --git a/CHANGELOG.md b/CHANGELOG.md index 97a9191b..dd094f1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ ### Minor changes +* **2026-11-05** + * The *apache* and *fpm* images stop right away when a `docker stop` is requested during a long startup step (e.g. a `STARTUP_COMMAND_*`, or the configuration of the extensions on a loaded host): they were killed after the stop timeout (exit code 137 after 10 s) + * **2026-11-03** * The `php` command is about 20 ms faster on each call: it detects the changes of the `PHP_*` environment variables without starting PHP a first time. The configuration is now also regenerated when a `PHP_*` variable is removed * The README recommends the fpm variant with its built-in Apache to serve a web application, and links to the v6 roadmap. The php2shell fix is now mentioned in the supported versions diff --git a/tests-suite/tool-startup-command.sh b/tests-suite/tool-startup-command.sh index ec6f6150..ef64b378 100755 --- a/tests-suite/tool-startup-command.sh +++ b/tests-suite/tool-startup-command.sh @@ -35,3 +35,20 @@ test_phpStartupWarning() { assert_equals "0" "$?" "Docker run failed" assert_equals "startup-ok" "$RESULT" } +############################################################ +## A docker stop during a long startup command stops the container right away +############################################################ +test_stopDuringStartupCommand() { + NAME="test-startup-stop-$(unused_port)" + docker run --name "${NAME}" ${RUN_OPTIONS} -d -e STARTUP_COMMAND_1="sleep 30" \ + "${REPO}:${TAG_PREFIX}${PHP_VERSION}-${BRANCH}-slim-${BRANCH_VARIANT}${ARCH_SUFFIX}" sleep 300 > /dev/null + for _ in $(seq 1 60); do + docker exec "${NAME}" pgrep -fx "sleep 30" > /dev/null 2>&1 && break + sleep 0.5 + done + START=$(date +%s) + docker stop "${NAME}" > /dev/null 2>&1 + DURATION=$(( $(date +%s) - START )) + docker rm -f "${NAME}" > /dev/null 2>&1 + assert "test ${DURATION} -lt 5" "Stopping during the startup command took ${DURATION}s (killed by timeout?)" +} diff --git a/utils/docker-entrypoint-as-root.sh b/utils/docker-entrypoint-as-root.sh index ec6cdcb4..7cdcf0c2 100755 --- a/utils/docker-entrypoint-as-root.sh +++ b/utils/docker-entrypoint-as-root.sh @@ -8,6 +8,13 @@ if [[ "$IMAGE_VARIANT" == "apache" ]]; then trap 'exit 0' WINCH fi +# Runs a startup step in the background and waits for it, so that a stop signal interrupts a long step (e.g. a +# STARTUP_COMMAND): bash only runs a trap once the foreground command ends +startup_step() { + "$@" <&0 & + wait $! +} + # Let's write a file saying the container is started (we are no longer in build mode, useful for php_proxy.sh) touch /opt/container_started @@ -152,11 +159,11 @@ unset REMOTE_HOST_FOUND source /usr/local/bin/php_env_fingerprint.sh php_env_fingerprint > /opt/php_env_fingerprint -/usr/bin/real_php -d display_errors=stderr /usr/local/bin/generate_conf.php > /etc/php/${PHP_VERSION}/mods-available/generated_conf.ini -PHP_VERSION="${PHP_VERSION}" /usr/bin/real_php -d display_errors=stderr /usr/local/bin/setup_extensions.php | sudo bash +startup_step /usr/bin/real_php -d display_errors=stderr /usr/local/bin/generate_conf.php > /etc/php/${PHP_VERSION}/mods-available/generated_conf.ini +startup_step bash -c '/usr/bin/real_php -d display_errors=stderr /usr/local/bin/setup_extensions.php | sudo bash' if [[ -n "$COMPOSER_VERSION" ]]; then - /usr/local/bin/select_composer_version.sh "$COMPOSER_VERSION" + startup_step /usr/local/bin/select_composer_version.sh "$COMPOSER_VERSION" fi if [[ -n "$LOCALES" ]]; then @@ -164,22 +171,22 @@ if [[ -n "$LOCALES" ]]; then echo 'Locales are not available in this image. If you are using the thecodingmachine/php "slim" variant, do not forget to add "ARG INSTALL_LOCALES=1" in your Dockerfile. Check the documentation for more details.' >&2 exit 1 fi - locale-gen --keep-existing $LOCALES > /dev/null + startup_step locale-gen --keep-existing $LOCALES > /dev/null fi # output on the logs can be done by writing on the "tini" PID. Useful for CRONTAB TINI_PID=`ps -e | grep tini | awk '{print $1;}'` -/usr/bin/real_php -d display_errors=stderr /usr/local/bin/generate_cron.php $TINI_PID > /tmp/generated_crontab +startup_step /usr/bin/real_php -d display_errors=stderr /usr/local/bin/generate_cron.php $TINI_PID > /tmp/generated_crontab chmod 0644 /tmp/generated_crontab if [[ "$WITH_APACHE" == "1" ]]; then - /usr/bin/real_php -d display_errors=stderr /usr/local/bin/enable_apache_mods.php | bash + startup_step bash -c '/usr/bin/real_php -d display_errors=stderr /usr/local/bin/enable_apache_mods.php | bash' fi if [ -e /etc/container/startup.sh ]; then - sudo -E -u "#$DOCKER_USER_ID" /etc/container/startup.sh + startup_step sudo -E -u "#$DOCKER_USER_ID" /etc/container/startup.sh fi -sudo -E -u "#$DOCKER_USER_ID" sh -c "/usr/bin/real_php -d display_errors=stderr /usr/local/bin/startup_commands.php | bash" +startup_step sudo -E -u "#$DOCKER_USER_ID" sh -c "/usr/bin/real_php -d display_errors=stderr /usr/local/bin/startup_commands.php | bash" if [[ "$APACHE_DOCUMENT_ROOT" == /* ]]; then export ABSOLUTE_APACHE_DOCUMENT_ROOT="$APACHE_DOCUMENT_ROOT"