4.8 KiB
auvem/php-fpm-wordpress — multi-version PHP-FPM + nginx Docker images
This repository contains Dockerfiles and configuration for building PHP-FPM images optimized for WordPress and a companion nginx image. It aims to make adding and maintaining multiple PHP versions straightforward while keeping builds reproducible and small.
Repository Layout
docker/— top-level directory containing per-image lanes7.4/— PHP 7.4 FPM lane (multi-stage, Alpine-based)Dockerfile— builds PHP + required extensions
nginx/— nginx laneDockerfile— nginx:alpine-slim image that shipsnginx.confnginx.conf— default server config that works with the php-fpm image
php-fpm/— canonical shared fileswww.conf— canonical php-fpm pool configentrypoint.sh— optional guarded entrypoint to fix mounts at container start
Note about shared files and builds
The CI workflow is configured to build with the repository root as the Docker
build context and to point Docker to lane Dockerfiles (for example,
file: docker/7.4/Dockerfile). That means Dockerfiles can safely COPY
shared files from docker/php-fpm/ without requiring per-lane duplicates. This
reduces maintenance overhead — keep the canonical copy in
docker/php-fpm/www.conf and the CI will make it available to all lanes.
Adding a new PHP version
- Create
docker/<version>/(e.g.docker/8.1/). - Copy
docker/7.4/Dockerfileinto the new directory and updateARG BASE_TAGto the desiredphp:<version>-fpm-alpinetag. - Adjust
docker-php-ext-install/build deps if needed. - Push — CI will detect the new lane and build it.
Bind mounts and permissions
- Images use
/var/www/htmlas the webroot. When you mount a host directory over that path the mount replaces the image contents, including ownership. - Recommended safe options:
- Pre-chown host files to UID/GID 1000 before starting containers:
sudo chown -R 1000:1000 ./wp_root- Or enable the entrypoint-based fixup in php-fpm by setting
CHOWN_ON_START=1for thephp-fpmservice (the entrypoint is guarded — it only runs when this env is explicitly enabled).
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.
Production Example
Below is an example docker-compose.yml for production deployments that pulls
images from your registry instead of building locally. Adjust image names and
secrets as appropriate.
services:
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- db_data:/var/lib/mysql
php-fpm:
image: gitea.auvem.com/auvem/wordpress-php-fpm:7.4-stable
restart: unless-stopped
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp_root:/var/www/html:rw
nginx:
image: gitea.auvem.com/auvem/wordpress-nginx:stable
ports:
- "80:80"
depends_on:
- php-fpm
volumes:
- ./wp_root:/var/www/html:ro
volumes:
db_data: {}
CI / build notes
- The GitHub Actions workflow at
.github/workflows/build.ymldiscovers immediate subdirectories ofdocker/and builds each as a lane. The workflow has been updated to use the repository root as the Docker build context and to set thefileproperty to the lane Dockerfile (so shared files indocker/php-fpm/are accessible during build). - The workflow tags and pushes images using the pattern
gitea.auvem.com/auvem/wordpress-<component>:<tag>.- PHP lanes are pushed to
gitea.auvem.com/auvem/wordpress-php-fpm:<version>-stable(for example7.4-stable). - The nginx lane is pushed to
gitea.auvem.com/auvem/wordpress-nginx:stable. If you prefer a different naming convention, update themetastep in the workflow.
- PHP lanes are pushed to
Security & hardening
- Multi-stage builds keep final images minimal and reduce attack surface.
- PHP uses
php.ini-productionwith opcache tuned. The php-fpm pool is configured to drop workers toapp(UID 1000) while the master runs asrootto avoid socket/permission surprises; workers remain unprivileged. - The nginx config contains conservative security headers and blocking of hidden files; review and extend headers (CSP, COEP, COOP) as needed per-site.
Production deployment and archival
- For archival (quiesce + tar), stop services and
tarthe./wp_rootand any associated volumes (database dump + attachments). Ensure services are fully stopped to avoid inconsistent state.