From 3b3cddeb4135363fec46dcce5578ef18aa8da120 Mon Sep 17 00:00:00 2001 From: Akira Yamamoto <3007213+akirayamamoto@users.noreply.github.com> Date: Sun, 26 Apr 2026 18:36:35 +1000 Subject: [PATCH] fix(docker): raise PHP post_max_size for default 20MB upload chunks speedtest_worker.js uploads in 20 MB chunks by default (xhr_ul_blob_megabytes: 20) but the official Docker images inherit PHP's stock post_max_size = 8M / upload_max_filesize = 2M, so every upload chunk: * triggers a "POST Content-Length ... exceeds the limit" warning (leaked into the response body of /backend/empty.php on the Debian variant where display_errors is on; suppressed but still emitted on Alpine where it's off); * causes empty.php's subsequent header() calls to fail with "Cannot modify header information - headers already sent", leaving the response without proper status, cache, or CORS directives. Ship a small docker/librespeed-php.ini with post_max_size = 32M, upload_max_filesize = 32M, memory_limit = 256M and COPY it into the right conf.d for each base image (/usr/local/etc/php/conf.d on Debian, /etc/php84/conf.d on Alpine). 99- prefix follows the NN-name.ini packaging convention so this loads after distro defaults but never silently shadows operator overrides. Verified post-fix on both variants: a 20 MB POST to /backend/empty.php returns HTTP 200 / 0 bytes with no warning leakage. --- Dockerfile | 6 ++++++ Dockerfile.alpine | 6 ++++++ docker/librespeed-php.ini | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 docker/librespeed-php.ini diff --git a/Dockerfile b/Dockerfile index 8aeca24..60665ce 100755 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,12 @@ RUN install-php-extensions iconv gd pdo pdo_mysql pdo_pgsql pgsql \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +COPY docker/librespeed-php.ini /tmp/librespeed-php.ini +RUN scan_dir="$(php -r 'echo rtrim(PHP_CONFIG_FILE_SCAN_DIR);')" \ + && [ -n "$scan_dir" ] \ + && install -D -m 0644 /tmp/librespeed-php.ini "$scan_dir/99-librespeed.ini" \ + && rm /tmp/librespeed-php.ini + # Prepare files and folders RUN mkdir -p /speedtest/ diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 47f694b..beec4c9 100755 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -20,6 +20,12 @@ RUN apk add --quiet --no-cache \ RUN ln -sf /dev/stdout /var/log/apache2/access.log && \ ln -sf /dev/stderr /var/log/apache2/error.log +COPY docker/librespeed-php.ini /tmp/librespeed-php.ini +RUN scan_dir="$(/usr/bin/php -r 'echo rtrim(PHP_CONFIG_FILE_SCAN_DIR);')" \ + && [ -n "$scan_dir" ] \ + && install -D -m 0644 /tmp/librespeed-php.ini "$scan_dir/99-librespeed.ini" \ + && rm /tmp/librespeed-php.ini + # Prepare files and folders RUN mkdir -p /speedtest/ diff --git a/docker/librespeed-php.ini b/docker/librespeed-php.ini new file mode 100644 index 0000000..82bcea3 --- /dev/null +++ b/docker/librespeed-php.ini @@ -0,0 +1,18 @@ +; LibreSpeed-recommended PHP override. +; +; speedtest_worker.js uploads in 20 MB chunks by default +; (xhr_ul_blob_megabytes: 20). PHP's stock post_max_size = 8M rejects +; every chunk: PHP emits a "POST Content-Length ... exceeds the +; limit" startup warning and prevents empty.php from sending its +; response headers (Cache-Control, Pragma, Connection, and CORS +; under ?cors). +; +; The upload throughput number itself is unaffected — the worker +; reads bytes-on-wire from xhr.upload.onprogress, not the response +; body — but the response from empty.php is otherwise malformed. +; +; 32M is the next round number above the worker's 20M default; it +; leaves headroom for operators who tune xhr_ul_blob_megabytes +; upwards. + +post_max_size = 32M