Drop the Debian COPY comment (it only restated the code) and the
version-fragility framing in the Alpine comment.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The previous build-time discovery via PHP_CONFIG_FILE_SCAN_DIR worked
but invoked a PHP binary just to learn a path that's already a stable
contract of each base image:
* php:8-apache exports PHP_INI_DIR=/usr/local/etc/php as part of the
docker-library image template, stable across PHP majors. Reference
it directly in the COPY destination — no RUN, no validation needed.
* Alpine's apk php-apache2 always installs mod_php's conf.d at
/etc/phpXX/conf.d (currently /etc/php84). The FROM php:8-alpine
image also ships its own PHP at /usr/local/etc/php/conf.d, but
mod_php doesn't read from there. Glob /etc/php*/conf.d to track
the apk-installed PHP major automatically; explicit error if the
glob matches nothing.
Net effect: Debian goes from a 5-line RUN block to a 1-line COPY.
Alpine keeps a small RUN block but no longer invokes a PHP binary,
so it doesn't matter which of the two PHP installs `php` resolves
to via $PATH.
Verified: both variants build, install the override at the right
conf.d, mod_php reports post_max_size=32M, and a 20 MB POST to
/backend/empty.php returns HTTP 200 / 0 bytes with no warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
- Load server list dynamically from servers.json for Docker frontend/dual modes
- Copy servers.json to web root in entrypoint.sh for frontend/dual modes
- Change back link from href="/" to href="./" for subdirectory installs
- Use binary search for visible chart data range (O(log n) vs O(n))
- Add 200ms minimum interval between pings to limit sample rate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a prolonged ping-based stability test with real-time canvas chart,
stats (avg/min/max/jitter/packet loss), stability rating, external ping
targets, CSV export, and Docker support. Link from main page to stability test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build an array of {idx, server} pairs before sorting so the original
SPEEDTEST_SERVERS index is carried through, eliminating the per-option
indexOf call.
Parse server names more robustly for sorting:
- "City, Country, Provider" → use second part as country
- "City, Country (1) (Hetzner)" → strip parentheticals from country
- "Frankfurt, Germany (FRA01)" → country is "Germany" not "Germany (FRA01)"
Address code review findings:
- Sort a shallow copy instead of mutating the caller's array
- Add null guard on server.name to handle malformed entries
- Use original SPEEDTEST_SERVERS index for classic UI option values
Sort the server dropdown by country first, then by city within the same
country. This makes it easier to find servers in a specific country when
the list is long. Applies to both modern and classic UIs.
ca-certificates-bundle (which provides /etc/ssl/certs/ca-certificates.crt)
is already pulled in transitively by apache2 / php-apache2 on alpine:3.23,
so live HTTPS calls from PHP work today (verified with file_get_contents
against ipinfo.io). But the master image (FROM php:8-alpine) installs
the full ca-certificates package explicitly, and operators with
IPINFO_APIKEY configured rely on outbound HTTPS. Make the dependency
explicit to:
* Match master's package set rather than relying on a transitive pull
that some future apk dep change could drop.
* Document the runtime TLS requirement at the Dockerfile level instead
of leaving it implicit.
~50 KB image-size cost; the umbrella ca-certificates package adds the
update-ca-certificates CLI on top of the bundle. Per Qodo's review on
PR #800.
The current Dockerfile.alpine pulls FROM php:8-alpine and then `apk
add php-apache2`. The result is two PHP installs side by side: the
docker-library PHP at /usr/local/bin/php (~30 MB, never used by
Apache) and the apk-installed PHP at /usr/bin/php (which mod_php
actually loads).
Pinning a fresh Alpine release and installing the apk packages
directly drops the dead /usr/local/bin/php install entirely.
Expected wins:
- Smaller image (~30 MB less; 2024 baseline was ~120 MB)
- One PHP binary, no $PATH ambiguity
- Cleaner story for any follow-up that touches PHP config
* Initial plan
* Add Docker TAGLINE env customization for modern UI slogan
Agent-Logs-Url: https://github.com/librespeed/speedtest/sessions/e1da6e0e-5194-453d-bffb-961ed782e215
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Refine TAGLINE replacement and expand E2E coverage
Agent-Logs-Url: https://github.com/librespeed/speedtest/sessions/e1da6e0e-5194-453d-bffb-961ed782e215
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Fix TAGLINE sed delimiter and add apostrophe tagline E2E test
- Switch TAGLINE sed from '#' to '/' delimiter so html_escape'd
apostrophes (') don't break the sed expression
- Add standalone-apostrophe Docker service with TAGLINE="It'd rather be fast!"
- Add standaloneApostrophe URL (port 18186) to env.js
- Add E2E test asserting the apostrophe tagline renders correctly
Agent-Logs-Url: https://github.com/librespeed/speedtest/sessions/ebe265a8-4b1e-49b5-959a-66133ea0ab3a
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* docker: restore TITLE env handling in entrypoint
* docker: escape TITLE for HTML output
* test(e2e): cover TITLE with umlauts and quotes
---------
Co-authored-by: Stefan Stidl <sti-github@stidl.com>