Production-ready RPM packaging system for PHP >= 8.5.12 compiled from official php.net sources, targeting VMware Photon OS 5.x with full tdnf compatibility.
- PHP 8.5.12 built from source with optimized flags (
-O2, LTO, stack protector, FORTIFY_SOURCE) - Split RPM subpackages: CLI, FPM, OPcache, and 15+ standard extensions
- PECL extensions: redis, igbinary, apcu, amqp, imagick, xdebug
- Production PHP-FPM configuration with security hardening
- Multi-architecture builds:
x86_64andaarch64via Docker Buildx + QEMU - Public RPM repository via GitHub Pages: https://pkgs.photon.lemric.com
- Kubernetes-ready Docker images (docker-library/php compatible layout)
├── .github/workflows/ # CI/CD pipelines
├── packaging/ # PHP, re2c, rabbitmq-c RPM specs
├── extensions/ # PECL extension specs
├── docker/ # Photon OS docker-library/php compatible images
│ └── 8.5/photon/ # CLI + FPM
├── pages/ # GitHub Pages templates (deployed to gh-pages branch)
├── scripts/ # Build automation
└── repo/ # Local build output (not committed)
- VMware Photon OS 5.x (or
photon:5.0Docker image) tdnf,rpm-build,createrepo_c- Root access for local builds
- Docker + Buildx + QEMU for multi-arch builds
On a Photon OS 5.x host or container:
git clone https://github.com/YOUR_ORG/photon-php.git
cd photon-php
sudo ./scripts/install-build-deps.sh# Build everything (re2c → PHP → extensions)
sudo ./scripts/build-rpm.sh all
# Or step by step:
sudo ./scripts/build-rpm.sh re2c # re2c >= 3.x (required by PHP 8.5)
sudo ./scripts/build-rpm.sh php # PHP core + extensions
sudo ./scripts/build-rpm.sh extensions # PECL extensions onlyRPMs are written to repo/$(uname -m)/.
sudo ./scripts/build-repo.sh# Builder image
docker build -f docker/Dockerfile.builder -t photon-php-builder .
# Build RPMs
docker run --rm -v "$(pwd):/build" -w /build photon-php-builder all
# Create repo metadata
docker run --privileged --rm -v "$(pwd):/build" -w /build photon:5.0 \
bash -c "tdnf install -y createrepo_c && ./scripts/build-repo.sh"docker buildx create --use --name photon-builder 2>/dev/null || true
for ARCH in x86_64 aarch64; do
PLATFORM=$([ "$ARCH" = "aarch64" ] && echo "linux/arm64" || echo "linux/amd64")
docker run --privileged --rm --platform "$PLATFORM" \
-v "$(pwd):/build" -w /build \
-e ARCH="$ARCH" \
-e OUTPUT_DIR="/build/repo/$ARCH" \
photon:5.0 \
bash -c "chmod +x scripts/*.sh && scripts/install-build-deps.sh && scripts/build-rpm.sh all"
done
docker run --privileged --rm -v "$(pwd):/build" -w /build photon:5.0 \
bash -c "tdnf install -y createrepo_c && ./scripts/build-repo.sh"Public repository: https://pkgs.photon.lemric.com
curl -fsSL https://pkgs.photon.lemric.com/photon-php.repo \
-o /etc/yum.repos.d/photon-php.repo
tdnf makecache
tdnf install -y php85 php85-fpm php85-opcacheOr configure manually:
ARCH=$(uname -m)
cat > /etc/yum.repos.d/photon-php.repo << EOF
[photon-php]
name=Photon PHP 8.5
baseurl=https://pkgs.photon.lemric.com/\${ARCH}
enabled=1
gpgcheck=0
EOF
tdnf makecache# Minimal web stack
tdnf install -y php85 php85-fpm php85-opcache
# Full production stack
tdnf install -y \
php85 php85-cli php85-fpm php85-common php85-opcache \
php85-mbstring php85-intl php85-xml php85-curl php85-gd \
php85-zip php85-bcmath php85-sodium php85-mysqlnd php85-pgsql \
php85-pecl-redis php85-pecl-igbinaryphp -v
php -m
php -r 'var_export(defined("PASSWORD_ARGON2ID"));' # Argon2 in php85-cli (libargon2)
php-fpm -t
systemctl enable --now php85-php-fpm| Path | Purpose |
|---|---|
/etc/php85/php.ini |
Main PHP configuration (production) |
/etc/php85/conf.d/ |
Extension .ini drop-ins |
/etc/php85/php-fpm.conf |
FPM global config |
/etc/php85/php-fpm.d/www.conf |
Default pool |
/usr/lib64/php85/modules/ |
PHP extension .so files |
expose_php = Offdisplay_errors = Off,log_errors = On- Dangerous functions disabled (
exec,shell_exec, etc.) - FPM:
clear_env = yes,security.limit_extensions = .php - OPcache:
validate_timestamps = 0(production), JIT tracing enabled
Production images are built from GPG-signed RPMs and published to GHCR after each successful RPM CI run.
| Image | Role |
|---|---|
ghcr.io/lemric/php85-photon-base |
Core modules (extend with your own SAPI) |
ghcr.io/lemric/php85-photon-cli |
PHP CLI |
ghcr.io/lemric/php85-photon-fpm |
PHP-FPM |
See docker/README.md for local build instructions.
docker run --rm -it ghcr.io/lemric/php85-photon-cli:8.5.12 php -v
docker run -d --name php-fpm -p 9000:9000 ghcr.io/lemric/php85-photon-fpm:8.5.12Legacy source-compile Dockerfiles (docker/8.5/photon/cli, docker/8.5/photon/fpm) remain for local development without published RPMs.
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-fpm
spec:
replicas: 2
selector:
matchLabels:
app: php-fpm
template:
metadata:
labels:
app: php-fpm
spec:
containers:
- name: php-fpm
image: php:8.5.12-fpm-photon
ports:
- containerPort: 9000
readinessProbe:
exec:
command: ["php-fpm", "-t"]
initialDelaySeconds: 5
livenessProbe:
exec:
command: ["php-fpm", "-t"]
periodSeconds: 30See docker/README.md for details.
RPM (tdnf) |
Docker | |
|---|---|---|
| Distribution | https://pkgs.photon.lemric.com | Container image |
| Binary | /usr/bin/php |
/usr/local/bin/php |
| Configuration | /etc/php85/ |
/usr/local/etc/php/ |
| Compatibility | Photon OS native | docker-library/php |
| Extensions | Separate RPMs | docker-php-ext-install |
Both approaches compile PHP 8.5.12 from php.net sources.
The RPM repository is published to the dedicated gh-pages branch and served at https://pkgs.photon.lemric.com.
| Branch | Contents |
|---|---|
main |
Source code, specs, CI workflows |
gh-pages |
RPM packages only (x86_64/, aarch64/, repo metadata) |
The gh-pages branch is updated incrementally by CI workflows after each package build. Do not commit source code to gh-pages.
- Settings → Pages → Build and deployment
- Source: Deploy from a branch
- Branch:
gh-pages// (root) - Custom domain:
pkgs.photon.lemric.com - Enable Enforce HTTPS after DNS propagation
| Type | Name | Value |
|---|---|---|
| CNAME | pkgs.photon |
<org>.github.io |
- Enable Enforce HTTPS after DNS propagation.
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml |
Push/PR to main, manual | Build bootstrap RPMs only when spec Version/Release changed; publish RPMs; reindex on every push to main |
build-php.yml |
After bootstrap, manual | Build PHP/PECL only when spec Version/Release changed; publish RPMs; reindex after each run |
docker-image.yml |
After successful PHP build, manual | Build/push Docker image from published RPMs on gh-pages |
Actions → Build PHP RPMs → Run workflow. Uses bootstrap packages already on gh-pages.
Actions → Docker PHP 8.5 (from published RPMs) → Run workflow. Uses packages already on gh-pages.
PHP series are defined in packaging/series/<NN>.conf (85, 86); the specs
contain no hard-coded version. scripts/build-rpm.sh reads the series selected
by PHP_SERIES (default 85) and passes it to rpmbuild as macros.
- Edit
PHP_VERSION(andPHP_PRERELEASEfor an RC) inpackaging/series/<NN>.conf - Add a changelog entry in
packaging/php.spec - Bump
Releaseinextensions/*.specso the extensions are rebuilt against the new PHP - Build:
PHP_SERIES=85 ./scripts/build-rpm.sh all - Tag and release:
git tag php-8.5.X && git push origin php-8.5.X
Only one PHP series can be installed on a host at a time (php85 and php86
conflict); build each series in a separate container or CI run
(php_series input of the Build PHP RPMs workflow).
PHP 8.6 release candidates are fetched from the php/php-src GitHub tag, because RC
tarballs are not published under php.net/distributions. A pre-release is packaged
as 8.6.0-0.rcN.M so that the final 8.6.0 upgrades it. For the final release,
set PHP_PRERELEASE= and switch PHP_SRCURL/PHP_SRCDIR to the php.net values
from 85.conf.
Extension sources come from the upstream VCS tags (GitHub), not from pecl.php.net, which is being retired in favour of PIE.
Some packages may not exist in default Photon OS 5.x repositories. This project provides specs to build them:
| Package | Spec | Required for |
|---|---|---|
re2c >= 3.x |
packaging/re2c.spec |
PHP 8.5 build |
libzip |
packaging/libzip.spec |
php85-zip extension |
rabbitmq-c |
packaging/rabbitmq-c.spec |
php85-pecl-amqp |
See packaging/photon-packages.md for Photon OS vs Fedora package name mapping.
Build order is handled automatically by scripts/build-rpm.sh.
If ImageMagick-devel is not available in Photon repos:
# Check availability
tdnf info ImageMagick-devel
# If missing, install from Photon contrib or build from source
# then rebuild: ./scripts/build-rpm.sh extensionsCFLAGS = -O2 -flto=auto -fstack-protector-strong -D_FORTIFY_SOURCE=2 -fPIC
LDFLAGS = -Wl,-z,relro -Wl,-z,now -flto=autoPHP configure includes all required extensions as shared modules for clean RPM splitting. Binaries are stripped to minimize package size.
- Files installed only under
/usr,/etc,/var - Correct ownership and permissions (
%defattr) - Dedicated
php-fpmsystem user - FPM systemd unit with
ProtectSystem,NoNewPrivileges, syscall filtering - Rootless Docker compatible
PHP is licensed under the PHP License v3.01. PECL extensions follow their respective licenses. Build scripts and specs in this repository are provided as-is for production use.