Skip to content
Merged
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
156 changes: 129 additions & 27 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,153 @@ on:
paths:
- "alpine/**"
- "debian/**"
- "images.json"
workflow_dispatch:

env:
IMAGE_NAME: loeffelhardt/php

jobs:
build:
# Single source of truth: images.json. Derive two matrices from it:
# - build_matrix: one entry per (image, platform), with the native
# runner to use for that platform (no QEMU).
# - merge_matrix: one entry per image, with its final tags, used to
# assemble the multi-arch manifest after the platform builds.
prepare:
runs-on: ubuntu-latest
outputs:
build_matrix: ${{ steps.matrices.outputs.build_matrix }}
merge_matrix: ${{ steps.matrices.outputs.merge_matrix }}
steps:
- uses: actions/checkout@v7

- name: Derive matrices from images.json
id: matrices
run: |
build_matrix=$(jq -c '{
include: [
.[] as $img
| $img.platforms[] as $p
| {
id: ($img.id | gsub("/"; "-")),
image: $img.dockerfile,
platform: $p,
runner: (
if $p == "linux/amd64" then "ubuntu-24.04"
elif $p == "linux/arm64" then "ubuntu-24.04-arm"
else "ubuntu-latest"
end
)
}
]
}' images.json)

merge_matrix=$(jq -c '{
include: [
.[] | { id: (.id | gsub("/"; "-")), tags: .tags }
]
}' images.json)

echo "build_matrix=${build_matrix}" >> "$GITHUB_OUTPUT"
echo "merge_matrix=${merge_matrix}" >> "$GITHUB_OUTPUT"

# Build each image natively on amd64 and arm64 runners (no QEMU emulation,
# full native compile speed). On `main` each variant is pushed by digest
# (untagged); the `merge` job later assembles the multi-arch manifests.
build:
needs: prepare
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
## Alpine
### Alpine 3.22
# - image: "alpine/3.22/8.4/Dockerfile"
# tags: [ "loeffelhardt/php:8.4-alpine3.22" ]
# platforms: [ "linux/amd64", "linux/arm64" ]

### Alpine 3.23
- image: "alpine/3.23/8.4/Dockerfile"
# tags: [ "loeffelhardt/php:latest", "loeffelhardt/php:8.4", "loeffelhardt/php:8.4-alpine3.23" ]
tags: [ "loeffelhardt/php:8.4-alpine3.23" ]
platforms: [ "linux/amd64", "linux/arm64" ]

## Debian
### Debian bullseye
# - image: 'debian/bullseye/8.4/Dockerfile'
# tags: [ 'loeffelhardt/php:8.4-debian' ]
# platforms: [ "linux/amd64", "linux/arm64" ]
matrix: ${{ fromJson(needs.prepare.outputs.build_matrix) }}

steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- uses: actions/checkout@v7

- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> "$GITHUB_ENV"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Login to DockerHub
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push
id: docker_build
# On main: push the single-platform image by digest (no tags yet).
- name: Build and push by digest
if: github.ref == 'refs/heads/main'
id: build_push
uses: docker/build-push-action@v7
with:
push: ${{ github.ref == 'refs/heads/main' }}
file: ${{ matrix.image }}
tags: ${{ join(matrix.tags) }}
platforms: ${{ join(matrix.platforms) }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true

# On other branches/PRs: just build natively to validate, no push.
- name: Build (validate only)
if: github.ref != 'refs/heads/main'
uses: docker/build-push-action@v7
with:
file: ${{ matrix.image }}
platforms: ${{ matrix.platform }}
push: false

- name: Export digest
if: github.ref == 'refs/heads/main'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build_push.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"

- name: Upload digest
if: github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v7
with:
name: digests-${{ matrix.id }}-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

# Assemble the final multi-arch manifest lists from the per-platform
# digests pushed above, tagging each image as defined in images.json.
merge:
if: github.ref == 'refs/heads/main'
needs: [ prepare, build ]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.prepare.outputs.merge_matrix) }}

steps:
- name: Download digests
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-${{ matrix.id }}-*
merge-multiple: true

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Login to DockerHub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
$(printf -- '-t %s ' ${{ join(matrix.tags, ' ') }}) \
$(printf '${{ env.IMAGE_NAME }}@sha256:%s ' *)

- name: Inspect image
run: |
docker buildx imagetools inspect ${{ matrix.tags[0] }}
29 changes: 29 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
SHELL := /usr/bin/env bash
SCRIPT := scripts/build-images.sh

.PHONY: help list login build push build-push clean

help: ## Show this help
@echo "Usage: make <target> [IMAGE=<id>]"
@echo
@echo "IMAGE is an optional filter matched against the 'id' field in images.json"
@echo "(e.g. IMAGE=alpine/3.24/8.5, IMAGE=alpine, IMAGE=debian). Omit for all images."
@echo
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {printf " %-12s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

list: ## List all images/tags defined in images.json
@$(SCRIPT) list

login: ## Log in to Docker Hub (prompts for username/password or token)
@$(SCRIPT) login

build: ## Build images and warm the local buildx cache (no push). Use IMAGE=<id> to filter.
@$(SCRIPT) build "$(IMAGE)"

push: ## (Re)build from cache and push images to Docker Hub. Use IMAGE=<id> to filter.
@$(SCRIPT) push "$(IMAGE)"

build-push: build push ## Run build then push in sequence.

clean: ## Remove the local buildx builder and cache
@$(SCRIPT) clean
63 changes: 12 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
Extends official Spryker PHP Docker images with extensions and tools to be able to run LΓΆffelhardt.

* Based on official PHP images
* `Alpine 3.22`
* `Alpine 3.23`
* `Alpine 3.24`
* `Debian "bookworm"`
* `Debian "bullseye"`

* Users: `root`, `spryker`
Expand All @@ -25,56 +26,16 @@ Extends official Spryker PHP Docker images with extensions and tools to be able

| Tag | PHP version | Linux distribution | Details | Dockerfile |
|:------------------------------------------------------------------------------------------------------|:------------|:-------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------|
| [loeffelhardt/php:latest](https://hub.docker.com/r/loeffelhardt/php/tags?name=latest) | 8.4.21 | Alpine 3.23 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:latest.svg)](https://microbadger.com/images/loeffelhardt/php:latest "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.23/8.4/Dockerfile) |
| [loeffelhardt/php:8.4](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4) | 8.4.21 | Alpine 3.23 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4.svg)](https://microbadger.com/images/loeffelhardt/php:8.4 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.23/8.4/Dockerfile) |
| [loeffelhardt/php:8.4-alpine3.23](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4-alpine3.23) | 8.4.21 | Alpine 3.23 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4-alpine3.23.svg)](https://microbadger.com/images/loeffelhardt/php:8.4-alpine3.23 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.23/8.4/Dockerfile) |
| [loeffelhardt/php:8.4-alpine3.22](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4-alpine3.22) | 8.4.21 | Alpine 3.22 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4-alpine3.22.svg)](https://microbadger.com/images/loeffelhardt/php:8.4-alpine3.22 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.22/8.4/Dockerfile) |
| [loeffelhardt/php:latest](https://hub.docker.com/r/loeffelhardt/php/tags?name=latest) | 8.5.9 | Alpine 3.24 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.5-alpine3.24.svg)](https://microbadger.com/images/loeffelhardt/php:8.5-alpine3.24 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.24/8.5/Dockerfile) |
| [loeffelhardt/php:8.5](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.5) | 8.5.9 | Alpine 3.24 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.5-alpine3.24.svg)](https://microbadger.com/images/loeffelhardt/php:8.5-alpine3.24 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.24/8.5/Dockerfile) |
| [loeffelhardt/php:8.5-alpine3.24](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.5-alpine3.24) | 8.5.9 | Alpine 3.24 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.5-alpine3.24.svg)](https://microbadger.com/images/loeffelhardt/php:8.5-alpine3.24 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.24/8.5/Dockerfile) |
| [loeffelhardt/php:8.4](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4) | 8.4.24 | Alpine 3.24 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4-alpine3.24.svg)](https://microbadger.com/images/loeffelhardt/php:8.4-alpine3.24 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.24/8.4/Dockerfile) |
| [loeffelhardt/php:8.4-alpine3.24](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4-alpine3.24) | 8.4.24 | Alpine 3.24 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4-alpine3.24.svg)](https://microbadger.com/images/loeffelhardt/php:8.4-alpine3.24 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.24/8.4/Dockerfile) |
| [loeffelhardt/php:8.4-alpine3.23](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4-alpine3.23) | 8.4.24 | Alpine 3.23 | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4-alpine3.23.svg)](https://microbadger.com/images/loeffelhardt/php:8.4-alpine3.23 "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/alpine/3.23/8.4/Dockerfile) |
| [loeffelhardt/php:8.5-debian](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.5-debian) | 8.5.9 | Debian "bookworm" | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.5-debian.svg)](https://microbadger.com/images/loeffelhardt/php:8.5-debian "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/debian/bookworm/8.5/Dockerfile) |
| [loeffelhardt/php:8.4-debian](https://hub.docker.com/r/loeffelhardt/php/tags?name=8.4-debian) | 8.4.11 | Debian "bullseye" | [![](https://images.microbadger.com/badges/image/loeffelhardt/php:8.4-debian.svg)](https://microbadger.com/images/loeffelhardt/php:8.4-debian "Get your own image badge on microbadger.com") | [:link:](https://github.com/loeffelhardt/el-docker-php/blob/master/debian/bullseye/8.4/Dockerfile) |
## How to use

### Pull image
```bash
$ docker pull loeffelhardt/php
$ docker pull loeffelhardt/php:8.4
```

### Run container
```bash
$ docker run -i --rm loeffelhardt/php:latest php -v
```

### Dockerfile
```dockerfile
FROM loeffelhardt/php:8.4
```

### docker-compose.yml
```yaml
service1:
image: loeffelhardt/php:8.3-debian
```

### Enable NewRelic
```dockerfile
FROM loeffelhardt/php:8.4

RUN mv /usr/local/etc/php/disabled/newrelic.ini /usr/local/etc/php/conf.d/90-newrelic.ini
```

### Enable Blackfire
```dockerfile
FROM loeffelhardt/php:8.4

RUN mv /usr/local/etc/php/disabled/blackfire.ini /usr/local/etc/php/conf.d/90-blackfire.ini
```

### Enable Tideways
```dockerfile
FROM loeffelhardt/php:8.4

RUN mv /usr/local/etc/php/disabled/tideways.ini /usr/local/etc/php/conf.d/90-tideways.ini
```

## PHP extensions

```
Expand Down Expand Up @@ -161,10 +122,10 @@ Disabled extensions
[ ] blackfire 1.87.1~linux-musl-x64-non_zts82
[ ] excimer 1.2.5
[ ] imagick 3.8.1
[ ] newrelic 12.8.0.37
[ ] newrelic 12.9.0.38
[ ] otel
[ ] pcov 1.0.12
[ ] tideways 5.32.0-d1af5cc
[ ] tideways 5.42.0
[ ] xhprof 2.3.10

INSTALLED PACKAGES, CHANNEL PECL.PHP.NET:
Expand All @@ -181,7 +142,7 @@ xhprof 2.3.10 stable

Composer
====================
Composer version 2.9.8 2025-12-30 13:40:17
Composer version 2.10.2
```
##### Run the following to get the report
```bash
Expand Down
6 changes: 3 additions & 3 deletions alpine/3.21/8.2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ARG SPRYKER_PHP_VERSION=8.2.29
FROM php:${SPRYKER_PHP_VERSION}-fpm-alpine3.21

ARG TARGETPLATFORM
ARG COMPOSER_VERSION=2.9.8
ARG COMPOSER_VERSION=2.10.2
ARG BLACKFIRE_VERSION=1.87.1
ARG BLACKFIRE_PHP_VERSION=82
ARG NEWRELIC_VERSION=12.8.0.37
ARG TIDEWAYS_VERSION=5.32.0
ARG NEWRELIC_VERSION=12.9.0.38
ARG TIDEWAYS_VERSION=5.42.0
ARG TIDEWAYS_PHP_VERSION=8.2

ENV srcRoot /data
Expand Down
6 changes: 3 additions & 3 deletions alpine/3.21/8.3/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ARG SPRYKER_PHP_VERSION=8.3.28
FROM php:${SPRYKER_PHP_VERSION}-fpm-alpine3.21

ARG TARGETPLATFORM
ARG COMPOSER_VERSION=2.9.8
ARG COMPOSER_VERSION=2.10.2
ARG BLACKFIRE_VERSION=1.92.48
ARG BLACKFIRE_PHP_VERSION=83
ARG NEWRELIC_VERSION=12.8.0.37
ARG TIDEWAYS_VERSION=5.32.0
ARG NEWRELIC_VERSION=12.9.0.38
ARG TIDEWAYS_VERSION=5.42.0
ARG TIDEWAYS_PHP_VERSION=8.3

ENV srcRoot /data
Expand Down
6 changes: 3 additions & 3 deletions alpine/3.21/8.4/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ARG SPRYKER_PHP_VERSION=8.4.15
FROM php:${SPRYKER_PHP_VERSION}-fpm-alpine3.21

ARG TARGETPLATFORM
ARG COMPOSER_VERSION=2.9.8
ARG COMPOSER_VERSION=2.10.2
ARG BLACKFIRE_VERSION=1.92.48
ARG BLACKFIRE_PHP_VERSION=84
ARG NEWRELIC_VERSION=12.8.0.37
ARG TIDEWAYS_VERSION=5.32.0
ARG NEWRELIC_VERSION=12.9.0.38
ARG TIDEWAYS_VERSION=5.42.0
ARG TIDEWAYS_PHP_VERSION=8.4

ENV srcRoot /data
Expand Down
6 changes: 3 additions & 3 deletions alpine/3.22/8.2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ARG SPRYKER_PHP_VERSION=8.2.31
FROM php:${SPRYKER_PHP_VERSION}-fpm-alpine3.22

ARG TARGETPLATFORM
ARG COMPOSER_VERSION=2.9.8
ARG COMPOSER_VERSION=2.10.2
ARG BLACKFIRE_VERSION=1.87.1
ARG BLACKFIRE_PHP_VERSION=82
ARG NEWRELIC_VERSION=12.8.0.37
ARG TIDEWAYS_VERSION=5.32.0
ARG NEWRELIC_VERSION=12.9.0.38
ARG TIDEWAYS_VERSION=5.42.0
ARG TIDEWAYS_PHP_VERSION=8.2

ENV srcRoot /data
Expand Down
6 changes: 3 additions & 3 deletions alpine/3.22/8.3/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ARG SPRYKER_PHP_VERSION=8.3.31
FROM php:${SPRYKER_PHP_VERSION}-fpm-alpine3.22

ARG TARGETPLATFORM
ARG COMPOSER_VERSION=2.9.8
ARG COMPOSER_VERSION=2.10.2
ARG BLACKFIRE_VERSION=1.92.48
ARG BLACKFIRE_PHP_VERSION=83
ARG NEWRELIC_VERSION=12.8.0.37
ARG TIDEWAYS_VERSION=5.32.0
ARG NEWRELIC_VERSION=12.9.0.38
ARG TIDEWAYS_VERSION=5.42.0
ARG TIDEWAYS_PHP_VERSION=8.3

ENV srcRoot /data
Expand Down
Loading