php-fpm-updated #97
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: Build and Push PHP-FPM+Nginx Multi-Service Images | |
| # IMPORTANT: This workflow depends on php-fpm tier images being available. | |
| # Do NOT add push triggers for php-fpm-nginx/** paths - this would cause race conditions | |
| # where php-fpm-nginx tries to build before php-fpm images are pushed. | |
| # Instead, use repository_dispatch from php-fpm workflow or workflow_dispatch. | |
| on: | |
| # NO push trigger - php-fpm-nginx depends on php-fpm images being built first | |
| # Use repository_dispatch from php-fpm workflow instead | |
| workflow_dispatch: | |
| inputs: | |
| php_version: | |
| description: 'PHP Version to build (8.2, 8.3, 8.4, or all)' | |
| required: false | |
| default: 'all' | |
| os_variant: | |
| description: 'OS variant to build (bookworm or all)' | |
| required: false | |
| default: 'all' | |
| repository_dispatch: | |
| types: [php-fpm-updated] | |
| workflow_run: | |
| workflows: ["Build and Push PHP-FPM Images"] | |
| types: [completed] | |
| branches: [main] | |
| schedule: | |
| # Weekly security rebuild - Monday 04:00 UTC (fallback; workflow_run trigger fires on completion) | |
| - cron: '0 4 * * 1' | |
| jobs: | |
| # ===================================================================== | |
| # SLIM TIER - Minimal PHP + essential extensions | |
| # ===================================================================== | |
| build-slim-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: slim | |
| target: slim-root | |
| tag-suffix: slim | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-cosign: true | |
| base-image-type: fpm | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-slim -p 8080:80 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-slim 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-slim | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec test-slim curl -sf http://127.0.0.1/health || { docker logs test-slim && exit 1; } | |
| docker exec test-slim php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-slim cbox-init --version || exit 1 | |
| docker exec test-slim composer --version || exit 1 | |
| # Slim tier should NOT have imagick or node | |
| ! docker exec test-slim php -m | grep -q imagick || echo "Warning: imagick found in slim tier" | |
| ! docker exec test-slim node --version 2>/dev/null || echo "Warning: node found in slim tier" | |
| docker stop test-slim && docker rm test-slim | |
| secrets: inherit | |
| build-slim-rootless-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: slim | |
| target: slim-rootless | |
| rootless: true | |
| tag-suffix: slim-rootless | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-cosign: true | |
| base-image-type: fpm | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-slim-rootless -p 8082:8080 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-slim-rootless 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-slim-rootless | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec test-slim-rootless id -u | grep -E "^(33|82)$" | |
| docker exec test-slim-rootless curl -sf http://127.0.0.1:8080/health || { docker logs test-slim-rootless && exit 1; } | |
| docker exec test-slim-rootless php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker stop test-slim-rootless && docker rm test-slim-rootless | |
| secrets: inherit | |
| # ===================================================================== | |
| # STANDARD TIER (DEFAULT) - + ImageMagick, vips, Node.js | |
| # ===================================================================== | |
| build-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: standard | |
| target: root | |
| tag-suffix: '' | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-convenience-tags: true | |
| enable-cosign: true | |
| enable-trivy: true | |
| base-image-type: fpm | |
| build-args: | | |
| BUILD_DATE=${{ github.event.repository.updated_at }} | |
| VCS_REF=${{ github.sha }} | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-multi -p 8080:80 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-multi 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-multi | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| echo "=== Container logs ===" && docker logs test-multi || true | |
| echo "=== Container status ===" && docker ps -a --filter name=test-multi || true | |
| docker exec test-multi curl -sf http://127.0.0.1/health || { echo "=== Health check failed, container logs ===" && docker logs test-multi && exit 1; } | |
| docker exec test-multi php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-multi cbox-init --version || exit 1 | |
| docker exec test-multi composer --version || exit 1 | |
| docker exec test-multi node --version || exit 1 | |
| docker stop test-multi && docker rm test-multi | |
| secrets: inherit | |
| build-rootless-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: standard | |
| target: rootless | |
| rootless: true | |
| tag-suffix: rootless | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-convenience-tags: true | |
| enable-cosign: true | |
| enable-trivy: true | |
| base-image-type: fpm | |
| build-args: | | |
| BUILD_DATE=${{ github.event.repository.updated_at }} | |
| VCS_REF=${{ github.sha }} | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-rootless -p 8082:8080 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-rootless 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-rootless | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| echo "=== Container logs ===" && docker logs test-rootless || true | |
| echo "=== Container status ===" && docker ps -a --filter name=test-rootless || true | |
| docker exec test-rootless id -u | grep -E "^(33|82)$" | |
| docker exec test-rootless curl -sf http://127.0.0.1:8080/health || { echo "=== Health check failed, container logs ===" && docker logs test-rootless && exit 1; } | |
| docker exec test-rootless php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-rootless cbox-init --version || exit 1 | |
| docker exec test-rootless composer --version || exit 1 | |
| docker exec test-rootless node --version || exit 1 | |
| docker stop test-rootless && docker rm test-rootless | |
| secrets: inherit | |
| # ===================================================================== | |
| # CHROMIUM TIER - + Chromium for Browsershot/Dusk/Puppeteer | |
| # ===================================================================== | |
| build-chromium-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: chromium | |
| target: chromium-root | |
| tag-suffix: chromium | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-cosign: true | |
| enable-trivy: true | |
| base-image-type: fpm | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-chromium -p 8080:80 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-chromium 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-chromium | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec test-chromium curl -sf http://127.0.0.1/health || { docker logs test-chromium && exit 1; } | |
| docker exec test-chromium php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-chromium cbox-init --version || exit 1 | |
| docker exec test-chromium composer --version || exit 1 | |
| docker exec test-chromium node --version || exit 1 | |
| # Chromium tier should have chromium | |
| docker exec test-chromium which chromium-browser || docker exec test-chromium which chromium | |
| docker stop test-chromium && docker rm test-chromium | |
| secrets: inherit | |
| build-chromium-rootless-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: chromium | |
| target: chromium-rootless | |
| rootless: true | |
| tag-suffix: chromium-rootless | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-cosign: true | |
| enable-trivy: true | |
| base-image-type: fpm | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-chromium-rootless -p 8082:8080 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-chromium-rootless 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-chromium-rootless | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec test-chromium-rootless id -u | grep -E "^(33|82)$" | |
| docker exec test-chromium-rootless curl -sf http://127.0.0.1:8080/health || { docker logs test-chromium-rootless && exit 1; } | |
| docker exec test-chromium-rootless php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-chromium-rootless cbox-init --version || exit 1 | |
| docker exec test-chromium-rootless composer --version || exit 1 | |
| docker exec test-chromium-rootless node --version || exit 1 | |
| # Chromium check | |
| docker exec test-chromium-rootless which chromium-browser || docker exec test-chromium-rootless which chromium | |
| docker stop test-chromium-rootless && docker rm test-chromium-rootless | |
| secrets: inherit | |
| # ===================================================================== | |
| # DEV TIER - Standard + Xdebug, PCOV, SPX for development/testing | |
| # ===================================================================== | |
| build-dev-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: dev | |
| target: dev-root | |
| tag-suffix: dev | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-cosign: true | |
| enable-trivy: true | |
| base-image-type: fpm | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-dev -p 8080:80 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-dev 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-dev | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec test-dev curl -sf http://127.0.0.1/health || { docker logs test-dev && exit 1; } | |
| docker exec test-dev php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-dev php -m | grep -E "xdebug|pcov|spx" || exit 1 | |
| docker exec test-dev cbox-init --version || exit 1 | |
| docker exec test-dev composer --version || exit 1 | |
| docker exec test-dev node --version || exit 1 | |
| # Dev tier should have chromium | |
| docker exec test-dev which chromium-browser || docker exec test-dev which chromium | |
| docker stop test-dev && docker rm test-dev | |
| secrets: inherit | |
| build-dev-rootless-matrix: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| os_variant: ['bookworm'] | |
| uses: ./.github/workflows/_build-image.yml | |
| with: | |
| image-name: php-fpm-nginx | |
| image-type: php-fpm-nginx | |
| php-version: ${{ matrix.php_version }} | |
| os-variant: ${{ matrix.os_variant }} | |
| tier: dev | |
| target: dev-rootless | |
| rootless: true | |
| tag-suffix: dev-rootless | |
| cache-scope-prefix: php-fpm-nginx | |
| enable-patch-tags: true | |
| enable-latest-tag: true | |
| enable-cosign: true | |
| enable-trivy: true | |
| base-image-type: fpm | |
| test-script: | | |
| docker pull $IMAGE | |
| docker run -d --name test-dev-rootless -p 8082:8080 $IMAGE | |
| echo "Waiting for container to become healthy..." | |
| for i in {1..60}; do | |
| STATUS=$(docker inspect --format='{{.State.Health.Status}}' test-dev-rootless 2>/dev/null || echo "unknown") | |
| if [ "$STATUS" = "healthy" ]; then | |
| echo "Container is healthy after ${i}s" | |
| break | |
| elif [ "$STATUS" = "unhealthy" ]; then | |
| echo "Container became unhealthy after ${i}s" | |
| docker logs test-dev-rootless | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec test-dev-rootless id -u | grep -E "^(33|82)$" | |
| docker exec test-dev-rootless curl -sf http://127.0.0.1:8080/health || { docker logs test-dev-rootless && exit 1; } | |
| docker exec test-dev-rootless php -v | grep "PHP $PHP_VERSION" || exit 1 | |
| docker exec test-dev-rootless php -m | grep -E "xdebug|pcov|spx" || exit 1 | |
| docker exec test-dev-rootless cbox-init --version || exit 1 | |
| docker exec test-dev-rootless composer --version || exit 1 | |
| docker exec test-dev-rootless node --version || exit 1 | |
| # Chromium check | |
| docker exec test-dev-rootless which chromium-browser || docker exec test-dev-rootless which chromium | |
| docker stop test-dev-rootless && docker rm test-dev-rootless | |
| secrets: inherit | |
| # ===================================================================== | |
| # Post-build notifications | |
| # ===================================================================== | |
| notify-security-updates: | |
| needs: [build-slim-matrix, build-slim-rootless-matrix, build-matrix, build-rootless-matrix, build-chromium-matrix, build-chromium-rootless-matrix, build-dev-matrix, build-dev-rootless-matrix] | |
| runs-on: ubuntu-24.04 | |
| if: github.event_name == 'schedule' | |
| steps: | |
| - name: Notify about weekly security rebuild | |
| run: | | |
| echo "Weekly security rebuild completed" | |
| echo "All images rebuilt with latest security patches" | |
| echo "PHP versions: 8.2, 8.3, 8.4" | |
| echo "OS variants: Debian Bookworm" | |
| echo "Rootless variants: Available for all OS variants" | |
| echo "Image tiers: slim, standard, chromium, dev" |