Files
cloud-apache-container/Dockerfile
T
jknapp e7d4db5bd3
Cloud Apache Container / Shell-Checks (push) Successful in 17s
Cloud Apache Container / Build-and-Push (82) (push) Successful in 4m12s
Cloud Apache Container / Build-and-Push (83) (push) Successful in 5m6s
Cloud Apache Container / Build-and-Push (84) (push) Successful in 5m21s
Cloud Apache Container / Build-FPM-Images (85) (push) Successful in 2m31s
Cloud Apache Container / Build-and-Push (85) (push) Successful in 5m49s
Cloud Apache Container / Build-FPM-Images (83) (push) Successful in 5m35s
Cloud Apache Container / Build-FPM-Images (82) (push) Successful in 5m53s
Cloud Apache Container / Build-FPM-Images (84) (push) Successful in 5m39s
Cloud Apache Container / Build-LiteSpeed-Images (82) (push) Successful in 2m36s
Cloud Apache Container / Build-LiteSpeed-Images (83) (push) Successful in 4m52s
Cloud Apache Container / Build-LiteSpeed-Images (84) (push) Successful in 4m53s
Cloud Apache Container / Build-LSPHP-Images (84) (push) Successful in 2m50s
Cloud Apache Container / Build-LiteSpeed-Images (85) (push) Successful in 4m36s
Cloud Apache Container / Build-Shared-httpd (push) Successful in 1m40s
Cloud Apache Container / Build-Shared-OLS (push) Successful in 38s
Cloud Apache Container / Build-LSPHP-Images (83) (push) Successful in 5m25s
Cloud Apache Container / Build-LSPHP-Images (82) (push) Successful in 5m46s
Cloud Apache Container / Build-LSPHP-Images (85) (push) Successful in 5m33s
Merge pull request 'fix(cac): healthcheck fails only on no answer or 5xx, not 4xx' (#34) from fix/healthcheck-4xx into trunk
2026-10-22 15:04:10 +00:00

99 lines
5.3 KiB
Docker

# Base image. CI passes BASE_IMAGE=almalinux/10-base@sha256:<digest>, resolved
# DIRECTLY from Docker Hub in the same run (.gitea/scripts/resolve-base-image.sh),
# so the pkg-cache registry mirror can only serve content-addressed blobs.
# Local builds use the tag. docs/pkg-cache.md "Base-image digest pinning".
ARG BASE_IMAGE=almalinux/10-base
FROM ${BASE_IMAGE}
ARG PHPVER=83
# Per-CI-run value: the first RUN below (dnf update) and everything after it can
# never be a layer-cache hit, so every build gets the repos' current packages.
# Local builds: --build-arg CACHE_BUST=$(date +%s) or --no-cache.
ARG CACHE_BUST=
# php.net's current release for this branch (CI); the build fails on older PHP.
ARG EXPECT_PHP_MIN=
# OPTIONAL internal package cache, e.g. --build-arg PKG_CACHE=https://192.168.1.40
# (CT130 pkg-cache, https only). Unset = upstream repositories. Release RPMs are
# GPG-verified against keys/pkg-cache/ either way. Repo files
# are restored at the end of every RUN, so no layer keeps the cache address.
# See scripts/pkg-cache-repos.sh.
ARG PKG_CACHE=
COPY ./scripts/pkg-cache-repos.sh /usr/local/sbin/pkg-cache-repos.sh
COPY ./keys/pkg-cache/ /usr/local/share/pkg-cache/
# Install repos, update, install only needed packages, clean up in one layer
RUN /usr/local/sbin/pkg-cache-repos.sh rpm && \
/usr/local/sbin/pkg-cache-repos.sh release-install epel remi && \
# Use Remi's origin, not the mirrorlist: during the 2026-10-21 PHP security
# release the mirrors lagged hours behind (still 8.2.34 when 8.2.35 was out),
# so builds shipped unpatched PHP. HTTPS first; plain http only as a fallback
# because the origin's HTTPS dropped/timed out under that day's load. A
# replayed (old) http index can't ship old PHP: packages stay GPG-checked and
# the EXPECT_PHP_MIN gate below fails the build on anything older than php.net.
sed -i -e 's|^#baseurl=http://\(.*\)$|baseurl=https://\1 http://\1|' -e 's/^mirrorlist=/#mirrorlist=/' /etc/yum.repos.d/remi*.repo && \
/usr/local/sbin/pkg-cache-repos.sh rpm && \
printf 'retries=10\ntimeout=60\n' >> /etc/dnf/dnf.conf && \
dnf update -y && \
dnf install -y httpd mod_ssl openssl wget procps cronie iproute postgresql-devel microdnf less git \
nano rsync unzip zip mariadb bind-utils jq patch nc tree dos2unix && \
/usr/local/sbin/pkg-cache-repos.sh restore && \
dnf clean all && \
rm -rf /var/cache/dnf /usr/share/doc /usr/share/man /usr/share/locale/*
# Copy scripts into the image and set permissions
COPY ./scripts/ /scripts/
RUN chmod +x /scripts/*
# Install ImageMagick from EPEL with HEIC/HEIF/AVIF support
RUN /usr/local/sbin/pkg-cache-repos.sh rpm && \
dnf install -y ImageMagick ImageMagick-libs ImageMagick-heic && \
/usr/local/sbin/pkg-cache-repos.sh restore && \
dnf clean all
# Generate self-signed cert, create needed dirs, install PHP, clean up
RUN openssl req -newkey rsa:2048 -nodes -keyout /etc/pki/tls/private/localhost.key -x509 -days 3650 -subj "/CN=localhost" -out /etc/pki/tls/certs/localhost.crt && \
mkdir -p /run/php-fpm/ && \
/usr/local/sbin/pkg-cache-repos.sh rpm && \
/scripts/install-php$PHPVER.sh && \
/usr/local/sbin/pkg-cache-repos.sh restore && \
# CI passes php.net's current release for the branch; never ship older PHP.
if [ -n "$EXPECT_PHP_MIN" ]; then \
php -r 'exit(version_compare(PHP_VERSION, getenv("EXPECT_PHP_MIN"), ">=") ? 0 : 1);' || \
{ echo "FATAL: built PHP $(php -r 'echo PHP_VERSION;') is older than php.net $EXPECT_PHP_MIN"; exit 1; }; \
else echo "WARNING: no EXPECT_PHP_MIN (local build) - PHP version not gated"; fi && \
echo "PHP version report:" && php -v && rpm -q php-cli php-common php-fpm && \
rm -rf /tmp/*
# Download and install wp-cli (consider pinning version for reproducibility)
RUN curl -L -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \
chmod +x /usr/local/bin/wp
# Download and install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
chmod +x /usr/local/bin/composer
# Copy configs and web files
COPY ./configs/default-index.conf /etc/httpd/conf.d/
COPY ./configs/prod-php.ini /etc/php.ini
# php2shell mitigation (CVE-2026-109618/-109619). Named zz- so it sorts after
# every other scan-dir ini (incl. runtime-written 99-*) and wins. Remove once
# all images ship PHP >= 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12.
COPY ./configs/zz-php2shell-mitigation.ini /etc/php.d/zz-php2shell-mitigation.ini
COPY ./configs/phpinfo.php /var/www/html/
COPY ./configs/mariadb.repo /etc/yum.repos.d/
COPY ./configs/index.php /var/www/html/
COPY ./configs/remote_ip.conf /etc/httpd/conf.d/
COPY ./configs/whp-security.conf /etc/httpd/conf.d/
# Set up cron job in a single layer
RUN echo "15 */12 * * * root /scripts/log-rotate.sh" >> /etc/crontab
## Healthy = Apache answered with anything but a 5xx. `curl -f` also failed on
## 4xx, so a new site with an empty docroot (403) or an app with no route for /
## (404) showed unhealthy forever, and WHP's monitor restarted it as "PHP
## wedged". 000 (no answer) and 5xx (PHP/app error) still fail.
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
CMD code=$(curl -s -o /dev/null -m 4 -w '%{http_code}' http://localhost/); \
case "$code" in 000|5*) echo "http $code"; exit 1;; esac
ENTRYPOINT [ "/scripts/entrypoint.sh" ]