Files
shadowdaoandClaude Opus 5.5 76fc53358c ci: stop building PHP 7.4, 8.0 and 8.1 images
All four image matrices (cac, cac-fpm, cac-litespeed, cac-lsphp) and the
emergency lsphp-from-source workflow now build PHP 8.2-8.5 only. 7.4-8.1 are
end of life and got no upstream fix for CVE-2026-109618/109619; no fleet site
runs them any more. Existing :php74/:php80/:php81 tags stay in the registry
but are no longer rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 18:13:18 -07:00

598 lines
28 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Cloud Apache Container
run-name: ${{ gitea.actor }} pushed a change to trunk
on:
push:
branches:
- trunk
workflow_dispatch:
jobs:
# Shell gate. Runs FIRST and costs seconds; the images below do not depend on
# it (a red job here does not block a push that is otherwise fine), but it is
# the only place the ENTRYPOINT logic is executed at all. The .phpt suite and
# the Dockerfile's `lsphp -i` probe both test the extension, and both were
# green for the release whose entrypoint declared that same extension
# missing — see scripts/tests/lsphp-info-probe.test.sh for what went wrong
# and why it needed a test outside the image build to catch it.
Shell-Checks:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# Runner images differ on whether they are root and whether sudo exists.
- name: Install shellcheck
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
(apt-get update && apt-get install -y shellcheck) ||
(sudo apt-get update && sudo apt-get install -y shellcheck)
fi
shellcheck --version
- name: Syntax check every shell script
run: |
set -euo pipefail
find scripts ext -name '*.sh' -print0 | xargs -0 -n1 bash -n
# Deliberately NOT repo-wide. The older scripts (entrypoint.sh,
# entrypoint-fpm.sh, create-vhost.sh, create-php-config.sh,
# detect-memory.sh) carry pre-existing SC2154/SC2027 findings that predate
# this job; listing them here would make the gate red on arrival and
# therefore ignored. This is the set that is clean today — the scripts
# that run `set -o pipefail` plus the tests. Add files as they are fixed;
# do not add one that is not yet clean.
- name: shellcheck (warnings and above, on the clean set)
run: |
shellcheck -S warning \
scripts/entrypoint-lsphp.sh \
scripts/entrypoint-litespeed.sh \
scripts/entrypoint-shared-ols.sh \
scripts/render-shared-ols-config.sh \
scripts/ols-htaccess-watcher.sh \
scripts/create-vhost-litespeed.sh \
scripts/install-lscache-wp.sh \
scripts/lsphp-apt-upgrade.sh \
scripts/lsphp-src-build.sh \
scripts/lsphp-src-overlay.sh \
scripts/lsphp-abi-gate.sh \
scripts/tune-mpm.sh \
scripts/tests/lsphp-info-probe.test.sh \
scripts/tests/lsphp-abi-gate.test.sh
- name: lsphp probe regression test
run: ./scripts/tests/lsphp-info-probe.test.sh
# The emergency php.net lsphp path (lsphp-source-emergency.yaml) keeps
# LiteSpeed's PECL .so files only if this gate says the Zend ABI is
# unchanged; prove here, on every push, that the gate can still FAIL.
- name: lsphp ABI gate regression test
run: |
if ! command -v pahole >/dev/null 2>&1 || ! command -v gcc >/dev/null 2>&1; then
(apt-get update && apt-get install -y gcc dwarves) ||
(sudo apt-get update && sudo apt-get install -y gcc dwarves)
fi
./scripts/tests/lsphp-abi-gate.test.sh
Build-and-Push:
runs-on: ubuntu-latest
strategy:
# One PHP version failing (e.g. an EOL stream) must not cancel the
# security builds of the others.
fail-fast: false
matrix:
phpver: [82, 83, 84, 85]
steps:
- name: Checkout
uses: actions/checkout@v4
# Internal package cache (CT130 pkg-cache, docs/pkg-cache.md). Used ONLY if
# it answers over TLS with our pinned CA; otherwise (down, unreachable,
# bad/expired cert) this job builds from the upstream repos and Docker Hub
# exactly as before. The repo cache and the registry mirror are probed
# separately so either can fail back on its own.
- name: Probe package cache
id: pkgcache
run: |
url=""; mirror=""
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40/; then url="https://192.168.1.40"; fi
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40:5000/v2/; then mirror="192.168.1.40:5000"; fi
echo "pkg-cache: repos=${url:-<unreachable: upstream>} registry-mirror=${mirror:-<unreachable: Docker Hub>}"
[ -n "$url" ] || echo "::warning::pkg-cache unreachable - building from upstream repositories"
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "mirror=${mirror}" >> "$GITHUB_OUTPUT"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
# so the mirror is configured on the builder; BuildKit itself still falls
# back to Docker Hub if the mirror stops answering mid-run.
- name: Set up Docker Buildx (Docker Hub via pkg-cache mirror)
if: steps.pkgcache.outputs.mirror != ''
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["192.168.1.40:5000"]
[registry."192.168.1.40:5000"]
ca = ["${{ github.workspace }}/keys/pkg-cache/ca.crt"]
- name: Set up Docker Buildx
if: steps.pkgcache.outputs.mirror == ''
uses: docker/setup-buildx-action@v3
# Per-run cache-bust value. Each job's buildx builder is created fresh by
# setup-buildx-action (no cache-from/cache-to here), so today nothing is
# cached between runs — this keeps it that way if a cache is ever added:
# the package-upgrade layers consume CACHE_BUST and can never be reused.
- name: Cache-bust value
id: bust
env:
RUN_ID: ${{ gitea.run_id }}
run: echo "value=$(date -u +%Y%m%dT%H%M%SZ)-${RUN_ID}" >> "$GITHUB_OUTPUT"
# The minimum PHP version this build must ship: php.net's current release for
# the branch (over HTTPS). The Dockerfile fails if Remi gave us anything older,
# so lagging mirrors or replayed repo metadata can't ship a vulnerable PHP.
- name: Resolve current PHP release from php.net
id: phpmin
# Values reach the script via env, never via ${{ }} inside run: (a
# crafted string would otherwise be shell); outputs are regex-checked.
env:
PHPVER: ${{ matrix.phpver }}
run: |
set -euo pipefail
v="$PHPVER"; branch="${v:0:1}.${v:1}"
json=$(curl -fsS --retry 5 --max-time 60 "https://www.php.net/releases/index.php?json&max=1&version=${branch}")
min=$(printf '%s' "$json" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(next(iter(d)) if isinstance(d,dict) and d else "")')
if [ -z "$min" ]; then echo "::error::no php.net release found for ${branch}"; exit 1; fi
[[ "$min" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "::error::php.net returned a malformed version for ${branch}"; exit 1; }
echo "php.net current ${branch}: ${min}"
echo "min=${min}" >> "$GITHUB_OUTPUT"
- name: Login to Gitea
uses: docker/login-action@v3
with:
registry: repo.anhonesthost.net
username: ${{ secrets.CI_USER }}
password: ${{ secrets.CI_TOKEN }}
- name: Build and Push Image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64
push: true
build-args: |
PHPVER=${{ matrix.phpver }}
CACHE_BUST=${{ steps.bust.outputs.value }}
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
tags: |
repo.anhonesthost.net/cloud-hosting-platform/cac:php${{ matrix.phpver }}
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac:latest' || '' }}
Build-FPM-Images:
runs-on: ubuntu-latest
strategy:
# One PHP version failing (e.g. an EOL stream) must not cancel the
# security builds of the others.
fail-fast: false
matrix:
phpver: [82, 83, 84, 85]
steps:
- name: Checkout
uses: actions/checkout@v4
# Internal package cache (CT130 pkg-cache, docs/pkg-cache.md). Used ONLY if
# it answers over TLS with our pinned CA; otherwise (down, unreachable,
# bad/expired cert) this job builds from the upstream repos and Docker Hub
# exactly as before. The repo cache and the registry mirror are probed
# separately so either can fail back on its own.
- name: Probe package cache
id: pkgcache
run: |
url=""; mirror=""
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40/; then url="https://192.168.1.40"; fi
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40:5000/v2/; then mirror="192.168.1.40:5000"; fi
echo "pkg-cache: repos=${url:-<unreachable: upstream>} registry-mirror=${mirror:-<unreachable: Docker Hub>}"
[ -n "$url" ] || echo "::warning::pkg-cache unreachable - building from upstream repositories"
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "mirror=${mirror}" >> "$GITHUB_OUTPUT"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
# so the mirror is configured on the builder; BuildKit itself still falls
# back to Docker Hub if the mirror stops answering mid-run.
- name: Set up Docker Buildx (Docker Hub via pkg-cache mirror)
if: steps.pkgcache.outputs.mirror != ''
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["192.168.1.40:5000"]
[registry."192.168.1.40:5000"]
ca = ["${{ github.workspace }}/keys/pkg-cache/ca.crt"]
- name: Set up Docker Buildx
if: steps.pkgcache.outputs.mirror == ''
uses: docker/setup-buildx-action@v3
# Per-run cache-bust value. Each job's buildx builder is created fresh by
# setup-buildx-action (no cache-from/cache-to here), so today nothing is
# cached between runs — this keeps it that way if a cache is ever added:
# the package-upgrade layers consume CACHE_BUST and can never be reused.
- name: Cache-bust value
id: bust
env:
RUN_ID: ${{ gitea.run_id }}
run: echo "value=$(date -u +%Y%m%dT%H%M%SZ)-${RUN_ID}" >> "$GITHUB_OUTPUT"
# The minimum PHP version this build must ship: php.net's current release for
# the branch (over HTTPS). The Dockerfile fails if Remi gave us anything older,
# so lagging mirrors or replayed repo metadata can't ship a vulnerable PHP.
- name: Resolve current PHP release from php.net
id: phpmin
# Values reach the script via env, never via ${{ }} inside run: (a
# crafted string would otherwise be shell); outputs are regex-checked.
env:
PHPVER: ${{ matrix.phpver }}
run: |
set -euo pipefail
v="$PHPVER"; branch="${v:0:1}.${v:1}"
json=$(curl -fsS --retry 5 --max-time 60 "https://www.php.net/releases/index.php?json&max=1&version=${branch}")
min=$(printf '%s' "$json" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(next(iter(d)) if isinstance(d,dict) and d else "")')
if [ -z "$min" ]; then echo "::error::no php.net release found for ${branch}"; exit 1; fi
[[ "$min" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "::error::php.net returned a malformed version for ${branch}"; exit 1; }
echo "php.net current ${branch}: ${min}"
echo "min=${min}" >> "$GITHUB_OUTPUT"
- name: Login to Gitea
uses: docker/login-action@v3
with:
registry: repo.anhonesthost.net
username: ${{ secrets.CI_USER }}
password: ${{ secrets.CI_TOKEN }}
- name: Build and Push FPM Image
uses: docker/build-push-action@v6
with:
file: ./Dockerfile.fpm
platforms: linux/amd64
push: true
build-args: |
PHPVER=${{ matrix.phpver }}
CACHE_BUST=${{ steps.bust.outputs.value }}
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
tags: |
repo.anhonesthost.net/cloud-hosting-platform/cac-fpm:php${{ matrix.phpver }}
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-fpm:latest' || '' }}
Build-LiteSpeed-Images:
runs-on: ubuntu-latest
strategy:
# One PHP version failing (e.g. an EOL stream) must not cancel the
# security builds of the others.
fail-fast: false
matrix:
# PHP 7.4/8.0 deliberately excluded — the LiteSpeed prebuilt base
# images stop at older OLS releases for those PHP versions, and the
# cac-litespeed tier is a paid premium offering: 8.1+ is the
# modernization story we're selling.
phpver: [82, 83, 84, 85]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Per-run cache-bust value. Each job's buildx builder is created fresh by
# setup-buildx-action (no cache-from/cache-to here), so today nothing is
# cached between runs — this keeps it that way if a cache is ever added:
# the package-upgrade layers consume CACHE_BUST and can never be reused.
- name: Cache-bust value
id: bust
env:
RUN_ID: ${{ gitea.run_id }}
run: echo "value=$(date -u +%Y%m%dT%H%M%SZ)-${RUN_ID}" >> "$GITHUB_OUTPUT"
# Ask the LiteSpeed apt repo (the same one the base image's apt uses) for the
# CURRENT lsphp version. The Dockerfile asserts the installed package equals
# this (build fails if the repo changed mid-build — just re-run) and writes
# it into the image labels org.whp.php-version / org.whp.lsphp-package-version.
- name: Resolve current lsphp${{ matrix.phpver }} from the LiteSpeed repo
id: lsphp
# HTTPS (rpms.litespeedtech.com serves it; measured 2026-10-21), values via
# env, and both outputs regex-checked before they reach GITHUB_OUTPUT.
env:
PHPVER: ${{ matrix.phpver }}
run: |
set -euo pipefail
idx=$(curl -fsS --proto '=https' --retry 3 --max-time 60 https://rpms.litespeedtech.com/debian/dists/noble/main/binary-amd64/Packages)
pkg=$(printf '%s\n' "$idx" | awk -v p="lsphp${PHPVER}" '/^Package: /{n=$2} /^Version: / && n==p {print $2}' | sort -V | tail -n1)
if [ -z "$pkg" ]; then echo "::error::lsphp${PHPVER} not found in the LiteSpeed repo index"; exit 1; fi
php="${pkg%%-*}"
[[ "$pkg" =~ ^[0-9][0-9A-Za-z.+~:-]*$ ]] || { echo "::error::malformed lsphp${PHPVER} package version in the repo index"; exit 1; }
[[ "$php" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "::error::malformed PHP version '${php}' derived from lsphp${PHPVER} ${pkg}"; exit 1; }
echo "lsphp${PHPVER} in repo: $pkg (PHP ${php})"
echo "pkg=$pkg" >> "$GITHUB_OUTPUT"
echo "php=${php}" >> "$GITHUB_OUTPUT"
- name: Login to Gitea
uses: docker/login-action@v3
with:
registry: repo.anhonesthost.net
username: ${{ secrets.CI_USER }}
password: ${{ secrets.CI_TOKEN }}
# A php.net emergency build (lsphp-source-emergency.yaml) may be what
# :phpNN points at right now. While LiteSpeed still lags, a normal build
# would silently put the VULNERABLE packaged lsphp back. Refuse instead;
# the job goes green again by itself once the LiteSpeed repo catches up.
# Fail-open if the tag cannot be inspected (first build, registry blip).
- name: Do not roll back a newer php.net emergency image
env:
PHPVER: ${{ matrix.phpver }}
NEW_PHP: ${{ steps.lsphp.outputs.php }}
run: |
set -euo pipefail
ref="repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:php${PHPVER}"
src=$(docker buildx imagetools inspect "$ref" --format '{{ index .Image.Config.Labels "org.whp.lsphp-source" }}' 2>/dev/null || true)
cur=$(docker buildx imagetools inspect "$ref" --format '{{ index .Image.Config.Labels "org.whp.php-version" }}' 2>/dev/null || true)
new="$NEW_PHP"
echo "published $ref: source=${src:-?} php=${cur:-?}; this build: packaged $new"
if [ "$src" = "php.net" ] && [ "$cur" != "$new" ] && [ "$(printf '%s\n%s\n' "$cur" "$new" | sort -V | tail -n1)" = "$cur" ]; then
echo "::error::$ref is a php.net emergency build of PHP $cur; LiteSpeed still ships $new. Not overwriting it with an older PHP. Re-run lsphp-source-emergency.yaml for a newer fix, or wait for LiteSpeed."
exit 1
fi
- name: Build and Push LiteSpeed Image
uses: docker/build-push-action@v6
with:
file: ./Dockerfile.litespeed
platforms: linux/amd64
push: true
build-args: |
PHPVER=${{ matrix.phpver }}
OLS_VERSION=1.8.4
CACHE_BUST=${{ steps.bust.outputs.value }}
EXPECT_LSPHP_PKG=${{ steps.lsphp.outputs.pkg }}
EXPECT_PHP_VERSION=${{ steps.lsphp.outputs.php }}
# OLS_VERSION pinned to 1.8.4. It was the only release with an lsphp81
# variant; 8.1 and older are no longer built (2026-10-21), so the pin
# can move to a newer OLS release after a local rebuild test.
# See spec: docs/superpowers/specs/2026-06-01-cac-litespeed-design.md
tags: |
repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:php${{ matrix.phpver }}
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:latest' || '' }}
Build-LSPHP-Images:
runs-on: ubuntu-latest
strategy:
# One PHP version failing (e.g. an EOL stream) must not cancel the
# security builds of the others.
fail-fast: false
matrix:
# Same PHP matrix as cac-litespeed (81–85): cac-lsphp is the detached
# backend for the shared-ols tier and shares the litespeed prebuilt
# base, which only ships lsphp for 8.1+. Keep this matrix in lockstep
# with Build-LiteSpeed-Images.
phpver: [82, 83, 84, 85]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Per-run cache-bust value. Each job's buildx builder is created fresh by
# setup-buildx-action (no cache-from/cache-to here), so today nothing is
# cached between runs — this keeps it that way if a cache is ever added:
# the package-upgrade layers consume CACHE_BUST and can never be reused.
- name: Cache-bust value
id: bust
env:
RUN_ID: ${{ gitea.run_id }}
run: echo "value=$(date -u +%Y%m%dT%H%M%SZ)-${RUN_ID}" >> "$GITHUB_OUTPUT"
# Ask the LiteSpeed apt repo (the same one the base image's apt uses) for the
# CURRENT lsphp version. The Dockerfile asserts the installed package equals
# this (build fails if the repo changed mid-build — just re-run) and writes
# it into the image labels org.whp.php-version / org.whp.lsphp-package-version.
- name: Resolve current lsphp${{ matrix.phpver }} from the LiteSpeed repo
id: lsphp
# HTTPS (rpms.litespeedtech.com serves it; measured 2026-10-21), values via
# env, and both outputs regex-checked before they reach GITHUB_OUTPUT.
env:
PHPVER: ${{ matrix.phpver }}
run: |
set -euo pipefail
idx=$(curl -fsS --proto '=https' --retry 3 --max-time 60 https://rpms.litespeedtech.com/debian/dists/noble/main/binary-amd64/Packages)
pkg=$(printf '%s\n' "$idx" | awk -v p="lsphp${PHPVER}" '/^Package: /{n=$2} /^Version: / && n==p {print $2}' | sort -V | tail -n1)
if [ -z "$pkg" ]; then echo "::error::lsphp${PHPVER} not found in the LiteSpeed repo index"; exit 1; fi
php="${pkg%%-*}"
[[ "$pkg" =~ ^[0-9][0-9A-Za-z.+~:-]*$ ]] || { echo "::error::malformed lsphp${PHPVER} package version in the repo index"; exit 1; }
[[ "$php" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "::error::malformed PHP version '${php}' derived from lsphp${PHPVER} ${pkg}"; exit 1; }
echo "lsphp${PHPVER} in repo: $pkg (PHP ${php})"
echo "pkg=$pkg" >> "$GITHUB_OUTPUT"
echo "php=${php}" >> "$GITHUB_OUTPUT"
- name: Login to Gitea
uses: docker/login-action@v3
with:
registry: repo.anhonesthost.net
username: ${{ secrets.CI_USER }}
password: ${{ secrets.CI_TOKEN }}
# A php.net emergency build (lsphp-source-emergency.yaml) may be what
# :phpNN points at right now. While LiteSpeed still lags, a normal build
# would silently put the VULNERABLE packaged lsphp back. Refuse instead;
# the job goes green again by itself once the LiteSpeed repo catches up.
# Fail-open if the tag cannot be inspected (first build, registry blip).
- name: Do not roll back a newer php.net emergency image
env:
PHPVER: ${{ matrix.phpver }}
NEW_PHP: ${{ steps.lsphp.outputs.php }}
run: |
set -euo pipefail
ref="repo.anhonesthost.net/cloud-hosting-platform/cac-lsphp:php${PHPVER}"
src=$(docker buildx imagetools inspect "$ref" --format '{{ index .Image.Config.Labels "org.whp.lsphp-source" }}' 2>/dev/null || true)
cur=$(docker buildx imagetools inspect "$ref" --format '{{ index .Image.Config.Labels "org.whp.php-version" }}' 2>/dev/null || true)
new="$NEW_PHP"
echo "published $ref: source=${src:-?} php=${cur:-?}; this build: packaged $new"
if [ "$src" = "php.net" ] && [ "$cur" != "$new" ] && [ "$(printf '%s\n%s\n' "$cur" "$new" | sort -V | tail -n1)" = "$cur" ]; then
echo "::error::$ref is a php.net emergency build of PHP $cur; LiteSpeed still ships $new. Not overwriting it with an older PHP. Re-run lsphp-source-emergency.yaml for a newer fix, or wait for LiteSpeed."
exit 1
fi
- name: Build and Push lsphp Image
uses: docker/build-push-action@v6
with:
file: ./Dockerfile.lsphp
platforms: linux/amd64
push: true
build-args: |
PHPVER=${{ matrix.phpver }}
OLS_VERSION=1.8.4
CACHE_BUST=${{ steps.bust.outputs.value }}
EXPECT_LSPHP_PKG=${{ steps.lsphp.outputs.pkg }}
EXPECT_PHP_VERSION=${{ steps.lsphp.outputs.php }}
# OLS_VERSION pinned to 1.8.4 to match Build-LiteSpeed-Images — same
# prebuilt base, same lsphp binaries. Bump both together.
tags: |
repo.anhonesthost.net/cloud-hosting-platform/cac-lsphp:php${{ matrix.phpver }}
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-lsphp:latest' || '' }}
Build-Shared-httpd:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# Internal package cache (CT130 pkg-cache, docs/pkg-cache.md). Used ONLY if
# it answers over TLS with our pinned CA; otherwise (down, unreachable,
# bad/expired cert) this job builds from the upstream repos and Docker Hub
# exactly as before. The repo cache and the registry mirror are probed
# separately so either can fail back on its own.
- name: Probe package cache
id: pkgcache
run: |
url=""; mirror=""
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40/; then url="https://192.168.1.40"; fi
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40:5000/v2/; then mirror="192.168.1.40:5000"; fi
echo "pkg-cache: repos=${url:-<unreachable: upstream>} registry-mirror=${mirror:-<unreachable: Docker Hub>}"
[ -n "$url" ] || echo "::warning::pkg-cache unreachable - building from upstream repositories"
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "mirror=${mirror}" >> "$GITHUB_OUTPUT"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
# so the mirror is configured on the builder; BuildKit itself still falls
# back to Docker Hub if the mirror stops answering mid-run.
- name: Set up Docker Buildx (Docker Hub via pkg-cache mirror)
if: steps.pkgcache.outputs.mirror != ''
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["192.168.1.40:5000"]
[registry."192.168.1.40:5000"]
ca = ["${{ github.workspace }}/keys/pkg-cache/ca.crt"]
- name: Set up Docker Buildx
if: steps.pkgcache.outputs.mirror == ''
uses: docker/setup-buildx-action@v3
- name: Login to Gitea
uses: docker/login-action@v3
with:
registry: repo.anhonesthost.net
username: ${{ secrets.CI_USER }}
password: ${{ secrets.CI_TOKEN }}
- name: Build and Push Shared httpd Image
uses: docker/build-push-action@v6
with:
file: ./Dockerfile.shared-httpd
platforms: linux/amd64
push: true
build-args: |
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
tags: |
repo.anhonesthost.net/cloud-hosting-platform/shared-httpd:latest
Build-Shared-OLS:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# Internal package cache (CT130 pkg-cache, docs/pkg-cache.md). Used ONLY if
# it answers over TLS with our pinned CA; otherwise (down, unreachable,
# bad/expired cert) this job builds from the upstream repos and Docker Hub
# exactly as before. The repo cache and the registry mirror are probed
# separately so either can fail back on its own.
- name: Probe package cache
id: pkgcache
run: |
url=""; mirror=""
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40/; then url="https://192.168.1.40"; fi
if curl -fsS --max-time 5 --cacert keys/pkg-cache/ca.crt -o /dev/null https://192.168.1.40:5000/v2/; then mirror="192.168.1.40:5000"; fi
echo "pkg-cache: repos=${url:-<unreachable: upstream>} registry-mirror=${mirror:-<unreachable: Docker Hub>}"
[ -n "$url" ] || echo "::warning::pkg-cache unreachable - building from upstream repositories"
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "mirror=${mirror}" >> "$GITHUB_OUTPUT"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
# so the mirror is configured on the builder; BuildKit itself still falls
# back to Docker Hub if the mirror stops answering mid-run.
- name: Set up Docker Buildx (Docker Hub via pkg-cache mirror)
if: steps.pkgcache.outputs.mirror != ''
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["192.168.1.40:5000"]
[registry."192.168.1.40:5000"]
ca = ["${{ github.workspace }}/keys/pkg-cache/ca.crt"]
- name: Set up Docker Buildx
if: steps.pkgcache.outputs.mirror == ''
uses: docker/setup-buildx-action@v3
- name: Login to Gitea
uses: docker/login-action@v3
with:
registry: repo.anhonesthost.net
username: ${{ secrets.CI_USER }}
password: ${{ secrets.CI_TOKEN }}
- name: Build and Push Shared OLS Image
uses: docker/build-push-action@v6
with:
file: ./Dockerfile.shared-ols
platforms: linux/amd64
push: true
# Single image (runs no PHP). PHPVER just selects the OLS base tag;
# pinned to 83 / OLS 1.8.4 to match the rest of the litespeed family.
build-args: |
PHPVER=83
OLS_VERSION=1.8.4
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
tags: |
repo.anhonesthost.net/cloud-hosting-platform/shared-ols:latest