Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
60 changes: 60 additions & 0 deletions .github/workflows/build-php-fpm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Build standalone PHP FPM
on:
workflow_dispatch:
push:
branches: [main]
paths: ['php-fpm/**', '.github/workflows/build-php-fpm.yml']
pull_request:
paths: ['php-fpm/**', '.github/workflows/build-php-fpm.yml']

concurrency:
group: '${{ github.workflow }}-${{ github.ref }}'
cancel-in-progress: true
permissions:
contents: read
packages: write
id-token: write

jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- id: matrix
run: |
matrix=$(docker buildx bake -f php-fpm/docker-bake.hcl --print fpm | jq -c '{include: [.group.fpm.targets[] as $target | {php: (.target[$target].args.PHP_VERSION | split(".")[:2] | join(".")), version: .target[$target].args.PHP_VERSION, suffix: ($target | ltrimstr("fpm-"))}]}')
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
fpm:
needs: matrix
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.matrix.outputs.matrix) }}
uses: docker/github-builder/.github/workflows/bake.yml@v1
with:
files: php-fpm/docker-bake.hcl
target: fpm-${{ matrix.suffix }}
output: image
push: true
cache: true
# Retain compilation stages, not just the final scratch image's COPY layers.
cache-mode: max
cache-scope: php-fpm-${{ matrix.php }}
meta-images: ghcr.io/shopware/docker-php-fpm${{ github.event_name == 'pull_request' && '-ci-test' || '' }}
meta-tags: |
type=raw,value=${{ github.event_name == 'pull_request' && format('{0}-', github.event.number) || '' }}${{ matrix.php }}
type=raw,value=${{ github.event_name == 'pull_request' && format('{0}-', github.event.number) || '' }}${{ matrix.version }}
meta-flavor: latest=false
secrets:
registry-auths: |
- registry: docker.io
username: ${{ toJSON(secrets.DOCKER_HUB_USERNAME) }}
password: ${{ toJSON(secrets.DOCKER_HUB_PASSWORD) }}
- registry: ghcr.io
username: ${{ github.actor }}
password: ${{ toJSON(secrets.GITHUB_TOKEN) }}
build-secrets: |
composer_auth: |
{"github-oauth":{"github.com":"${{ secrets.GITHUB_TOKEN }}"}}
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,57 @@ Both workflows also support manual runs and daily rebuilds.

Run `node scripts/update-php-matrix.mjs` from the repository root to update the
PHP patch versions in the family-specific Bake files.

## Standalone PHP FPM

See [the consumption guide](php-fpm/README.md) for downstream Dockerfiles, image tags,
configuration and optional extensions.

`php-fpm/` compiles PHP and extensions independently of image generations.
Consumers start from Alpine, copy the compiled files, and install runtime APK
packages from the supplied dependency manifest. The published image is a scratch
image used as a copy source. It publishes
`ghcr.io/shopware/docker-php-fpm:<minor>` and `:<patch>` for AMD64 and ARM64.
v1 continues to use its existing bases; adopting this image is a separate change.
The compiled files include upstream FPM configuration and an entrypoint script.
Consumers configure their own users, environment, entrypoint and command.

The PHP build recipe and `docker-php-*` helpers are maintained locally in
`php-fpm/`, adapted from [docker-library/php](https://github.com/docker-library/php/tree/5ec2a6a0dad498e89a91a39454dbb52e98ce2bdb/8.6-rc/alpine3.24/fpm).
The original license is included as `php-fpm/LICENSE.docker-library-php`.
Builds download PHP releases directly from php.net and verify both their SHA-256
checksums and release signatures; they do not fetch Dockerfiles or scripts from
upstream. The recipe retains NTS and the build options needed by PHP 8.2–8.5.

Update each release's `version`, `sha256` and `gpgKeys` in
`php-fpm/docker-bake.hcl` when PHP changes. `alpineVersion` selects the base OS.
The existing v1 matrix updater does not change these source build inputs.

The image includes the normal FPM extensions plus gRPC, OpenTelemetry, Xdebug,
Tideways, Blackfire and SPX. Telemetry and profilers are installed but disabled.
Downstream images can enable an optional extension by renaming its `.disabled`
file in `/usr/local/etc/php/conf.d/` to `.ini`.

The standalone image builds when its PHP source inputs or extension recipe change,
with manual builds available through the workflow. Depending images can rebuild
daily from Alpine, installing current runtime packages and reusing the published
PHP binaries and extensions.

Build from the repository root:

```sh
phpMinor=8.4 docker buildx bake -f php-fpm/docker-bake.hcl \
--set '*.platform=linux/arm64' \
--set 'fpm-8-4.tags=shopware-php-fpm-local:fpm-8-4' --load fpm
```

Choose `linux/amd64` or `linux/arm64` for your local architecture. Omit
`phpMinor` to build the full matrix. Add `--print` to inspect the build plan.
Use `--push` to publish both architectures after registry login, without the
local platform and tag overrides. CI publishes PR images to
`ghcr.io/shopware/docker-php-fpm-ci-test:<pr>-<php-version>`.

An optional `COMPOSER_AUTH` environment variable can be passed to PIE with
`--set '*.secrets=id=composer_auth,env=COMPOSER_AUTH'`. Extension and installer
downloads are resolved when PHP is built; changes to the base recipe can be used
to update extensions between PHP releases.
Loading
Loading