deprecate: remove PHP 7.x, 8.0 and 8.1 from active builds and update docs #11
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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.2'] | |
| 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'] | |
| php-type: [fpm, cli, apache] | |
| php-base: [alpine, bookworm] | |
| exclude: | |
| - php-type: apache | |
| php-base: alpine | |
| 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' |