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.
This commit is contained in:
Akira Yamamoto 2026-04-26 18:36:35 +10:00
parent 23b7780056
commit 3b3cddeb41
3 changed files with 30 additions and 0 deletions

View file

@ -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/

View file

@ -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/

18
docker/librespeed-php.ini Normal file
View file

@ -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