update README with latest structure

This commit is contained in:
Elijah Duffy
2025-12-08 02:00:35 -08:00
parent 4ca77133be
commit aeec557b45

View File

@@ -1,68 +1,54 @@
# auvem/php-fpm-wordpress — multi-version PHP-FPM + nginx Docker images # auvem/php-fpm-wordpress — multi-version PHP-FPM + nginx Docker images
This repository contains Dockerfiles and configuration for building PHP-FPM 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.
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 ## Repository Layout
- `docker/` — top-level directory containing per-image lanes - `php-fpm/` — top-level directory containing PHP version lanes
- `7.4/` — PHP 7.4 FPM lane (multi-stage, Alpine-based) - `7.4/` — PHP 7.4 FPM lane (multi-stage, Alpine-based)
- `Dockerfile` — builds PHP + required extensions - `Dockerfile` — builds PHP + required extensions
- `nginx/` — nginx lane - `...`
- `nginx/` — NGINX build configuration with batteries-included configuration file
- `Dockerfile` — nginx:alpine-slim image that ships `nginx.conf` - `Dockerfile` — nginx:alpine-slim image that ships `nginx.conf`
- `nginx.conf` — default server config that works with the php-fpm image - `nginx.conf` — default server config that works with the php-fpm image
- `php-fpm/` — canonical shared files - `shared/php-fpm/` — canonical shared files
- `www.conf` — canonical php-fpm pool config - `www.conf` — canonical php-fpm pool config
- `entrypoint.sh` — optional guarded entrypoint to fix mounts at container start - `entrypoint.sh` — optional guarded entrypoint to fix mount permissions at container start
### Note about shared files and builds ### Note about shared files and builds
The CI workflow is configured to build with the repository root as the Docker 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.
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 ## Adding a new PHP version
1. Create `docker/<version>/` (e.g. `docker/8.1/`). 1. Create `php-fpm/<version>/` (e.g. `php-fpm/8.1/`).
2. Copy `docker/7.4/Dockerfile` into the new directory and update `ARG BASE_TAG` 2. Copy `php-fpm/7.4/Dockerfile` (for example) into the new directory and update `ARG BASE_TAG` to the desired `php:<version>-fpm-alpine` tag.
to the desired `php:<version>-fpm-alpine` tag.
3. Adjust `docker-php-ext-install`/build deps if needed. 3. Adjust `docker-php-ext-install`/build deps if needed.
4. Push — CI will detect the new lane and build it. 4. Update the `matrix.lane` list for the `build` job in `.github/workflows/php-fpm.yml`.
5. Push — CI will detect the new lane and build it. NOTE: CI will additionally rebuild all other images registered in `matrix.lane`, cost tradeoff of this overhead vs. the benefits of intermittent rebuilds with latest OS security patches built-in should be weighed.
## Bind mounts and permissions ## Bind mounts and permissions
- Images use `/var/www/html` as the webroot. When you mount a host directory - Images use `/var/www/html` as the webroot. When you mount a host directory over that path the mount replaces the image contents, including ownership.
over that path the mount replaces the image contents, including ownership.
- Recommended safe options: - Recommended safe options:
- Pre-chown host files to UID/GID 1000 before starting containers: - Pre-chown host files to UID/GID 1000 before starting containers:
```bash ```bash
sudo chown -R 1000:1000 ./wp_root sudo chown -R 1000:1000 ./wp_root
``` ```
- Or enable the entrypoint-based fixup in php-fpm by setting - Or enable the entrypoint-based fixup in php-fpm by setting `CHOWN_ON_START=1` for the `php-fpm` service (the entrypoint is guarded — it only runs when this env is explicitly enabled).
`CHOWN_ON_START=1` for the `php-fpm` service (the entrypoint is guarded — it
only runs when this env is explicitly enabled).
## Local Testing & Development ## Local Testing & Development
Use the provided `docker-compose.yml` in the repo root for local 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.
it builds images from the repo (so shared files are available) and mounts
`./wp_root` for site content.
## Production Example ## Production Example
Below is an example `docker-compose.yml` for production deployments that pulls Below is an example `docker-compose.yml` for production deployments that pulls images from the package registry at gitea.auvem.com. Adjust image versions and secrets as appropriate.
images from your registry instead of building locally. Adjust image names and
secrets as appropriate.
```yaml ```yaml
services: services:
db: db:
image: mariadb:10.11 image: mariadb:latest
restart: unless-stopped restart: unless-stopped
environment: environment:
MYSQL_DATABASE: wordpress MYSQL_DATABASE: wordpress
@@ -70,55 +56,32 @@ services:
MYSQL_PASSWORD: ${MYSQL_PASSWORD} MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes: volumes:
- db_data:/var/lib/mysql - ./db_data:/var/lib/mysql
php-fpm: php-fpm:
image: gitea.auvem.com/auvem/wordpress-docker/php-fpm:7.4-stable image: gitea.auvem.com/auvem/wordpress-docker/php-fpm:7.4-stable
restart: unless-stopped restart: unless-stopped
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes: volumes:
- ./wp_root:/var/www/html:rw - ./wp_root:/var/www/html:rw
nginx: nginx:
image: gitea.auvem.com/auvem/wordpress-docker/nginx:stable image: gitea.auvem.com/auvem/wordpress-docker/nginx:latest
ports: ports:
- "80:80" - "80:80"
depends_on: depends_on:
- php-fpm - php-fpm
volumes: volumes:
- ./wp_root:/var/www/html:ro - ./wp_root:/var/www/html:ro
volumes:
db_data: {}
``` ```
## CI / build notes ## CI / build notes
- The GitHub Actions workflow at `.github/workflows/build.yml` discovers
immediate subdirectories of `docker/` and builds each as a lane. The workflow
has been updated to use the repository root as the Docker build context and
to set the `file` property to the lane Dockerfile (so shared files in
`docker/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 example `7.4-stable`).
- The nginx lane is pushed to `gitea.auvem.com/auvem/wordpress-nginx:stable`.
If you prefer a different naming convention, update the `meta` step in the workflow.
### Security & hardening ### Security & hardening
- Multi-stage builds keep final images minimal and reduce attack surface. - Multi-stage builds keep final images minimal and reduce attack surface.
- PHP uses `php.ini-production` with opcache tuned. The php-fpm pool is - PHP uses `php.ini-production` with opcache tuned. The php-fpm pool is configured to drop workers to `app` (UID 1000) while the master runs as `root` to avoid socket/permission surprises; workers remain unprivileged.
configured to drop workers to `app` (UID 1000) while the master runs as - The nginx config contains conservative security headers and blocking of hidden files; review and extend headers (CSP, COEP, COOP) as needed per-site.
`root` to 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 ### Production deployment and archival
- For archival (quiesce + tar), stop services and `tar` the `./wp_root` and any - For archival (quiesce + tar), stop services and `tar` the `./wp_root` and any associated volumes (database dump + attachments). Ensure services are fully topped to avoid inconsistent state.
associated volumes (database dump + attachments). Ensure services are fully
stopped to avoid inconsistent state.