Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
8c6ed6a
this is what the opposite of an atomic commit looks like!
Mar 14, 2025
4bbb038
Update README.md with enhanced features, usage examples, and architec…
Mar 14, 2025
650d798
Refactor architecture diagram formatting in README.md
Mar 14, 2025
0f04e28
Refactor GitHub Actions workflow to use heredoc syntax for dynamic ma…
Mar 14, 2025
b0ea437
Update GitHub Actions to use actions/upload-artifact@v4
Mar 14, 2025
c66eb79
Update Docker image workflow to enhance BuildKit configuration and pl…
Mar 14, 2025
94bdc45
Enhance Docker image workflow by updating artifact naming and adding …
Mar 15, 2025
ac724f1
Update Docker image workflow to configure BuildKit for additional pla…
Mar 15, 2025
bda5b04
Fix Docker image workflow by updating keepBytes and keepDuration to s…
Mar 15, 2025
c37df72
Refactor Docker image workflow to update keepBytes and keepDuration t…
Mar 15, 2025
45084d4
Remove BuildKit configuration for GCP policy in Docker image workflow
Mar 15, 2025
f335b41
Update PHP version matrix in Docker image workflow to reflect support…
Mar 15, 2025
d5c3464
Fix typo in QUAY_TAG variable in Docker image workflow
Mar 15, 2025
1b8da11
Fix QUAY_TAG and cache reference to use lowercased repository owner
Mar 15, 2025
b6c1650
Set lowercase owner name for Docker image caching
Mar 15, 2025
815eba1
Fix matrix.php-version variable to use correct PHP version matrix ref…
Mar 15, 2025
2f5b8a6
Refactor Dockerfile to use multi-stage builds, optimize dependency in…
Mar 15, 2025
ef8316c
Update Dockerfile to use public ECR PHP image for builder and product…
Mar 15, 2025
b4944f5
Add system library installation for Debian and Alpine in Dockerfile
Mar 15, 2025
c1392e4
Fix Dockerfile to correct library name from 'libsnappy' to 'snappy'
Mar 15, 2025
2e296c1
Refactor Dockerfile to update system library installation for Debian …
Mar 15, 2025
9d25b5c
Update Dockerfile to add additional system libraries for Debian and A…
Mar 15, 2025
3519b2b
Fix Dockerfile to correct library names and ensure proper installatio…
Mar 15, 2025
61c736b
Fix Dockerfile to update library name from 'libavif' to 'libavif9' fo…
Mar 15, 2025
f6f47c6
Update Dockerfile and workflows to remove PHP 7 support and adjust ve…
Mar 15, 2025
8691b6a
remove bullseye-specific commands for builder stage
Mar 15, 2025
a4fbf30
Fix typo in QUAY_TAG variable in Docker workflow for the 60th time
Mar 15, 2025
0d9c5e7
Add mcrypt extension to PHP installation in Dockerfile
Mar 16, 2025
d6ac99f
Update Dockerfile and workflow to support PHP 8.4
Mar 16, 2025
401f859
Refactor Docker workflow to remove bullseye support and streamline ta…
Mar 16, 2025
00b5618
Enhance PHP configuration in Dockerfile with additional settings for …
Mar 16, 2025
91bf31a
Remove mcrypt extension from PHP installation in Dockerfile and make …
Mar 16, 2025
150c564
Add pull_request trigger for Docker workflow
Mar 16, 2025
bd64a0c
Add main branch trigger for Docker image workflow
Mar 16, 2025
812debf
Update README.md to include environment variables and troubleshooting…
Mar 25, 2025
eee64ee
Add S6 Overlay for process management and enhance PHP configuration
Mar 26, 2025
686b8d9
Update Docker image workflow to include s6-overlay paths and ignore m…
Mar 26, 2025
1186c89
Refactor Docker image workflow to exclude specific paths from trigger…
Mar 26, 2025
47d2804
Enhance Dockerfile to create necessary directories and set permission…
Mar 26, 2025
32c14ba
Update Dockerfile and S6 scripts for improved compatibility and permi…
Mar 26, 2025
26c53d8
Fix variable name for PHP version in Docker image workflow to ensure …
Mar 26, 2025
761a86c
Fix PHP version variable usage in Docker image workflow for Quay tag …
Mar 26, 2025
637a11e
Fix PHP version variable usage in Quay tag within Docker image workfl…
Mar 26, 2025
9b4f5af
Add Dockerfile.v1: configurable PHP image with OS-specific deps and e…
Oct 19, 2025
4a9c8d3
Add Dockerfile.v2: multi-stage PHP image with OS-specific deps, exten…
Oct 19, 2025
16ebba0
chore: add test-build.sh helper script for building v1/v2 Docker images
Oct 19, 2025
590c849
fix: parse tag and pass build args (VERSION, PHPVERSION, BASEOS) to d…
Oct 19, 2025
eeefb77
fix: enable BuildKit for v2 builds to support cache mounts
Oct 19, 2025
daf0408
Add docker-image.v1 GitHub Actions workflow
Oct 19, 2025
79f081e
Add docker-image.v2 GitHub Actions workflow for multi-arch PHP builds
Oct 19, 2025
75fe76d
feat: add unified CI workflow for v1 and v2 Docker builds
Oct 20, 2025
53600f7
ci: disable automated triggers and PR preview builds in docker-image.…
Oct 20, 2025
2d9a9f7
feat: enhance smoke tests with comprehensive checks and error handling
Oct 20, 2025
76b6aac
docs: comprehensive v1/v2 documentation with migration and troublesho…
Oct 20, 2025
cdd60b1
ci: add scheduled build and publish on Tuesdays at 3AM UTC
Oct 20, 2025
0e93737
fix: add default values to VERSION arg to silence BuildKit linter war…
Oct 20, 2025
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
18 changes: 18 additions & 0 deletions .github/docker-setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# .github/actions/docker-setup/action.yml
name: 'Docker Setup'
description: 'Sets up Docker for multi-platform builds'

runs:
using: "composite"
steps:
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64,arm

- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
network=host
image=moby/buildkit:latest
327 changes: 327 additions & 0 deletions .github/workflows/docker-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
name: Docker CI (v1 + v2)

on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
schedule:
- cron: '0 3 * * 2' # Weekly on Tuesday at 3:00 AM UTC
workflow_dispatch:

concurrency:
group: docker-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
variant: [v1, v2]
php-version: ['8.3', '8.1']
php-type: [fpm, cli]
php-base: [alpine, bookworm]
exclude:
- php-type: apache
php-base: alpine

name: ${{ matrix.variant }}-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64,arm

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Set build variables
id: vars
run: |
VERSION="${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}"
TAG_BASE="php-docker:${VERSION}"

if [ "${{ matrix.variant }}" = "v2" ]; then
TAG="${TAG_BASE}-v2"
DOCKERFILE="Dockerfile.v2"
else
TAG="${TAG_BASE}"
DOCKERFILE="Dockerfile.v1"
fi

echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "TAG=${TAG}" >> $GITHUB_OUTPUT
echo "DOCKERFILE=${DOCKERFILE}" >> $GITHUB_OUTPUT
echo "CACHE_SCOPE=${{ matrix.variant }}-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}" >> $GITHUB_OUTPUT

- name: Build test image
uses: docker/build-push-action@v6
with:
context: .
file: ${{ steps.vars.outputs.DOCKERFILE }}
load: true
platforms: linux/amd64
cache-from: type=gha,scope=${{ steps.vars.outputs.CACHE_SCOPE }}
cache-to: type=gha,mode=max,scope=${{ steps.vars.outputs.CACHE_SCOPE }}
build-args: |
VERSION=${{ steps.vars.outputs.VERSION }}
PHPVERSION=${{ matrix.php-version }}
BASEOS=${{ matrix.php-base }}
tags: test-${{ steps.vars.outputs.TAG }}

- name: Smoke tests - PHP version
run: |
echo "::group::Testing PHP version"
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} php -v | tee php-version.txt; then
echo "::error::Failed to run php -v"
docker logs test-${{ steps.vars.outputs.TAG }} 2>&1 || true
exit 1
fi

if ! grep -q "${{ matrix.php-version }}" php-version.txt; then
echo "::error::PHP version mismatch - expected ${{ matrix.php-version }}"
cat php-version.txt
exit 1
fi
echo "✅ PHP version correct"
echo "::endgroup::"

- name: Smoke tests - Basic PHP CLI run
run: |
echo "::group::Testing basic PHP CLI execution"
SAPI=$(docker run --rm test-${{ steps.vars.outputs.TAG }} php -r "echo PHP_SAPI;" 2>&1)
if [ $? -ne 0 ]; then
echo "::error::Failed to execute PHP CLI test"
echo "$SAPI"
exit 1
fi
echo "✅ PHP CLI runs successfully (SAPI: $SAPI)"
echo "::endgroup::"

- name: Smoke tests - Extensions
run: |
echo "::group::Testing PHP extensions"
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} php -m | tee extensions.txt; then
echo "::error::Failed to list PHP extensions"
docker logs test-${{ steps.vars.outputs.TAG }} 2>&1 || true
exit 1
fi

# Core extensions that should be present
REQUIRED_EXTS="gd json mysqli zip"
MISSING_EXTS=""

for ext in $REQUIRED_EXTS; do
if ! grep -qi "$ext" extensions.txt; then
MISSING_EXTS="$MISSING_EXTS $ext"
echo "::error::Missing extension: $ext"
else
echo "✅ Extension $ext found"
fi
done

if [ -n "$MISSING_EXTS" ]; then
echo "::error::Missing required extensions:$MISSING_EXTS"
echo "Available extensions:"
cat extensions.txt
exit 1
fi
echo "::endgroup::"

- name: Smoke tests - Entrypoint quick-run
run: |
echo "::group::Testing entrypoint/init quick-run"
OUTPUT=$(docker run --rm test-${{ steps.vars.outputs.TAG }} php -r "echo 'entrypoint-ok';" 2>&1)
EXIT_CODE=$?

if [ $EXIT_CODE -ne 0 ]; then
echo "::error::Entrypoint test failed with exit code $EXIT_CODE"
echo "$OUTPUT"
exit 1
fi

if ! echo "$OUTPUT" | grep -q "entrypoint-ok"; then
echo "::error::Entrypoint did not produce expected output"
echo "Output: $OUTPUT"
exit 1
fi
echo "✅ Entrypoint executes successfully"
echo "::endgroup::"

- name: Smoke tests - Directory permissions
run: |
echo "::group::Testing directory permissions"
DIRS_TO_CHECK="/tmp /var/www"

for dir in $DIRS_TO_CHECK; do
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} sh -c "test -d $dir && [ -w $dir ]" 2>&1; then
echo "::warning::Directory $dir either doesn't exist or is not writable"
else
echo "✅ Directory $dir exists and is writable"
fi
done
echo "::endgroup::"

- name: Smoke tests - v2 specific (s6-overlay)
if: matrix.variant == 'v2'
run: |
echo "::group::Testing s6-overlay presence and PID1 behavior"

# Check s6-overlay directory
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} sh -c "test -d /etc/s6-overlay" 2>&1; then
echo "::error::s6-overlay directory not found at /etc/s6-overlay"
docker run --rm test-${{ steps.vars.outputs.TAG }} ls -la /etc/ 2>&1 || true
exit 1
fi
echo "✅ s6-overlay directory exists"

# Check init binary
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} sh -c "test -f /init" 2>&1; then
echo "::error::s6 init binary not found at /init"
docker run --rm test-${{ steps.vars.outputs.TAG }} ls -la / 2>&1 || true
exit 1
fi
echo "✅ s6 init binary exists"

# Check for s6-overlay services directory
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} sh -c "test -d /etc/s6-overlay/s6-rc.d || test -d /etc/services.d" 2>&1; then
echo "::warning::s6 services directory not found (expected /etc/s6-overlay/s6-rc.d or /etc/services.d)"
else
echo "✅ s6 services directory found"
fi

echo "::endgroup::"

- name: Smoke tests - FPM specific
if: matrix.php-type == 'fpm'
run: |
echo "::group::Testing PHP-FPM"
if ! docker run --rm test-${{ steps.vars.outputs.TAG }} php-fpm --version 2>&1 | tee fpm-version.txt; then
echo "::error::Failed to run php-fpm --version"
cat fpm-version.txt || true
exit 1
fi
echo "✅ PHP-FPM version check passed"
echo "::endgroup::"

- name: Summary
run: |
echo "::notice::✅ Build and tests passed for ${{ matrix.variant }} - ${{ steps.vars.outputs.TAG }}"

publish:
needs: build-and-test
if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'schedule')
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
variant: [v1, v2]
php-version: ['8.3', '8.2', '8.1', '7']
php-type: [fpm, cli, apache]
php-base: [alpine, bookworm, bullseye]
exclude:
- php-type: apache
php-base: alpine
- php-version: '7'
php-base: bookworm
- php-version: '8.3'
php-base: bullseye
- php-version: '8.2'
php-base: bullseye
- php-version: '8.1'
php-base: bullseye

name: publish-${{ matrix.variant }}-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64,arm

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Login to Quay.io
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_ROBOT_TOKEN }}

- name: Set publish variables
id: vars
run: |
VERSION="${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}"

if [ "${{ matrix.variant }}" = "v2" ]; then
TAG_SUFFIX="-v2"
DOCKERFILE="Dockerfile.v2"
else
TAG_SUFFIX=""
DOCKERFILE="Dockerfile.v1"
fi

echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "TAG_SUFFIX=${TAG_SUFFIX}" >> $GITHUB_OUTPUT
echo "DOCKERFILE=${DOCKERFILE}" >> $GITHUB_OUTPUT
echo "DOCKERHUB_TAG=docker.io/${{ secrets.DOCKERHUB_USERNAME }}/php-docker:${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT
echo "GHCR_TAG=ghcr.io/kingpin/php-docker:${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT
echo "QUAY_TAG=quay.io/kingpinx1/php-docker:${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT
echo "CACHE_SCOPE=${{ matrix.variant }}-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}" >> $GITHUB_OUTPUT

- name: Build and push multi-arch image
uses: docker/build-push-action@v6
with:
context: .
file: ${{ steps.vars.outputs.DOCKERFILE }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
cache-from: type=gha,scope=${{ steps.vars.outputs.CACHE_SCOPE }}
cache-to: type=gha,mode=max,scope=${{ steps.vars.outputs.CACHE_SCOPE }}
build-args: |
VERSION=${{ steps.vars.outputs.VERSION }}
PHPVERSION=${{ matrix.php-version }}
BASEOS=${{ matrix.php-base }}
tags: |
${{ steps.vars.outputs.DOCKERHUB_TAG }}
${{ steps.vars.outputs.GHCR_TAG }}
${{ steps.vars.outputs.QUAY_TAG }}

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: image
image-ref: ${{ steps.vars.outputs.DOCKERHUB_TAG }}
format: 'sarif'
severity: 'CRITICAL,HIGH'
output: 'trivy-results-${{ matrix.variant }}-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}.sarif'

- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results-${{ matrix.variant }}-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base }}.sarif'
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Docker Image CI

on:
schedule:
- cron: '31 16 * * 3'
workflow_dispatch:
# schedule:
# - cron: '31 16 * * 3'

jobs:
build:
Expand Down Expand Up @@ -117,4 +117,4 @@ jobs:
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base-os }}.sarif'
sarif_file: 'trivy-results-${{ matrix.php-version }}-${{ matrix.php-type }}-${{ matrix.php-base-os }}.sarif'
Loading
Loading