From c2a4f4cd7b65d71a5369abb38f28481166b959b5 Mon Sep 17 00:00:00 2001 From: Ernesto Baschny Date: Tue, 28 Oct 2025 16:29:32 +0100 Subject: [PATCH 1/4] Allow setting php.ini and php-fpm pool setting via individial env vars --- README.md | 18 ++++++++++++++++++ example-app/.env.example | 12 ++++++++++++ files/entrypoint-extras.sh | 33 ++++++++++++++++++++++++++++++++- files/entrypoint.sh | 24 ++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 875c939..5e4cd1c 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,24 @@ Application root is `/app`. Application runs as user `application` (uid=1000). | `PHP_FPM_OVERRIDE` | fpm | | Allow overriding php-fpm pool settings. The multiline content for php-fpm.conf here. Use "\n" for multiline i.e. in ECS | | `PHP_EXTENSIONS` | fpm, ssh | (all) | Comma separated list of PHP extensions to enable (if this is not set, all are enabled). | | `PHP_DISABLE_EXTENSIONS` | fpm, ssh | | Comma separated list of PHP extensions to disable (in case you keep all enabled, you can disable individual ones, i.e. igbinary). | +| `PHPINI__xxx__yyy` | fpm, ssh | | Set php.ini setting `xxx.yyy` (always lower cased) | +| `PHPFPM__xxx__yyy` | fpm | | Set php-fpm pool setting `xxx.yyy` (always lower cased) | + +The `PHPINI__...` and `PHPFPM__...` allow to set individual settings for `php.ini` +and `php-fpm.conf` (pool settings) using individual environment variables. Just +replace the `.` in the settings by `__`. Examples: + +Upper case allowed (will be lower-cased): +``` +PHPINI__SESSION__SAVE_HANDLER=redis +PHPINI__REDIS__SESSION__LOCKING_ENABLED=1 +``` + +Or: +``` +PHPFPM__request_terminate_timeout=30s +PHPFPM__pm__max_children=15 +``` ## Example usage diff --git a/example-app/.env.example b/example-app/.env.example index 351f9ff..a884f04 100644 --- a/example-app/.env.example +++ b/example-app/.env.example @@ -42,3 +42,15 @@ slowlog = /tmp/slow.log request_slowlog_timeout = 3s pm.max_children = 5 " + +# ----------------------------------------- +# PHP settings by env vars +# ----------------------------------------- + +# Example of setting php.ini settings +PHPINI__SESSION__SAVE_HANDLER=redis +PHPINI__REDIS__SESSION__LOCKING_ENABLED=1 + +# Example of setting PHP-FPM settings +PHPFPM__REQUEST_terminate_timeout=30s +PHPFPM__pm__max_children=15 diff --git a/files/entrypoint-extras.sh b/files/entrypoint-extras.sh index d44b682..dabf07c 100644 --- a/files/entrypoint-extras.sh +++ b/files/entrypoint-extras.sh @@ -7,6 +7,8 @@ # Controls which extensions are enabled. +CUSTOM_INI="/usr/local/etc/php/conf.d/zz-02-custom.ini" + if [ ! -z "${PHP_EXTENSIONS}" ]; then # If PHP_EXTENSIONS is set: only enable the ones specified @@ -85,10 +87,39 @@ if [ ! -z "${APPLICATION_UID}" ] || [ ! -z "${APPLICATION_GID}" ]; then fi if [ ! -z "${PHP_INI_OVERRIDE}" ]; then - echo "${PHP_INI_OVERRIDE}" | sed -e 's/\\n/\n/g' > /usr/local/etc/php/conf.d/zz-02-custom.ini + echo "${PHP_INI_OVERRIDE}" | sed -e 's/\\n/\n/g' > "$CUSTOM_INI" fi unset PHP_INI_OVERRIDE +# Fill from ENV variables prefixed with PHPINI__ +# Example: PHPINI__session__save_handler=redis -> session.save_handler = redis +# PHPINI__redis__session__locking_enabled=1 -> redis.session.locking_enabled = 1 +if env | grep -q '^PHPINI__'; then + # Ensure the custom ini exists (and keep any content already written above) + touch "$CUSTOM_INI" + # Iterate over all matching env var names only + for name in $(printenv | awk -F= '/^PHPINI__/ {print $1}'); do + value=$(printenv "$name") + # Transform key: PHPINI__this__setting => this.setting + key=${name#PHPINI__} + key=$(printf '%s' "$key" | sed 's/__/./g') + key=${key,,} + # Append as "key = value" (value is written as-is; quote in ENV if needed) + printf '* setting in php.ini: %s = %s\n' "$key" "$value" + printf '%s = %s\n' "$key" "$value" >> "$CUSTOM_INI" + # Unset them, not relevant to the running containers + unset "$name" + done +fi + +if [ -s "$CUSTOM_INI" ] +then + echo "* Custom php.ini settings ($CUSTOM_INI)" + echo "- - - 8< - - -" + cat $CUSTOM_INI + echo "- - - 8< - - -" +fi + # Remove ENV variables that are meant only for the SSH container unset SSH_PRIVATE_KEY diff --git a/files/entrypoint.sh b/files/entrypoint.sh index e0c66e7..ddd0258 100644 --- a/files/entrypoint.sh +++ b/files/entrypoint.sh @@ -32,5 +32,29 @@ if [ ! -z "${PHP_FPM_OVERRIDE}" ]; then fi unset PHP_FPM_OVERRIDE +# Fill from ENV variables prefixed with PHPFPM__ +# Examples: +# PHPFPM__pm__max_children=15 => pm.max_children = 15 +# PHPFPM__request_terminate_timeout=30s => request_terminate_timeout = 30s +# PHPFPM__slowlog=/data/php-logs/slow.log => slowlog = /data/php-logs/slow.log +# +if env | grep -q '^PHPFPM__'; then + # Ensure the custom ini exists (and keep any content already written above) + touch "$CUSTOM_INI" + # Iterate over all matching env var names only + for name in $(printenv | awk -F= '/^PHPFPM__/ {print $1}'); do + value=$(printenv "$name") + # Transform key: PHPINI__this__setting => this.setting + key=${name#PHPFPM__} + key=$(printf '%s' "$key" | sed 's/__/./g') + key=${key,,} + # Append as "key = value" (value is written as-is; quote in ENV if needed) + printf '* PHP-FPM pool setting: %s = %s\n' "$key" "$value" + printf '%s = %s\n' "$key" "$value" >> "$PHP_FPM_POOL_CONF" + # Unset them, not relevant to the running containers + unset "$name" + done +fi + # Start the "real" entrypoint . /usr/local/bin/docker-php-entrypoint From 3d9c26e4ea754ac4bd74cd884062951068fbdf60 Mon Sep 17 00:00:00 2001 From: Ernesto Baschny Date: Tue, 28 Oct 2025 18:43:25 +0100 Subject: [PATCH 2/4] Fix "Bad substitution" (we are in sh, not bash) --- files/entrypoint-extras.sh | 3 ++- files/entrypoint.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/files/entrypoint-extras.sh b/files/entrypoint-extras.sh index dabf07c..fe5ebe0 100644 --- a/files/entrypoint-extras.sh +++ b/files/entrypoint-extras.sh @@ -103,7 +103,8 @@ if env | grep -q '^PHPINI__'; then # Transform key: PHPINI__this__setting => this.setting key=${name#PHPINI__} key=$(printf '%s' "$key" | sed 's/__/./g') - key=${key,,} + # Lowercase in POSIX sh (dash/busybox) without bash-specific substitution + key=$(printf '%s' "$key" | tr '[:upper:]' '[:lower:]') # Append as "key = value" (value is written as-is; quote in ENV if needed) printf '* setting in php.ini: %s = %s\n' "$key" "$value" printf '%s = %s\n' "$key" "$value" >> "$CUSTOM_INI" diff --git a/files/entrypoint.sh b/files/entrypoint.sh index ddd0258..bd667f7 100644 --- a/files/entrypoint.sh +++ b/files/entrypoint.sh @@ -47,7 +47,7 @@ if env | grep -q '^PHPFPM__'; then # Transform key: PHPINI__this__setting => this.setting key=${name#PHPFPM__} key=$(printf '%s' "$key" | sed 's/__/./g') - key=${key,,} + key=$(printf '%s' "$key" | tr '[:upper:]' '[:lower:]') # Append as "key = value" (value is written as-is; quote in ENV if needed) printf '* PHP-FPM pool setting: %s = %s\n' "$key" "$value" printf '%s = %s\n' "$key" "$value" >> "$PHP_FPM_POOL_CONF" From 07d235af152b6159fb60686422a1980ba36c1c60 Mon Sep 17 00:00:00 2001 From: Ernesto Baschny Date: Tue, 28 Oct 2025 18:44:29 +0100 Subject: [PATCH 3/4] Fix docs, comments and enhance example --- README.md | 8 +++++++- example-app/.env.example | 7 ++++--- files/entrypoint-extras.sh | 3 +-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5e4cd1c..cf789d7 100644 --- a/README.md +++ b/README.md @@ -176,15 +176,21 @@ replace the `.` in the settings by `__`. Examples: Upper case allowed (will be lower-cased): ``` PHPINI__SESSION__SAVE_HANDLER=redis +PHPINI__SESSION__SAVE_PATH='"tcp://redis:6379?persistent=1&weight=1&database=10&prefix=PHPSESSID:"' PHPINI__REDIS__SESSION__LOCKING_ENABLED=1 ``` -Or: +Or (lower case also fine): ``` PHPFPM__request_terminate_timeout=30s PHPFPM__pm__max_children=15 ``` +**Note**: make sure that potentially required double quotes `"` are part of the +"string" that ends up in the ENV variable, so quote as necessary, because this +string is copied "as is" to the ini files. See example above for the +`PHPINI__SESSION__SAVE_PATH` - this would be the syntax for a `.env` file. + ## Example usage Copy the files from `example-app/` folder to your application, tweak, and you are diff --git a/example-app/.env.example b/example-app/.env.example index a884f04..e3a9408 100644 --- a/example-app/.env.example +++ b/example-app/.env.example @@ -47,10 +47,11 @@ pm.max_children = 5 # PHP settings by env vars # ----------------------------------------- -# Example of setting php.ini settings +# Example of setting php.ini settings, UPPER CASED PHPINI__SESSION__SAVE_HANDLER=redis +PHPINI__SESSION__SAVE_PATH='"tcp://redis:6379?persistent=1&weight=1&database=10&prefix=PHPSESSID:"' PHPINI__REDIS__SESSION__LOCKING_ENABLED=1 -# Example of setting PHP-FPM settings -PHPFPM__REQUEST_terminate_timeout=30s +# Example of setting PHP-FPM settings, lower cased also possible +PHPFPM__request_terminate_timeout=30s PHPFPM__pm__max_children=15 diff --git a/files/entrypoint-extras.sh b/files/entrypoint-extras.sh index fe5ebe0..b93b3bf 100644 --- a/files/entrypoint-extras.sh +++ b/files/entrypoint-extras.sh @@ -103,10 +103,9 @@ if env | grep -q '^PHPINI__'; then # Transform key: PHPINI__this__setting => this.setting key=${name#PHPINI__} key=$(printf '%s' "$key" | sed 's/__/./g') - # Lowercase in POSIX sh (dash/busybox) without bash-specific substitution key=$(printf '%s' "$key" | tr '[:upper:]' '[:lower:]') # Append as "key = value" (value is written as-is; quote in ENV if needed) - printf '* setting in php.ini: %s = %s\n' "$key" "$value" + printf '* Setting in php.ini: %s = %s\n' "$key" "$value" printf '%s = %s\n' "$key" "$value" >> "$CUSTOM_INI" # Unset them, not relevant to the running containers unset "$name" From d571b9c0102975e95d3c689f97f60934797f702a Mon Sep 17 00:00:00 2001 From: Ernesto Baschny Date: Wed, 29 Oct 2025 10:55:09 +0100 Subject: [PATCH 4/4] Reset custom php.ini in case we wipe all env settings --- files/entrypoint-extras.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/entrypoint-extras.sh b/files/entrypoint-extras.sh index b93b3bf..1426d68 100644 --- a/files/entrypoint-extras.sh +++ b/files/entrypoint-extras.sh @@ -86,6 +86,9 @@ if [ ! -z "${APPLICATION_UID}" ] || [ ! -z "${APPLICATION_GID}" ]; then test -d /home/application && find /home/application/ -mount -not -user application -exec chown application: {} \; fi +# Start with a clean custom php.ini: +rm -f "$CUSTOM_INI" + if [ ! -z "${PHP_INI_OVERRIDE}" ]; then echo "${PHP_INI_OVERRIDE}" | sed -e 's/\\n/\n/g' > "$CUSTOM_INI" fi