docs: update docs for rpm packages and extension availability (#1988)

continues https://github.com/php/frankenphp/pull/1756

---------

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
This commit is contained in:
Marc
2025-11-21 14:31:43 +01:00
committed by GitHub
parent 01beb66573
commit f28f6e8d03
7 changed files with 125 additions and 184 deletions

View File

@@ -297,7 +297,6 @@ jobs:
targets: static-builder-gnu
set: |
${{ (github.event_name == 'pull_request' || matrix.platform == 'linux/arm64') && 'static-builder-gnu.args.NO_COMPRESS=1' || '' }}
static-builder-gnu.args.BUILD_PACKAGES=1
*.tags=
*.platform=${{ matrix.platform }}
*.cache-from=type=gha,scope=${{ needs.prepare.outputs.ref || github.ref }}-static-builder-gnu

View File

@@ -16,21 +16,58 @@ FrankenPHP can also be used as a standalone Go library to embed PHP in any app u
## Getting Started
### Standalone Binary
We provide static FrankenPHP binaries for Linux and macOS
containing [PHP 8.4](https://www.php.net/releases/8.4/en.php) and most popular PHP extensions.
On Windows, use [WSL](https://learn.microsoft.com/windows/wsl/) to run FrankenPHP.
[Download FrankenPHP](https://github.com/php/frankenphp/releases) or copy this line into your
terminal to automatically install the version appropriate for your platform:
### Install Script
You can copy this line into your terminal to automatically
install an appropriate version for your platform:
```console
curl https://frankenphp.dev/install.sh | sh
mv frankenphp /usr/local/bin/
```
### Standalone Binary
We provide static FrankenPHP binaries for development purposes on Linux and macOS
containing [PHP 8.4](https://www.php.net/releases/8.4/en.php) and most popular PHP extensions.
[Download FrankenPHP](https://github.com/php/frankenphp/releases)
### rpm Packages
Our maintainers offer rpm packages for all systems using `dnf`. To install, run:
```console
sudo dnf install https://rpm.henderkes.com/static-php-1-0.noarch.rpm
sudo dnf module enable php-zts:static-8.4 # 8.2-8.5 available
sudo dnf install frankenphp
# to install extensions:
sudo dnf install php-zts-xdebug
# if an extension is not available by default, install it with pie
sudo dnf install php-zts-devel
sudo pie install asgrim/example-pie-extension --with-php-config=php-config-zts
```
### deb Packages
Our maintainers offer deb packages for all systems using `apt`. To install, run:
```console
sudo curl -fsSL https://key.henderkes.com/static-php.gpg -o /usr/share/keyrings/static-php.gpg && \
echo "deb [signed-by=/usr/share/keyrings/static-php.gpg] https://deb.henderkes.com/ stable main" | sudo tee /etc/apt/sources.list.d/static-php.list && \
sudo apt update
sudo apt install frankenphp
# to install extensions:
sudo apt install php-zts-xdebug
# if an extension is not available by default, install it with pie
sudo apt install php-zts-devel
sudo pie install asgrim/example-pie-extension --with-php-config=php-config-zts
```
### Usage
To serve the content of the current directory, run:
```console
@@ -43,6 +80,24 @@ You can also run command-line scripts with:
frankenphp php-cli /path/to/your/script.php
```
### Homebrew
FrankenPHP is also available as a [Homebrew](https://brew.sh) package for macOS and Linux.
To install it:
```console
brew install dunglas/frankenphp/frankenphp
```
To serve the content of the current directory, run:
```console
frankenphp php-server
```
If you need extensions, you will have to install them with [pie](https://github.com/php/pie).
### Docker
Alternatively, [Docker images](https://frankenphp.dev/docs/docker/) are available:
@@ -60,22 +115,6 @@ Go to `https://localhost`, and enjoy!
> Do not attempt to use `https://127.0.0.1`. Use `https://localhost` and accept the self-signed certificate.
> Use the [`SERVER_NAME` environment variable](docs/config.md#environment-variables) to change the domain to use.
### Homebrew
FrankenPHP is also available as a [Homebrew](https://brew.sh) package for macOS and Linux.
To install it:
```console
brew install dunglas/frankenphp/frankenphp
```
To serve the content of the current directory, run:
```console
frankenphp php-server
```
## Docs
- [Classic mode](https://frankenphp.dev/docs/classic/)

View File

@@ -1,119 +0,0 @@
#!/bin/bash
set -o errexit
set -x
# Ensure required tools are installed
if ! command -v rpmbuild &>/dev/null; then
echo "Error: rpm-build is required to create RPM packages."
echo "Install it with: sudo dnf install rpm-build"
exit 1
fi
if ! command -v ruby &>/dev/null; then
echo "Error: Ruby is required by FPM."
echo "Install it with: sudo dnf install ruby"
exit 1
fi
if ! command -v fpm &>/dev/null; then
echo "Error: FPM (rubygem-fpm) is required to create RPM packages."
echo "Install it with: sudo gem install fpm"
exit 1
fi
arch="$(uname -m)"
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
bin="frankenphp-${os}-${arch}"
if [ ! -f "dist/$bin" ]; then
echo "Error: dist/$bin not found. Run './build-static.sh' first"
exit 1
fi
version_output="$(dist/"$bin" version)"
frankenphp_version=$(echo "$version_output" | grep -oP 'FrankenPHP\s+\K[^ ]+' || true)
frankenphp_version=${frankenphp_version#v}
if [[ ! "${frankenphp_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Warning: frankenphp_version must be set to X.Y.Z (e.g. 1.5.1), got '${frankenphp_version}'"
echo "Falling back to non-release version 0.0.0"
frankenphp_version=0.0.0
fi
group_preexists=0
user_preexists=0
if getent group frankenphp >/dev/null; then
group_preexists=1
else
sudo groupadd --system frankenphp
fi
if getent passwd frankenphp >/dev/null; then
user_preexists=1
else
sudo useradd --system \
--gid frankenphp \
--create-home \
--home-dir /var/lib/frankenphp \
--shell /usr/sbin/nologin \
--comment "FrankenPHP web server" \
frankenphp
fi
mkdir -p package/empty
mkdir -p package/etc
[ -f ./dist/static-php-cli/source/php-src/php.ini-production ] && cp -f ./dist/static-php-cli/source/php-src/php.ini-production ./package/etc/php.ini
cd dist
iteration=1
glibc_version=$(ldd -v "$bin" | awk '/GLIBC_/ {gsub(/[()]/, "", $2); print $2}' | grep -v GLIBC_PRIVATE | sort -V | tail -n1)
cxxabi_version=$(strings "$bin" | grep -oP 'CXXABI_\d+\.\d+(\.\d+)?' | sort -V | tail -n1)
fpm -s dir -t rpm -n frankenphp -v "${frankenphp_version}" \
--config-files /etc/frankenphp/Caddyfile \
--config-files /etc/frankenphp/php.ini \
--depends "libc.so.6(${glibc_version})(64bit)" \
--depends "libstdc++.so.6(${cxxabi_version})(64bit)" \
--before-install ../package/rhel/preinstall.sh \
--after-install ../package/rhel/postinstall.sh \
--before-remove ../package/rhel/preuninstall.sh \
--after-remove ../package/rhel/postuninstall.sh \
--iteration "${iteration}" \
--rpm-user frankenphp --rpm-group frankenphp \
"${bin}=/usr/bin/frankenphp" \
"../package/rhel/frankenphp.service=/usr/lib/systemd/system/frankenphp.service" \
"../package/Caddyfile=/etc/frankenphp/Caddyfile" \
"../package/content/=/usr/share/frankenphp" \
"../package/etc/php.ini=/etc/frankenphp/php.ini" \
"../package/empty/=/etc/frankenphp/php.d" \
"../package/empty/=/usr/lib/frankenphp/modules" \
"../package/empty/=/var/lib/frankenphp"
glibc_version=$(ldd -v "$bin" | awk '/GLIBC_/ {gsub(/[()]/, "", $2); print $2}' | grep -v GLIBC_PRIVATE | sed 's/GLIBC_//' | sort -V | tail -n1)
cxxabi_version=$(strings "$bin" | grep -oP 'CXXABI_\d+\.\d+(\.\d+)?' | sed 's/CXXABI_//' | sort -V | tail -n1)
fpm -s dir -t deb -n frankenphp -v "${frankenphp_version}" \
--config-files /etc/frankenphp/Caddyfile \
--config-files /etc/frankenphp/php.ini \
--depends "libc6 (>= ${glibc_version})" \
--depends "libstdc++6 (>= ${cxxabi_version})" \
--after-install ../package/debian/postinst.sh \
--before-remove ../package/debian/prerm.sh \
--after-remove ../package/debian/postrm.sh \
--iteration "${iteration}" \
--deb-user frankenphp --deb-group frankenphp \
"${bin}=/usr/bin/frankenphp" \
"../package/debian/frankenphp.service=/usr/lib/systemd/system/frankenphp.service" \
"../package/Caddyfile=/etc/frankenphp/Caddyfile" \
"../package/content/=/usr/share/frankenphp" \
"../package/etc/php.ini=/etc/frankenphp/php.ini" \
"../package/empty/=/etc/frankenphp/php.d" \
"../package/empty/=/usr/lib/frankenphp/modules" \
"../package/empty/=/var/lib/frankenphp"
[ "$user_preexists" -eq 0 ] && sudo userdel frankenphp
[ "$group_preexists" -eq 0 ] && (sudo groupdel frankenphp || true)
cd ..

View File

@@ -203,8 +203,9 @@ for pkg in ${SPC_OPT_INSTALL_ARGS}; do
done
# shellcheck disable=SC2086
${spcCommand} download --with-php="${PHP_VERSION}" --for-extensions="${PHP_EXTENSIONS}" --for-libs="${PHP_EXTENSION_LIBS}" ${SPC_OPT_DOWNLOAD_ARGS}
export FRANKENPHP_SOURCE_PATH="${CURRENT_DIR}"
# shellcheck disable=SC2086
FRANKENPHP_SOURCE_DIR=${CURRENT_DIR} ${spcCommand} build --enable-zts --build-embed --build-frankenphp ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}"
${spcCommand} build --enable-zts --build-embed --build-frankenphp ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}"
if [ -n "$CI" ]; then
rm -rf ./downloads

View File

@@ -41,11 +41,9 @@ especially when compiled in ZTS mode (thread-safe), which is required for Franke
Also, [some bugs only happen when using musl](https://github.com/php/php-src/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen+label%3ABug+musl).
In production environments, we recommend using FrankenPHP linked against glibc.
In production environments, we recommend using FrankenPHP linked against glibc, compiled with an appropriate optimization level.
This can be achieved by using the Debian Docker images (the default), downloading the -gnu suffix binary from our [Releases](https://github.com/php/frankenphp/releases), or by [compiling FrankenPHP from sources](compile.md).
Alternatively, we provide static musl binaries compiled with [the mimalloc allocator](https://github.com/microsoft/mimalloc), which alleviates the problems in threaded scenarios.
This can be achieved by using the Debian Docker images, using our maintainers [.deb](https://debs.henderkes.com) or [.rpm](https://rpms.henderkes.com) packages, or by [compiling FrankenPHP from sources](compile.md).
## Go Runtime Configuration

View File

@@ -2,6 +2,11 @@
set -e
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
fi
if [ -z "${BIN_DIR}" ]; then
BIN_DIR=$(pwd)
fi
@@ -13,6 +18,11 @@ OS=$(uname -s)
ARCH=$(uname -m)
GNU=""
if ! command -v curl >/dev/null 2>&1; then
echo "Please install curl to download FrankenPHP"
exit 1
fi
if type "tput" >/dev/null 2>&1; then
bold=$(tput bold || true)
italic=$(tput sitm || true)
@@ -21,6 +31,46 @@ fi
case ${OS} in
Linux*)
if [ "${ARCH}" = "aarch64" ] || [ "${ARCH}" = "x86_64" ]; then
if command -v dnf >/dev/null 2>&1; then
echo "📦 Detected dnf. Installing FrankenPHP from RPM repository..."
if [ -n "${SUDO}" ]; then
echo "❗ Enter your password to grant sudo powers for package installation"
${SUDO} -v || true
fi
${SUDO} dnf -y install https://rpm.henderkes.com/static-php-1-0.noarch.rpm
${SUDO} dnf -y module enable php-zts:static-8.4 || true
${SUDO} dnf -y install frankenphp
echo
echo "🥳 FrankenPHP installed successfully"
echo
echo "⭐ If you like FrankenPHP, please give it a star on GitHub: ${italic}https://github.com/php/frankenphp${normal}"
exit 0
fi
if command -v apt >/dev/null 2>&1 || command -v apt-get >/dev/null 2>&1; then
echo "📦 Detected apt. Installing FrankenPHP from DEB repository..."
if [ -n "${SUDO}" ]; then
echo "❗ Enter your password to grant sudo powers for package installation"
${SUDO} -v || true
fi
${SUDO} sh -c 'curl -fsSL https://key.henderkes.com/static-php.gpg -o /usr/share/keyrings/static-php.gpg'
${SUDO} sh -c 'echo "deb [signed-by=/usr/share/keyrings/static-php.gpg] https://deb.henderkes.com/ stable main" > /etc/apt/sources.list.d/static-php.list'
if command -v apt >/dev/null 2>&1; then
${SUDO} apt update
${SUDO} apt -y install frankenphp
else
${SUDO} apt-get update
${SUDO} apt-get -y install frankenphp
fi
echo
echo "🥳 FrankenPHP installed successfully."
echo
echo "⭐ If you like FrankenPHP, please give it a star on GitHub: ${italic}https://github.com/php/frankenphp${normal}"
exit 0
fi
fi
case ${ARCH} in
aarch64)
THE_ARCH_BIN="frankenphp-linux-aarch64"
@@ -63,8 +113,6 @@ if [ -z "${THE_ARCH_BIN}" ]; then
exit 1
fi
SUDO=""
echo "📦 Downloading ${bold}FrankenPHP${normal} for ${OS}${GNU} (${ARCH}):"
# check if $DEST is writable and suppress an error message
@@ -76,20 +124,20 @@ if [ $? -eq 1 ]; then
SUDO="sudo"
fi
if type "curl" >/dev/null 2>&1; then
curl -L --progress-bar "https://github.com/php/frankenphp/releases/latest/download/${THE_ARCH_BIN}" -o "${DEST}"
elif type "wget" >/dev/null 2>&1; then
${SUDO} wget "https://github.com/php/frankenphp/releases/latest/download/${THE_ARCH_BIN}" -O "${DEST}"
else
echo "❗ Please install ${italic}curl${normal} or ${italic}wget${normal} to download FrankenPHP"
exit 1
fi
curl -L --progress-bar "https://github.com/php/frankenphp/releases/latest/download/${THE_ARCH_BIN}" -o "${DEST}"
${SUDO} chmod +x "${DEST}"
# Allow binding to ports 80/443 without running as root (if setcap is available)
if command -v setcap >/dev/null 2>&1; then
${SUDO} setcap 'cap_net_bind_service=+ep' "${DEST}" || true
else
echo "❗ install setcap (e.g. libcap2-bin) to allow FrankenPHP to bind to ports 80/443 without root:"
echo " sudo setcap 'cap_net_bind_service=+ep' \"${DEST}\""
fi
echo
echo "🥳 FrankenPHP downloaded successfully to ${italic}${DEST}${normal}"
echo "🔧 Move the binary to ${italic}/usr/local/bin/${normal} or another directory in your ${italic}PATH${normal} to use it globally:"
echo " ${bold}sudo mv ${DEST} /usr/local/bin/${normal}"
echo " ${bold}sudo mv ${DEST} /usr/local/bin/${normal}"
echo
echo "⭐ If you like FrankenPHP, please give it a star on GitHub: ${italic}https://github.com/php/frankenphp${normal}"

View File

@@ -6,8 +6,6 @@ FROM centos:7
ARG FRANKENPHP_VERSION=''
ENV FRANKENPHP_VERSION=${FRANKENPHP_VERSION}
ARG BUILD_PACKAGES=''
ARG PHP_VERSION=''
ENV PHP_VERSION=${PHP_VERSION}
@@ -130,29 +128,6 @@ ENV EXTENSION_DIR='/usr/lib/frankenphp/modules'
# not sure if this is needed
ENV COMPOSER_ALLOW_SUPERUSER=1
# install tools to build packages, if requested - needs gcc 10
RUN if [ -n "${BUILD_PACKAGES}" ]; then \
yum install -y \
bzip2 \
libffi-devel \
libyaml \
libyaml-devel \
make \
openssl-devel \
rpm-build \
sudo \
zlib-devel && \
curl -o ruby.tar.gz -fsSL https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.4.tar.gz && \
tar -xzf ruby.tar.gz && \
cd ruby-* && \
./configure --without-baseruby && \
make && \
make install && \
cd .. && \
rm -rf ruby* && \
gem install fpm; \
fi
WORKDIR /go/src/app
COPY go.mod go.sum ./
RUN go mod download