platform/site-templates/images/php-fpm/Dockerfile
Bart Van Geyt edfb4c44b8 Phase 3: site templates & base images
Add the building blocks the provisioning CLI renders per site.

Base images (site-templates/images):
- php-fpm: non-root (www-data) php:<ver>-fpm-alpine with pdo_mysql, mysqli,
  gd, intl, zip, opcache, exif; tuned php.ini + pool; built per PHP version.
- nginx: hardened nginx:1.27-alpine with shared security + fastcgi snippets;
  per-site server block mounted at runtime.
- build.sh: build + Trivy-scan (+ optional push) for both images.

Profile templates (site-templates/profiles), Jinja2 rendered:
- static, redirect (tiny nginx 301/302), custom-php (nginx + our php-fpm,
  optional DB), wordpress (nginx + official wordpress-fpm, DB required,
  upload-exec denied). Only nginx carries Traefik labels and joins proxy;
  php-fpm uses the private <slug>_net and joins platform only when a DB is
  needed. Secrets stay in a git-ignored .env, not the compose.

CI: .forgejo/workflows/images.yml builds/scans images (gitleaks + Trivy).
README documents the render context and the Phase 4 web-root ownership item.

Templates validated: all profiles render to valid compose YAML across the
database on/off branches and single/multi-domain host rules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:06:25 +02:00

27 lines
1.2 KiB
Docker

# heleos php-fpm base image — runs as non-root (www-data, uid 82 on alpine).
# Build arg PHP_VERSION selects the runtime; tag the image to match.
ARG PHP_VERSION=8.3
FROM php:${PHP_VERSION}-fpm-alpine
# Build extensions with dev headers, then keep only the runtime shared libs.
RUN set -eux; \
apk add --no-cache --virtual .build-deps \
icu-dev libzip-dev libpng-dev libjpeg-turbo-dev freetype-dev oniguruma-dev; \
docker-php-ext-configure gd --with-freetype --with-jpeg; \
docker-php-ext-install -j"$(nproc)" \
pdo_mysql mysqli gd intl zip opcache exif; \
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' | sort -u | awk 'system("[ -e /usr/local/lib/"$1" ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-cache $runDeps icu-libs libzip libpng libjpeg-turbo freetype oniguruma; \
apk del .build-deps
# Platform php + pool config.
COPY php.ini /usr/local/etc/php/conf.d/zz-heleos.ini
COPY www.conf /usr/local/etc/php-fpm.d/zz-heleos.conf
# Drop privileges: the container runs entirely as www-data. php-fpm listens on
# TCP 9000 (unprivileged), so no root is needed.
USER www-data
EXPOSE 9000