php-fpm: refactor with deterministic config files & improved debug
All checks were successful
php-fpm-build / build (7.4) (push) Successful in 5m6s
All checks were successful
php-fpm-build / build (7.4) (push) Successful in 5m6s
This commit is contained in:
@@ -31,12 +31,21 @@ The CI workflow is configured to build with the repository root as the Docker bu
|
|||||||
|
|
||||||
- Images use `/var/www/html` as the webroot. When you mount a host directory over that path the mount replaces the image contents, including ownership.
|
- Images use `/var/www/html` as the webroot. When you mount a host directory over that path the mount replaces the image contents, including ownership.
|
||||||
- Recommended safe options:
|
- Recommended safe options:
|
||||||
|
|
||||||
- Pre-chown host files to UID/GID 1000 before starting containers:
|
- Pre-chown host files to UID/GID 1000 before starting containers:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo chown -R 1000:1000 ./wp_root
|
sudo chown -R 1000:1000 ./wp_root
|
||||||
```
|
```
|
||||||
|
|
||||||
- Or enable the entrypoint-based fixup in php-fpm by setting `CHOWN_ON_START=1` for the `php-fpm` service (the entrypoint is guarded — it only runs when this env is explicitly enabled).
|
- Or enable the entrypoint-based fixup in php-fpm by setting `CHOWN_ON_START=1` for the `php-fpm` service (the entrypoint is guarded — it only runs when this env is explicitly enabled).
|
||||||
|
|
||||||
|
## Logging & debugging
|
||||||
|
|
||||||
|
- PHP-FPM is configured to stream its master/process worker logs and PHP error log to stderr, so `docker compose logs php-fpm` (or your platform equivalent) will always contain fatal errors.
|
||||||
|
- When you need full stack traces in the browser, set `FORCE_DEBUG_ERRORS=1` on the `php-fpm` service. The shipped `force-debug.php` bootstrap will notice the flag, turn on verbose error reporting, and emit a single log line indicating that debug mode is active.
|
||||||
|
- Remove or unset `FORCE_DEBUG_ERRORS` after troubleshooting so production responses stay clean.
|
||||||
|
|
||||||
## Local Testing & Development
|
## Local Testing & Development
|
||||||
|
|
||||||
Use the provided `docker-compose.yml` in the repo root for local development — it builds images from the repo (so shared files are available) and mounts `./wp_root` for site content.
|
Use the provided `docker-compose.yml` in the repo root for local development — it builds images from the repo (so shared files are available) and mounts `./wp_root` for site content.
|
||||||
|
|||||||
@@ -79,30 +79,16 @@ RUN addgroup -g 1000 app && \
|
|||||||
mkdir -p /var/run/php /run/php /var/log/php && \
|
mkdir -p /var/run/php /run/php /var/log/php && \
|
||||||
chown -R app:app /var/run/php /run/php /var/log/php
|
chown -R app:app /var/run/php /run/php /var/log/php
|
||||||
|
|
||||||
# Minimal security / production tuning for opcache and PHP
|
# Ship opinionated PHP configuration snippets from source control
|
||||||
RUN set -eux; \
|
COPY php-fpm/conf.d/ /usr/local/etc/php/conf.d/
|
||||||
{ \
|
|
||||||
echo 'opcache.enable=1'; \
|
|
||||||
echo 'opcache.memory_consumption=128'; \
|
|
||||||
echo 'opcache.interned_strings_buffer=8'; \
|
|
||||||
echo 'opcache.max_accelerated_files=10000'; \
|
|
||||||
echo 'opcache.revalidate_freq=2'; \
|
|
||||||
echo 'opcache.fast_shutdown=1'; \
|
|
||||||
echo 'opcache.enable_file_override=0'; \
|
|
||||||
} > /usr/local/etc/php/conf.d/zz-opcache.ini; \
|
|
||||||
{ \
|
|
||||||
echo 'expose_php = Off'; \
|
|
||||||
echo 'display_errors = On'; \
|
|
||||||
echo 'log_errors = On'; \
|
|
||||||
echo 'error_log = /proc/self/fd/2'; \
|
|
||||||
} > /usr/local/etc/php/conf.d/zz-hardening.ini
|
|
||||||
|
|
||||||
# Copy the force-debug script and enable it
|
# Copy the force-debug script (enablement is handled via conf.d/99-force-debug.ini)
|
||||||
COPY --chown=app:app shared/php-fpm/force-debug.php /usr/local/etc/php/force-debug.php
|
COPY --chown=app:app shared/php-fpm/force-debug.php /usr/local/etc/php/force-debug.php
|
||||||
RUN echo 'auto_prepend_file = /usr/local/etc/php/force-debug.php' > /usr/local/etc/php/conf.d/zz-force-debug.ini
|
|
||||||
|
|
||||||
# Copy pool configuration from this directory
|
# Copy pool configuration from this directory
|
||||||
COPY --chown=app:app php-fpm/${BASE_VERSION}/www.conf /usr/local/etc/php-fpm.d/www.conf
|
COPY --chown=app:app php-fpm/${BASE_VERSION}/www.conf /usr/local/etc/php-fpm.d/www.conf
|
||||||
|
# Copy the global php-fpm configuration so logging defaults are predictable
|
||||||
|
COPY php-fpm/${BASE_VERSION}/php-fpm.conf /usr/local/etc/php-fpm.conf
|
||||||
|
|
||||||
# Copy entrypoint from shared path in repo root
|
# Copy entrypoint from shared path in repo root
|
||||||
COPY --chown=root:root shared/php-fpm/entrypoint.sh /usr/local/bin/entrypoint.sh
|
COPY --chown=root:root shared/php-fpm/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|||||||
8
php-fpm/7.4/php-fpm.conf
Normal file
8
php-fpm/7.4/php-fpm.conf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[global]
|
||||||
|
pid = /var/run/php/php-fpm.pid
|
||||||
|
error_log = /proc/self/fd/2
|
||||||
|
log_limit = 8192
|
||||||
|
log_buffering = no
|
||||||
|
daemonize = no
|
||||||
|
|
||||||
|
include = /usr/local/etc/php-fpm.d/*.conf
|
||||||
@@ -41,6 +41,10 @@ request_terminate_timeout = 300s
|
|||||||
request_slowlog_timeout = 5s
|
request_slowlog_timeout = 5s
|
||||||
slowlog = /var/log/php/www-slow.log
|
slowlog = /var/log/php/www-slow.log
|
||||||
|
|
||||||
|
; Force all PHP errors into the container log stream so kubernetes/docker can collect them.
|
||||||
|
php_admin_flag[log_errors] = on
|
||||||
|
php_admin_value[error_log] = /proc/self/fd/2
|
||||||
|
|
||||||
; Redirect worker stdout and stderr to the main error log.
|
; Redirect worker stdout and stderr to the main error log.
|
||||||
; This ensures that any `echo` or `var_dump` calls from workers are captured in the container logs.
|
; This ensures that any `echo` or `var_dump` calls from workers are captured in the container logs.
|
||||||
catch_workers_output = yes
|
catch_workers_output = yes
|
||||||
|
|||||||
7
php-fpm/conf.d/40-opcache.ini
Normal file
7
php-fpm/conf.d/40-opcache.ini
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
opcache.enable=1
|
||||||
|
opcache.memory_consumption=128
|
||||||
|
opcache.interned_strings_buffer=8
|
||||||
|
opcache.max_accelerated_files=10000
|
||||||
|
opcache.revalidate_freq=2
|
||||||
|
opcache.fast_shutdown=1
|
||||||
|
opcache.enable_file_override=0
|
||||||
5
php-fpm/conf.d/90-runtime.ini
Normal file
5
php-fpm/conf.d/90-runtime.ini
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
expose_php=Off
|
||||||
|
log_errors=On
|
||||||
|
error_log=/proc/self/fd/2
|
||||||
|
display_errors=Off
|
||||||
|
display_startup_errors=Off
|
||||||
1
php-fpm/conf.d/99-force-debug.ini
Normal file
1
php-fpm/conf.d/99-force-debug.ini
Normal file
@@ -0,0 +1 @@
|
|||||||
|
auto_prepend_file=/usr/local/etc/php/force-debug.php
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -euo pipefail
|
set -eu
|
||||||
|
|
||||||
: ${CHOWN_ON_START:=}
|
PHP_ENTRYPOINT="/usr/local/bin/docker-php-entrypoint"
|
||||||
if [ "${CHOWN_ON_START}" = "1" ] || [ "${CHOWN_ON_START}" = "true" ]; then
|
if [ ! -x "${PHP_ENTRYPOINT}" ]; then
|
||||||
|
echo "[entrypoint] Missing ${PHP_ENTRYPOINT}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${CHOWN_ON_START:-}" in
|
||||||
|
1|true|TRUE|yes|on)
|
||||||
echo "[entrypoint] CHOWN_ON_START enabled — fixing ownership of /var/www/html"
|
echo "[entrypoint] CHOWN_ON_START enabled — fixing ownership of /var/www/html"
|
||||||
if [ -d /var/www/html ]; then
|
if [ -d /var/www/html ]; then
|
||||||
chown -R 1000:1000 /var/www/html || true
|
chown -R 1000:1000 /var/www/html || true
|
||||||
fi
|
fi
|
||||||
fi
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
exec "$@"
|
exec "${PHP_ENTRYPOINT}" "$@"
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
// force-debug.php
|
// force-debug.php
|
||||||
// This script is prepended to all PHP requests to force error reporting.
|
// Optional debug bootstrap that can be toggled with FORCE_DEBUG_ERRORS=1.
|
||||||
|
|
||||||
|
$forceDebug = getenv('FORCE_DEBUG_ERRORS');
|
||||||
|
if ($forceDebug === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized = strtolower(trim($forceDebug));
|
||||||
|
$enabled = in_array($normalized, ['1', 'true', 'yes', 'on'], true);
|
||||||
|
|
||||||
|
if (!$enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set error reporting to the highest level.
|
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
// Ensure errors are displayed directly in the browser.
|
|
||||||
// This overrides any ini_set('display_errors', 'Off') in the application.
|
|
||||||
ini_set('display_errors', '1');
|
ini_set('display_errors', '1');
|
||||||
|
ini_set('display_startup_errors', '1');
|
||||||
// Also ensure errors are logged.
|
|
||||||
ini_set('log_errors', '1');
|
ini_set('log_errors', '1');
|
||||||
?>
|
ini_set('error_log', '/proc/self/fd/2');
|
||||||
|
|
||||||
|
error_log('[force-debug] Verbose error reporting enabled via FORCE_DEBUG_ERRORS');
|
||||||
|
|||||||
Reference in New Issue
Block a user