Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/workflows/docker-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ jobs:
id: matrix
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
PHP_VERSIONS='["8.4","8.2"]'
echo "::notice::PR detected — testing PHP 8.4 + 8.2 only (skipping 8.3)"
PHP_VERSIONS='["8.5","8.2"]'
echo "::notice::PR detected — testing PHP 8.5 + 8.2 only (skipping 8.4 and 8.3)"
else
PHP_VERSIONS='["8.4","8.3","8.2"]'
PHP_VERSIONS='["8.5","8.4","8.3","8.2"]'
fi

# Build trixie include list for v2 based on selected PHP versions
Expand Down Expand Up @@ -301,7 +301,7 @@ jobs:
fail-fast: false
matrix:
variant: [v1, v2]
php-version: ['8.4', '8.3', '8.2']
php-version: ['8.5', '8.4', '8.3', '8.2']
php-type: [fpm, cli, apache]
php-base: [alpine, bookworm]
exclude:
Expand All @@ -312,6 +312,18 @@ jobs:
php-base: bookworm
include:
# v2 builds on trixie for Debian images
- variant: v2
php-version: '8.5'
php-type: fpm
php-base: trixie
- variant: v2
php-version: '8.5'
php-type: cli
php-base: trixie
- variant: v2
php-version: '8.5'
php-type: apache
php-base: trixie
- variant: v2
php-version: '8.4'
php-type: fpm
Expand Down
62 changes: 62 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Multi-architecture PHP Docker image builder. Two parallel Dockerfile variants (v1 and v2) produce images for PHP 8.2, 8.3, 8.4, 8.5 across alpine/bookworm (v1) and alpine/trixie (v2), with fpm and cli types. Published to Docker Hub, GHCR, and Quay.io.

Deprecation policy: PHP versions are removed from the build matrix when upstream security support ends ([php.net schedule](https://www.php.net/supported-versions.php)). PHP 8.2 is scheduled for removal after 2026-12-31.

## Local Build Commands

```bash
# Build a single image locally
./extras/test-build.sh v1 8.3-fpm-alpine
./extras/test-build.sh v2 8.3-fpm-alpine # tags as php-docker:8.3-fpm-alpine-v2
./extras/test-build.sh both 8.3-fpm-alpine # builds both variants

# v2 requires BuildKit (test-build.sh sets DOCKER_BUILDKIT=1 automatically)

# Smoke test installed extensions
docker run --rm php-docker:8.3-fpm-alpine php /extras/php_test.php
```

Tag format: `<php-version>-<type>-<baseos>` (e.g., `8.4-cli-trixie`, `8.2-fpm-bookworm`).

Build args used by both Dockerfiles: `VERSION`, `PHPVERSION`, `BASEOS`.

## CI/CD

Primary workflow: `.github/workflows/docker-ci.yml` — runs on push to main, PRs, weekly schedule (Tuesday 3 AM UTC), and `workflow_dispatch`. Uses a build matrix across all variant/version/type/base combinations with `fail-fast: false`.

Key matrix rules:
- v1 uses bookworm for Debian; v2 uses trixie
- No apache type on alpine
- Multi-arch production builds: linux/amd64, linux/arm64, linux/arm/v7
- PR fast-path tests only newest + oldest PHP versions (currently 8.5 + 8.2); push/schedule runs the full matrix

## Architecture: v1 vs v2

**v1 (Dockerfile.v1)**: Simple single-stage build. No init system. Base images from ECR (`public.ecr.aws/docker/library/php`). Suited for single-process containers.

**v2 (Dockerfile.v2)**: s6-overlay v3.2.1.0 for process supervision. OCI labels. Handles Debian Trixie t64 library transitions. BuildKit required. Production multi-process workloads.

Both install 30+ PHP extensions via `install-php-extensions` (with retry/backoff logic) and include Composer, image optimization tools (gifsicle, jpegoptim, optipng, pngquant).

## s6-overlay (v2 only)

- `s6-overlay/cont-init.d/10-php-config` — applies PHP config from environment variables (PHP_MEMORY_LIMIT, PHP_UPLOAD_MAX_FILESIZE, etc.)
- `s6-overlay/services.d/php/run` — auto-detects and starts php-fpm, apache, or sleep for cli
- `s6-overlay/services.d/php/finish` — graceful shutdown

## Platform-Specific Gotchas

- ARM/v7: GD built without AVIF support (no AV1 on armv7)
- Trixie (v2): requires t64 library name handling (`libavif-dev` vs `libavif-devt64`)
- ECR base images preferred over Docker Hub to avoid rate limits
- install-php-extensions download has retry logic with exponential backoff

## Documentation Checks

`docs-ci.yml` validates markdown links on changes to `**.md` or `docs/**`. Config in `.github/markdown-link-check-config.json`.
66 changes: 42 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ Multi-architecture PHP Docker images with extensive extensions for modern web de

## 🎯 Which Image Should I Use?

**New projects or need process supervision?** → Use **v2** images (e.g., `8.3-fpm-alpine-v2`)
**Existing deployments or maximum compatibility?** → Use **v1** images (e.g., `8.3-fpm-alpine`)
**New projects or need process supervision?** → Use **v2** images (e.g., `8.5-fpm-alpine-v2`)
**Existing deployments or maximum compatibility?** → Use **v1** images (e.g., `8.5-fpm-alpine`)

See [v1 vs v2 comparison](#v1-vs-v2-comparison) below for details.

## Features

- **Multi-Architecture Support**: Works on `amd64`, `arm64/aarch64` and `arm32v7/armhf` platforms
- **Multiple PHP Versions**: PHP 8.2, 8.3, and 8.4 (actively built); PHP 7.x, 8.0, and 8.1 deprecated
- **Multiple PHP Versions**: PHP 8.2, 8.3, 8.4, and 8.5 (actively built); PHP 7.x, 8.0, and 8.1 deprecated. PHP 8.2 is scheduled for removal after 2026-12-31 when upstream security support ends — see [deprecation schedule](#deprecation-schedule).
- **Multiple Server Types**: CLI, FPM, and Apache
- **Base OS Options**: Alpine (lightweight) and Debian (v1: Bookworm, v2: Trixie with Bookworm-compatible tags)
- **Extensive Extensions**: 30+ PHP extensions pre-installed
Expand Down Expand Up @@ -75,7 +75,7 @@ The following environment variables are applied at container startup by the s6-o
### Example usage

```bash
docker run -e PHP_MEMORY_LIMIT=512M -e PHP_MAX_EXECUTION_TIME=600 kingpin/php-docker:8.3-fpm-alpine-v2
docker run -e PHP_MEMORY_LIMIT=512M -e PHP_MAX_EXECUTION_TIME=600 kingpin/php-docker:8.5-fpm-alpine-v2
```

## 🚀 Quick Start
Expand All @@ -84,26 +84,26 @@ docker run -e PHP_MEMORY_LIMIT=512M -e PHP_MAX_EXECUTION_TIME=600 kingpin/php-do

```bash
# Run PHP CLI
docker run --rm kingpin/php-docker:8.3-cli-alpine php -v
docker run --rm kingpin/php-docker:8.5-cli-alpine php -v

# Run with your code mounted
docker run --rm -v $(pwd):/app -w /app kingpin/php-docker:8.3-cli-alpine php script.php
docker run --rm -v $(pwd):/app -w /app kingpin/php-docker:8.5-cli-alpine php script.php

# Start PHP-FPM server
docker run -d -p 9000:9000 -v $(pwd):/var/www/html kingpin/php-docker:8.3-fpm-alpine
docker run -d -p 9000:9000 -v $(pwd):/var/www/html kingpin/php-docker:8.5-fpm-alpine
```

### v2 (Modern/Supervised)

```bash
# Run PHP CLI with s6-overlay
docker run --rm kingpin/php-docker:8.3-cli-alpine-v2 php -v
docker run --rm kingpin/php-docker:8.5-cli-alpine-v2 php -v

# Run with your code mounted
docker run --rm -v $(pwd):/app -w /app kingpin/php-docker:8.3-cli-alpine-v2 php script.php
docker run --rm -v $(pwd):/app -w /app kingpin/php-docker:8.5-cli-alpine-v2 php script.php

# Start PHP-FPM with s6 supervision
docker run -d -p 9000:9000 -v $(pwd):/var/www/html kingpin/php-docker:8.3-fpm-alpine-v2
docker run -d -p 9000:9000 -v $(pwd):/var/www/html kingpin/php-docker:8.5-fpm-alpine-v2
```

## v1 vs v2 Comparison
Expand Down Expand Up @@ -218,27 +218,27 @@ These images are designed with security in mind:

1. **Never run as root**: Keep the default non-root user or specify your own
```bash
docker run --user 1001:1001 kingpin/php-docker:8.3-fpm-alpine
docker run --user 1001:1001 kingpin/php-docker:8.5-fpm-alpine
```

2. **Use read-only volumes when possible**
```bash
docker run -v $(pwd)/config:/app/config:ro kingpin/php-docker:8.3-cli-alpine
docker run -v $(pwd)/config:/app/config:ro kingpin/php-docker:8.5-cli-alpine
```

3. **Limit capabilities**: Drop unnecessary capabilities
```bash
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE kingpin/php-docker:8.3-apache-bookworm
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE kingpin/php-docker:8.5-apache-bookworm
```

4. **Set memory and CPU limits**
```bash
docker run --memory="256m" --cpus="0.5" kingpin/php-docker:8.3-fpm-alpine
docker run --memory="256m" --cpus="0.5" kingpin/php-docker:8.5-fpm-alpine
```

5. **Use secrets management for sensitive data**
```bash
docker run --secret db_password kingpin/php-docker:8.3-cli-alpine
docker run --secret db_password kingpin/php-docker:8.5-cli-alpine
```

6. **Regularly update images** to get the latest security patches
Expand All @@ -254,7 +254,7 @@ docker run \
-e PHP_OPCACHE_MEMORY_CONSUMPTION=256 \
-e PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 \
-e PHP_OPCACHE_INTERNED_STRINGS_BUFFER=32 \
kingpin/php-docker:8.3-fpm-alpine
kingpin/php-docker:8.5-fpm-alpine
```

### PHP-FPM Tuning (for FPM variants)
Expand All @@ -275,7 +275,7 @@ pm.max_requests = 500
```bash
docker run \
-e PHP_MEMORY_LIMIT=128M \
kingpin/php-docker:8.3-fpm-alpine
kingpin/php-docker:8.5-fpm-alpine
```

### JIT Configuration (PHP 8.0+)
Expand Down Expand Up @@ -309,15 +309,20 @@ All registries have identical image content and tags.

### Tag Format

- **v1 images**: `{php-version}-{type}-{os}` (e.g., `8.3-fpm-alpine`)
- **v2 images**: `{php-version}-{type}-{os}-v2` (e.g., `8.3-fpm-alpine-v2`)
- **v1 images**: `{php-version}-{type}-{os}` (e.g., `8.5-fpm-alpine`)
- **v2 images**: `{php-version}-{type}-{os}-v2` (e.g., `8.5-fpm-alpine-v2`)

### Current Supported Images

Both v1 and v2 variants are available for all combinations below:

| PHP Version | Type | OS | v1 Tag Example | v2 Tag Example |
|-------------|--------|-----------|------------------------|----------------------------|
| 8.5 | CLI | Alpine | `8.5-cli-alpine` | `8.5-cli-alpine-v2` |
| 8.5 | CLI | Bookworm | `8.5-cli-bookworm` | `8.5-cli-bookworm-v2` |
| 8.5 | FPM | Alpine | `8.5-fpm-alpine` | `8.5-fpm-alpine-v2` |
| 8.5 | FPM | Bookworm | `8.5-fpm-bookworm` | `8.5-fpm-bookworm-v2` |
| 8.5 | Apache | Bookworm | `8.5-apache-bookworm` | `8.5-apache-bookworm-v2` |
| 8.4 | CLI | Alpine | `8.4-cli-alpine` | `8.4-cli-alpine-v2` |
| 8.4 | CLI | Bookworm | `8.4-cli-bookworm` | `8.4-cli-bookworm-v2` |
| 8.4 | FPM | Alpine | `8.4-fpm-alpine` | `8.4-fpm-alpine-v2` |
Expand All @@ -336,6 +341,19 @@ Both v1 and v2 variants are available for all combinations below:

> **Note:** v1 Debian images use Bookworm. v2 Debian images use Trixie, with `:bookworm-v2` tags as compatibility aliases pointing to the same Trixie-built images.

### Deprecation Schedule

PHP versions are removed from the build matrix when upstream security support ends ([php.net schedule](https://www.php.net/supported-versions.php)). Existing image tags remain pullable from registries indefinitely; only **new** builds stop.

| Version | Upstream security ends | Planned removal |
|---------|------------------------|-----------------|
| 8.2 | 2026-12-31 | After 2026-12-31 |
| 8.3 | 2027-12-31 | After 2027-12-31 |
| 8.4 | 2028-12-31 | After 2028-12-31 |
| 8.5 | 2029-12-31 | After 2029-12-31 |

If you're pinned to a `8.2-*` tag, plan to bump to 8.3 or newer before the end of 2026.

### Deprecated Tags (v1 only)

The following tags are deprecated and will not be built going forward, but remain available in registries for backwards compatibility:
Expand All @@ -355,7 +373,7 @@ The following tags are deprecated and will not be built going forward, but remai
- `8.1-fpm-bullseye`, `8.1-fpm-bookworm`, `8.1-fpm-alpine`
- `8.1-apache-bullseye`, `8.1-apache-bookworm`

> **Important:** These versions are deprecated. Please upgrade to PHP 8.2, 8.3, or 8.4 for security and performance.
> **Important:** These versions are deprecated. Please upgrade to an actively-supported PHP version (8.2–8.5) for security and performance.

## 📊 Image Sizes

Expand Down Expand Up @@ -421,15 +439,15 @@ Approximate compressed sizes (vary by PHP version and platform):
### Basic usage with Docker

```bash
docker run -d --name php-app kingpin/php-docker:8.3-cli-alpine php -v
docker run -d --name php-app kingpin/php-docker:8.5-cli-alpine php -v
```

### With Docker Compose

```yaml
services:
php-fpm:
image: kingpin/php-docker:8.3-fpm-alpine
image: kingpin/php-docker:8.5-fpm-alpine
volumes:
- ./src:/var/www/html
networks:
Expand All @@ -456,7 +474,7 @@ For detailed WordPress setup instructions, visit our [guide](https://sumguy.com/
You can build custom images based on these by extending the Dockerfile:

```dockerfile
FROM kingpin/php-docker:8.3-fpm-alpine
FROM kingpin/php-docker:8.5-fpm-alpine

# Add your custom configurations
COPY custom-php.ini /usr/local/etc/php/conf.d/
Expand All @@ -480,7 +498,7 @@ The following PHP versions are **no longer actively built** but remain available
- Available tags: `8.1-cli-alpine`, `8.1-fpm-alpine`, `8.1-apache-bookworm`, etc.

**Migration Path:**
- Upgrade to PHP 8.2 or 8.3 for continued security updates and new builds
- Upgrade to an actively-supported PHP version (8.2–8.5) for continued security updates and new builds
- See [migration guide](docs/migration.md) for upgrade assistance
- Existing images will remain available in Docker Hub, GHCR, and Quay.io

Expand Down
18 changes: 10 additions & 8 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@

#### 1. build-and-test

Runs on every push and pull request:
Runs on every push to `main`, pull request, weekly schedule, and `workflow_dispatch`:

Comment on lines 22 to 25
```yaml
matrix:
variant: [v1, v2]
php-version: ['8.3', '8.1']
php-type: [fpm, cli]
php-base: [alpine, bookworm]
php-version: ['8.5', '8.4', '8.3', '8.2'] # PR fast-path: ['8.5', '8.2']
php-type: [fpm, cli, apache]
php-base: [alpine, bookworm] # v2 uses trixie instead of bookworm
# apache+alpine excluded; v2/trixie added via include
```
Comment on lines +24 to 33

**What it does:**
Expand All @@ -49,9 +50,10 @@
```yaml
matrix:
variant: [v1, v2]
php-version: ['8.3', '8.2', '8.1', '7']
php-version: ['8.5', '8.4', '8.3', '8.2']
php-type: [fpm, cli, apache]
php-base: [alpine, bookworm, bullseye]
php-base: [alpine, bookworm] # v2 uses trixie instead of bookworm
# apache+alpine excluded; v2/trixie added via include
```

**What it does:**
Expand All @@ -68,7 +70,7 @@
To enable publishing, configure these GitHub repository secrets:

| Secret | Description | Used For |
|--------|-------------|----------|

Check failure on line 73 in docs/ci.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Table column style

docs/ci.md:73:35 MD060/table-column-style Table column style [Table pipe is missing space to the left for style "compact"] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md060.md

Check failure on line 73 in docs/ci.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Table column style

docs/ci.md:73:24 MD060/table-column-style Table column style [Table pipe is missing space to the right for style "compact"] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md060.md

Check failure on line 73 in docs/ci.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Table column style

docs/ci.md:73:24 MD060/table-column-style Table column style [Table pipe is missing space to the left for style "compact"] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md060.md

Check failure on line 73 in docs/ci.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Table column style

docs/ci.md:73:10 MD060/table-column-style Table column style [Table pipe is missing space to the right for style "compact"] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md060.md

Check failure on line 73 in docs/ci.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Table column style

docs/ci.md:73:10 MD060/table-column-style Table column style [Table pipe is missing space to the left for style "compact"] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md060.md

Check failure on line 73 in docs/ci.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Table column style

docs/ci.md:73:1 MD060/table-column-style Table column style [Table pipe is missing space to the right for style "compact"] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md060.md
| `DOCKERHUB_USERNAME` | Docker Hub username | Docker Hub login |
| `DOCKERHUB_TOKEN` | Docker Hub access token | Docker Hub authentication |
| `QUAY_USERNAME` | Quay.io username | Quay.io login |
Expand Down Expand Up @@ -176,8 +178,8 @@
**v2:** `{php-version}-{type}-{os}-v2`

Examples:
- `8.3-fpm-alpine` (v1)
- `8.3-fpm-alpine-v2` (v2)
- `8.5-fpm-alpine` (v1)
- `8.5-fpm-alpine-v2` (v2)
- `8.2-cli-bookworm` (v1)
- `8.2-cli-bookworm-v2` (v2)

Expand Down
Loading
Loading