Description
Dockerfile.alpine uses FROM php:8-alpine and then runs apk add php-apache2 … to install Apache + mod_php. The result is two PHP installs side by side in the same image:
- The docker-library PHP at
/usr/local/bin/php (~30 MB) reading /usr/local/etc/php/conf.d. Never used: Apache loads mod_php from the apk packages, not this binary.
- The apk-installed PHP at
/usr/bin/php reading /etc/phpXX/conf.d. This is the one mod_php uses.
Beyond the unused binary, the FROM image also carries PHP source headers under /usr/src/php and build artifacts that aren't needed at runtime. A fresh build of current master lands at ~227 MB.
Switching the base to plain alpine:3.23 and installing PHP via apk only drops the image to ~102 MB, a 56% reduction. Apache still serves the same speedtest with the same mod_php.
Background
#201 (2019) originally proposed FROM alpine:latest, and the maintainer at the time said yes. That work stalled. #631 (2024) eventually shipped Dockerfile.alpine from a different contributor using FROM php:8-alpine. The review focused on Docker labels and PHP version (8.2 → 8.3); the FROM choice wasn't questioned. The dual-install layout has been carrying ~120 MB of dead weight since the file landed.
Proposed change
Replace FROM php:8-alpine with FROM alpine:3.23 (current latest stable) and add php to the apk package list so /usr/bin/php is guaranteed.
-FROM php:8-alpine
+FROM alpine:3.23
RUN apk add --quiet --no-cache \
bash \
apache2 \
+ php \
php-apache2 \
php-ctype \
php-phar \
...
The dead docker-php-extension-installer comment block can also go; it never applied to the alpine variant.
Verification
Built both variants on the same host:
libsp-old:alpine 227 MB (master HEAD, FROM php:8-alpine)
libsp-exp:alpine 102 MB (FROM alpine:3.23)
Inside the experiment image: only /usr/bin/php exists, command -v php returns the apk binary, and mod_php is /usr/lib/apache2/mod_php84.so from the php84-apache2 package — same PHP major as master's FROM php:8-alpine.
The full Playwright e2e suite passes against the experiment image: 12/12 tests, 22.4s. Specs: classic-standalone-regression, design-switch, modes, title-special-chars across standalone/backend/frontend/dual configs.
Notes
- alpine:3.23's
php-apache2 meta resolves to php84-apache2, the same PHP major the current master image lands on via FROM php:8-alpine. No version regression.
- Base-image swap only, no application code change.
- Dependabot needs no config change: the docker ecosystem at
/ auto-discovers FROM lines, so it'll drop php:8-alpine and pick up alpine:3.23 automatically. One behavior shift to be aware of: future Alpine bumps via Dependabot can carry implicit PHP major bumps when the apk meta shifts (e.g., 3.24 might move php-apache2 to php85). If you want PHP locked to a major, pin php84-apache2 and the matching extension packages explicitly.
PR open: #800.
Description
Dockerfile.alpineusesFROM php:8-alpineand then runsapk add php-apache2 …to install Apache + mod_php. The result is two PHP installs side by side in the same image:/usr/local/bin/php(~30 MB) reading/usr/local/etc/php/conf.d. Never used: Apache loads mod_php from the apk packages, not this binary./usr/bin/phpreading/etc/phpXX/conf.d. This is the one mod_php uses.Beyond the unused binary, the FROM image also carries PHP source headers under
/usr/src/phpand build artifacts that aren't needed at runtime. A fresh build of current master lands at ~227 MB.Switching the base to plain
alpine:3.23and installing PHP via apk only drops the image to ~102 MB, a 56% reduction. Apache still serves the same speedtest with the same mod_php.Background
#201 (2019) originally proposed
FROM alpine:latest, and the maintainer at the time said yes. That work stalled. #631 (2024) eventually shippedDockerfile.alpinefrom a different contributor usingFROM php:8-alpine. The review focused on Docker labels and PHP version (8.2 → 8.3); theFROMchoice wasn't questioned. The dual-install layout has been carrying ~120 MB of dead weight since the file landed.Proposed change
Replace
FROM php:8-alpinewithFROM alpine:3.23(current latest stable) and addphpto the apk package list so/usr/bin/phpis guaranteed.The dead
docker-php-extension-installercomment block can also go; it never applied to the alpine variant.Verification
Built both variants on the same host:
Inside the experiment image: only
/usr/bin/phpexists,command -v phpreturns the apk binary, and mod_php is/usr/lib/apache2/mod_php84.sofrom thephp84-apache2package — same PHP major as master'sFROM php:8-alpine.The full Playwright e2e suite passes against the experiment image: 12/12 tests, 22.4s. Specs: classic-standalone-regression, design-switch, modes, title-special-chars across standalone/backend/frontend/dual configs.
Notes
php-apache2meta resolves tophp84-apache2, the same PHP major the current master image lands on viaFROM php:8-alpine. No version regression./auto-discovers FROM lines, so it'll dropphp:8-alpineand pick upalpine:3.23automatically. One behavior shift to be aware of: future Alpine bumps via Dependabot can carry implicit PHP major bumps when the apk meta shifts (e.g., 3.24 might movephp-apache2to php85). If you want PHP locked to a major, pinphp84-apache2and the matching extension packages explicitly.PR open: #800.