From 229b8ad361f1cf38f073db373fd584475971bc76 Mon Sep 17 00:00:00 2001 From: Sylvester Damgaard Date: Thu, 7 May 2026 10:31:47 +0200 Subject: [PATCH 1/3] fix(php-fpm-nginx): forward nginx access/error logs to stdout/stderr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The php-fpm-nginx image installs nginx with Debian's stock /etc/nginx/nginx.conf, which writes: access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log warn; In a container these are regular files inside the overlay fs and never reach `docker logs` / `kubectl logs`. The standalone nginx image already symlinks them to /dev/stdout and /dev/stderr — this brings php-fpm-nginx in line with the same convention. Symptom: an operator running id (Cbox · ID, a Laravel app) on this baseimage saw cbox-init's own startup messages in `kubectl logs` but nothing from nginx (no access lines, no warnings, no upstream errors) and only fragments from PHP-FPM. Symlinking at build time means the existing config keeps writing to /var/log/nginx/access.log + error.log, but those paths now resolve to the container's stdout/stderr. Applied to all 8 stages (slim/standard/chromium/dev × root/rootless). --- php-fpm-nginx/Dockerfile | 60 +++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/php-fpm-nginx/Dockerfile b/php-fpm-nginx/Dockerfile index 31eaa94..3950bd7 100644 --- a/php-fpm-nginx/Dockerfile +++ b/php-fpm-nginx/Dockerfile @@ -45,9 +45,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories +# Create nginx directories + forward access/error logs to docker log +# collector (stdout/stderr) so kubectl logs / docker logs sees them. RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Also remove the default site that conflicts with our configuration @@ -105,10 +108,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories with www-data ownership +# Create nginx directories with www-data ownership + forward access/error +# logs to docker log collector (stdout/stderr) so kubectl logs / docker +# logs sees them. # Note: Debian nginx uses /var/lib/nginx for tmp dirs (body, proxy, fastcgi, etc.) RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx /var/lib/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Remove default site that conflicts with our configuration @@ -169,9 +176,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories +# Create nginx directories + forward access/error logs to docker log +# collector (stdout/stderr) so kubectl logs / docker logs sees them. RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Also remove the default site that conflicts with our configuration @@ -229,10 +239,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories with www-data ownership +# Create nginx directories with www-data ownership + forward access/error +# logs to docker log collector (stdout/stderr) so kubectl logs / docker +# logs sees them. # Note: Debian nginx uses /var/lib/nginx for tmp dirs (body, proxy, fastcgi, etc.) RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx /var/lib/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Remove default site that conflicts with our configuration @@ -293,9 +307,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories +# Create nginx directories + forward access/error logs to docker log +# collector (stdout/stderr) so kubectl logs / docker logs sees them. RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Also remove the default site that conflicts with our configuration @@ -353,10 +370,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories with www-data ownership +# Create nginx directories with www-data ownership + forward access/error +# logs to docker log collector (stdout/stderr) so kubectl logs / docker +# logs sees them. # Note: Debian nginx uses /var/lib/nginx for tmp dirs (body, proxy, fastcgi, etc.) RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx /var/lib/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Remove default site that conflicts with our configuration @@ -417,9 +438,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories +# Create nginx directories + forward access/error logs to docker log +# collector (stdout/stderr) so kubectl logs / docker logs sees them. RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Also remove the default site that conflicts with our configuration @@ -477,10 +501,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx gettext-base \ && rm -rf /var/lib/apt/lists/* -# Create nginx directories with www-data ownership +# Create nginx directories with www-data ownership + forward access/error +# logs to docker log collector (stdout/stderr) so kubectl logs / docker +# logs sees them. # Note: Debian nginx uses /var/lib/nginx for tmp dirs (body, proxy, fastcgi, etc.) RUN mkdir -p /etc/nginx/conf.d /var/log/nginx /run/nginx /var/lib/nginx && \ - chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx + chown -R www-data:www-data /var/log/nginx /run/nginx /etc/nginx /var/lib/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log # Debian nginx uses www-data by default, but let's ensure it # Remove default site that conflicts with our configuration From 2330b715e02f78f507c3cb454b07aecab616b973 Mon Sep 17 00:00:00 2001 From: Sylvester Damgaard Date: Thu, 7 May 2026 11:12:25 +0200 Subject: [PATCH 2/3] ci: migrate all workflows from self-hosted runners to GitHub-hosted Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/_build-image.yml | 16 ++++++---------- .github/workflows/build-nginx.yml | 2 +- .github/workflows/build-php-base.yml | 2 +- .github/workflows/build-php-fpm-nginx.yml | 2 +- .github/workflows/build-php-fpm.yml | 2 +- .github/workflows/check-updates.yml | 2 +- .github/workflows/e2e-tests.yml | 4 ++-- .github/workflows/integration-tests.yml | 6 +++--- 8 files changed, 16 insertions(+), 20 deletions(-) diff --git a/.github/workflows/_build-image.yml b/.github/workflows/_build-image.yml index 6292de5..2ab2abd 100644 --- a/.github/workflows/_build-image.yml +++ b/.github/workflows/_build-image.yml @@ -105,28 +105,24 @@ on: # ═══════════════════════════════════════════════════════════════════════════════ # Architecture: Split into parallel builds + manifest merge # -# build-amd64 (self-hosted ax41, native) ──┐ +# build-amd64 (GitHub-hosted ubuntu-24.04, native) ──┐ # ├── merge (GitHub-hosted, manifest + sign) # build-arm64 (GitHub-hosted ARM runner, native) ──┘ # -# AMD64 builds natively on self-hosted Hetzner AX41. ARM64 builds natively on +# AMD64 builds natively on GitHub-hosted ubuntu-24.04. ARM64 builds natively on # GitHub-hosted ARM runners (ubuntu-24.04-arm). Both push by digest; the merge -# job runs on GitHub-hosted ubuntu-24.04 to avoid token expiry and resource -# contention on the self-hosted runner. For PRs, builds run but skip push; -# merge is skipped. +# job creates a multi-arch manifest, signs, and scans. For PRs, builds run but +# skip push; merge is skipped. # ═══════════════════════════════════════════════════════════════════════════════ jobs: # ───────────────────────────────────────────────────────────────────────────── - # AMD64 build (native on self-hosted Hetzner AX41) + # AMD64 build (native on GitHub-hosted runner) # ───────────────────────────────────────────────────────────────────────────── build-amd64: if: contains(inputs.platforms, 'linux/amd64') - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 timeout-minutes: ${{ inputs.timeout }} - concurrency: - group: amd64-build-${{ inputs.php-version }} - cancel-in-progress: false permissions: contents: read diff --git a/.github/workflows/build-nginx.yml b/.github/workflows/build-nginx.yml index 9885f16..9901cf3 100644 --- a/.github/workflows/build-nginx.yml +++ b/.github/workflows/build-nginx.yml @@ -20,7 +20,7 @@ env: jobs: build-matrix: - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/build-php-base.yml b/.github/workflows/build-php-base.yml index 52cb2b8..44c1b80 100644 --- a/.github/workflows/build-php-base.yml +++ b/.github/workflows/build-php-base.yml @@ -275,7 +275,7 @@ jobs: trigger-dependent-builds: 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] if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 permissions: contents: write steps: diff --git a/.github/workflows/build-php-fpm-nginx.yml b/.github/workflows/build-php-fpm-nginx.yml index 200cb02..64d5c8b 100644 --- a/.github/workflows/build-php-fpm-nginx.yml +++ b/.github/workflows/build-php-fpm-nginx.yml @@ -456,7 +456,7 @@ jobs: # ===================================================================== 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: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 if: github.event_name == 'schedule' steps: diff --git a/.github/workflows/build-php-fpm.yml b/.github/workflows/build-php-fpm.yml index f0a1b9f..5fc2a18 100644 --- a/.github/workflows/build-php-fpm.yml +++ b/.github/workflows/build-php-fpm.yml @@ -300,7 +300,7 @@ jobs: trigger-dependent-builds: 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] if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 permissions: contents: write steps: diff --git a/.github/workflows/check-updates.yml b/.github/workflows/check-updates.yml index b37e2a1..af298ec 100644 --- a/.github/workflows/check-updates.yml +++ b/.github/workflows/check-updates.yml @@ -12,7 +12,7 @@ permissions: jobs: check-updates: - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 3edf4e2..74030f9 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -55,7 +55,7 @@ jobs: # Quick smoke test on every push - builds entire chain locally smoke-test: if: github.event_name != 'workflow_dispatch' - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 timeout-minutes: 30 steps: @@ -133,7 +133,7 @@ jobs: # Full matrix test (manual trigger) full-matrix: if: github.event_name == 'workflow_dispatch' - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 timeout-minutes: 45 steps: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 96a2044..837573c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -14,7 +14,7 @@ permissions: jobs: framework-detection-tests: name: Framework Detection Tests - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 steps: - name: Checkout code @@ -73,7 +73,7 @@ jobs: performance-benchmarks: name: Performance Benchmarks - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 needs: framework-detection-tests steps: @@ -128,7 +128,7 @@ jobs: security-scan: name: CVE Security Scan - runs-on: [self-hosted, linux, ax41] + runs-on: ubuntu-24.04 steps: - name: Checkout code From ab2cc22cb31892c9c820f758b64fafaaf64a2eb5 Mon Sep 17 00:00:00 2001 From: Sylvester Damgaard Date: Thu, 7 May 2026 11:43:31 +0200 Subject: [PATCH 3/3] chore(deps): bump cbox-init to v2.1.1 Co-Authored-By: Claude Opus 4.6 (1M context) --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 12c2b31..a4e512a 100644 --- a/versions.json +++ b/versions.json @@ -48,7 +48,7 @@ }, "tools": { "composer": "2", - "cbox_init": "2.1.0" + "cbox_init": "2.1.1" }, "deprecation_policy": { "php_removal_after_eol_months": 6,