Add apk repository, update debian repository instructions (#2099)

closes https://github.com/php/frankenphp/pull/1753
closes https://github.com/php/frankenphp/issues/2156

As per discussion here
https://github.com/php/frankenphp/discussions/2060#discussioncomment-15299936
I went ahead with different repos for different php versions. Versioned
support with stuff like `apt install frankenphp8.5` or `apk add
frankenphp85` are technically also ready, but I'm not running any CI for
that yet. I don't think it's worth it at this point as it would double
the amount of runs.

The old debian repository with only 8.4 is deprecated but will receive
updates for a few more months.
Every update/installation will print this notice, though, which will
hopefully make everyone aware:

```console
# running update from 8.4.15...
Unpacking php-zts-cli (8.4.16-1) ...
Setting up php-zts-cli (8.4.16-1) ...

================================================================================
                          ⚠️  DEPRECATION NOTICE
================================================================================

The single-version php-zts repository is deprecated and will no longer receive updates.

Please migrate to the new repository with different PHP versions available.

More information: https://pkgs.henderkes.com

================================================================================
```

Updated the installer to version 8.5.
This commit is contained in:
Marc
2026-02-06 11:11:58 +01:00
committed by GitHub
parent fba79a6ac8
commit e3da54d15f
11 changed files with 207 additions and 43 deletions

View File

@@ -60,8 +60,9 @@ sudo pie-zts install asgrim/example-pie-extension
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 && \
VERSION=85 # 82-85 available
sudo curl https://pkg.henderkes.com/api/packages/${VERSION}/debian/repository.key -o /etc/apt/keyrings/static-php${VERSION}.asc
echo "deb [signed-by=/etc/apt/keyrings/static-php${VERSION}.asc] https://pkg.henderkes.com/api/packages/${VERSION}/debian php-zts main" | sudo tee -a /etc/apt/sources.list.d/static-php${VERSION}.list
sudo apt update
sudo apt install frankenphp
```
@@ -75,6 +76,28 @@ sudo apt install pie-zts
sudo pie-zts install asgrim/example-pie-extension
```
### apk Packages
Our maintainers offer apk packages for all systems using `apk`. To install, run:
```console
VERSION=85 # 82-85 available
echo "https://pkg.henderkes.com/api/packages/${VERSION}/alpine/main/php-zts" | sudo tee -a /etc/apk/repositories
KEYFILE=$(curl -sJOw '%{filename_effective}' https://pkg.henderkes.com/api/packages/${VERSION}/alpine/key)
sudo mv ${KEYFILE} /etc/apk/keys/ &&
sudo apk update &&
sudo apk add frankenphp
```
**Installing extensions:** `sudo apk add php-zts-<extension>`
For extensions not available by default, use [PIE](https://github.com/php/pie):
```console
sudo apk add pie-zts
sudo pie-zts install asgrim/example-pie-extension
```
### Homebrew
FrankenPHP is also available as a [Homebrew](https://brew.sh) package for macOS and Linux.

View File

@@ -7,7 +7,7 @@ However, it is possible to substantially improve performance using an appropriat
By default, FrankenPHP starts 2 times more threads and workers (in worker mode) than the available numbers of CPU.
The appropriate values depend heavily on how your application is written, what it does and your hardware.
The appropriate values depend heavily on how your application is written, what it does, and your hardware.
We strongly recommend changing these values. For best system stability, it is recommended to have `num_threads` x `memory_limit` < `available_memory`.
To find the right values, it's best to run load tests simulating real traffic.
@@ -43,7 +43,7 @@ Also, [some bugs only happen when using musl](https://github.com/php/php-src/iss
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, using our maintainers [.deb](https://debs.henderkes.com) or [.rpm](https://rpms.henderkes.com) packages, or by [compiling FrankenPHP from sources](compile.md).
This can be achieved by using the Debian Docker images, using [our maintainers .deb, .rpm, or .apk packages](https://pkgs.henderkes.com), or by [compiling FrankenPHP from sources](compile.md).
## Go Runtime Configuration
@@ -146,7 +146,7 @@ All usual PHP-related performance optimizations apply with FrankenPHP.
In particular:
- check that [OPcache](https://www.php.net/manual/en/book.opcache.php) is installed, enabled and properly configured
- check that [OPcache](https://www.php.net/manual/en/book.opcache.php) is installed, enabled, and properly configured
- enable [Composer autoloader optimizations](https://getcomposer.org/doc/articles/autoloader-optimization.md)
- ensure that the `realpath` cache is big enough for the needs of your application
- use [preloading](https://www.php.net/manual/en/opcache.preloading.php)

View File

@@ -3,9 +3,6 @@
set -e
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
fi
if [ -z "${BIN_DIR}" ]; then
BIN_DIR=$(pwd)
@@ -34,12 +31,13 @@ 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
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
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 https://rpm.henderkes.com/static-php-1-1.noarch.rpm
${SUDO} dnf -y module enable php-zts:static-8.5 || true
${SUDO} dnf -y install frankenphp
echo
echo "🥳 FrankenPHP installed to ${italic}/usr/bin/frankenphp${normal} successfully."
@@ -50,21 +48,17 @@ Linux*)
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
if command -v apt-get >/dev/null 2>&1; then
echo "📦 Detected apt-get. Installing FrankenPHP from DEB repository..."
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
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
${SUDO} sh -c 'curl -fsSL https://pkg.henderkes.com/api/packages/85/debian/repository.key -o /etc/apt/keyrings/static-php85.asc'
${SUDO} sh -c 'echo "deb [signed-by=/etc/apt/keyrings/static-php85.asc] https://pkg.henderkes.com/api/packages/85/debian php-zts main" | sudo tee -a /etc/apt/sources.list.d/static-php85.list'
${SUDO} apt-get update
${SUDO} apt-get -y install frankenphp
echo
echo "🥳 FrankenPHP installed to ${italic}/usr/bin/frankenphp${normal} successfully."
echo "❗ The systemd service uses the Caddyfile in ${italic}/etc/frankenphp/Caddyfile${normal}"
@@ -73,6 +67,36 @@ Linux*)
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 apk >/dev/null 2>&1; then
echo "📦 Detected apk. Installing FrankenPHP from APK repository..."
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
echo "❗ Enter your password to grant sudo powers for package installation"
${SUDO} -v || true
fi
KEY_URL="https://pkg.henderkes.com/api/packages/85/alpine/key"
${SUDO} sh -c "cd /etc/apk/keys && curl -JOsS \"$KEY_URL\" 2>/dev/null || true"
REPO_URL="https://pkg.henderkes.com/api/packages/85/alpine/main/php-zts"
if grep -q "$REPO_URL" /etc/apk/repositories 2>/dev/null; then
echo "Repository already exists in /etc/apk/repositories"
else
${SUDO} sh -c "echo \"$REPO_URL\" >> /etc/apk/repositories"
${SUDO} apk update
echo "Repository added to /etc/apk/repositories"
fi
${SUDO} apk add frankenphp
echo
echo "🥳 FrankenPHP installed to ${italic}/usr/bin/frankenphp${normal} successfully."
echo "❗ The OpenRC service uses the Caddyfile in ${italic}/etc/frankenphp/Caddyfile${normal}"
echo "❗ Your php.ini is found in ${italic}/etc/php-zts/php.ini${normal}"
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

View File

@@ -0,0 +1,29 @@
#!/sbin/openrc-run
name="FrankenPHP"
description="The modern PHP app server"
command="/usr/bin/frankenphp"
command_args="run --environ --config /etc/frankenphp/Caddyfile"
command_user="frankenphp:frankenphp"
command_background="yes"
capabilities="^cap_net_bind_service"
pidfile="/run/frankenphp/frankenphp.pid"
start_stop_daemon_args="--chdir /var/lib/frankenphp"
depend() {
need net
after firewall
}
start_pre() {
checkpath --directory --owner frankenphp:frankenphp --mode 0755 /run/frankenphp
$command validate --config /etc/frankenphp/Caddyfile
}
reload() {
ebegin "Reloading $name configuration"
$command reload --config /etc/frankenphp/Caddyfile --force
eend $?
}

View File

@@ -0,0 +1,13 @@
#!/bin/sh
if getent passwd frankenphp >/dev/null; then
deluser frankenphp
fi
if getent group frankenphp >/dev/null; then
delgroup frankenphp
fi
rmdir /var/lib/frankenphp 2>/dev/null || true
exit 0

43
package/alpine/post-install.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/sh
if ! getent group frankenphp >/dev/null; then
addgroup -S frankenphp
fi
if ! getent passwd frankenphp >/dev/null; then
adduser -S -h /var/lib/frankenphp -s /sbin/nologin -G frankenphp -g "FrankenPHP web server" frankenphp
fi
chown -R frankenphp:frankenphp /var/lib/frankenphp
chmod 755 /var/lib/frankenphp
# allow binding to privileged ports
if command -v setcap >/dev/null 2>&1; then
setcap cap_net_bind_service=+ep /usr/bin/frankenphp || true
fi
# check if 0.0.0.0:2019 or 127.0.0.1:2019 are in use
port_in_use() {
port_hex=$(printf '%04X' "$1")
grep -qE "(00000000|0100007F):${port_hex}" /proc/net/tcp 2>/dev/null
}
# trust frankenphp certificates if the admin api can start
if [ -x /usr/bin/frankenphp ]; then
if ! port_in_use 2019; then
HOME=/var/lib/frankenphp /usr/bin/frankenphp run >/dev/null 2>&1 &
FRANKENPHP_PID=$!
sleep 2
HOME=/var/lib/frankenphp /usr/bin/frankenphp trust || true
kill -TERM $FRANKENPHP_PID 2>/dev/null || true
chown -R frankenphp:frankenphp /var/lib/frankenphp
fi
fi
if command -v rc-update >/dev/null 2>&1; then
rc-update add frankenphp default
rc-service frankenphp start
fi
exit 0

11
package/alpine/pre-deinstall.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
if command -v rc-service >/dev/null 2>&1; then
rc-service frankenphp stop || true
fi
if command -v rc-update >/dev/null 2>&1; then
rc-update del frankenphp default || true
fi
exit 0

View File

@@ -1,5 +1,5 @@
[Unit]
Description=FrankenPHP
Description=FrankenPHP - The modern PHP app server
Documentation=https://frankenphp.dev/docs/
After=network.target network-online.target
Requires=network-online.target
@@ -8,12 +8,15 @@ Requires=network-online.target
Type=notify
User=frankenphp
Group=frankenphp
ExecStartPre=/usr/bin/frankenphp validate --config /etc/frankenphp/Caddyfile
ExecStart=/usr/bin/frankenphp run --environ --config /etc/frankenphp/Caddyfile
ExecReload=/usr/bin/frankenphp reload --config /etc/frankenphp/Caddyfile --force
ExecReload=/usr/bin/frankenphp reload --config /etc/frankenphp/Caddyfile
WorkingDirectory=/var/lib/frankenphp
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

View File

@@ -19,17 +19,29 @@ if [ "$1" = "configure" ]; then
usermod -aG www-data frankenphp
fi
# trust frankenphp certificates before starting the systemd service
if [ -z "$2" ] && [ -x /usr/bin/frankenphp ]; then
HOME=/var/lib/frankenphp /usr/bin/frankenphp run --config /dev/null &
FRANKENPHP_PID=$!
sleep 2
HOME=/var/lib/frankenphp /usr/bin/frankenphp trust || true
kill "$FRANKENPHP_PID" || true
wait "$FRANKENPHP_PID" 2>/dev/null || true
chown -R frankenphp:frankenphp /var/lib/frankenphp
fi
# Handle cases where package was installed and then purged;
# user and group will still exist but with no home dir
if [ ! -d /var/lib/frankenphp ]; then
mkdir -p /var/lib/frankenphp
chown frankenphp:frankenphp /var/lib/frankenphp
chown -R frankenphp:frankenphp /var/lib/frankenphp
fi
# Add log directory with correct permissions
if [ ! -d /var/log/frankenphp ]; then
mkdir -p /var/log/frankenphp
chown frankenphp:frankenphp /var/log/frankenphp
chown -R frankenphp:frankenphp /var/log/frankenphp
fi
fi
@@ -61,11 +73,3 @@ fi
if command -v setcap >/dev/null 2>&1; then
setcap cap_net_bind_service=+ep /usr/bin/frankenphp || true
fi
if [ -x /usr/bin/frankenphp ]; then
HOME=/var/lib/frankenphp /usr/bin/frankenphp run --config /dev/null &
FRANKENPHP_PID=$!
HOME=/var/lib/frankenphp /usr/bin/frankenphp trust || true
kill "$FRANKENPHP_PID" || true
wait "$FRANKENPHP_PID" 2>/dev/null || true
fi

View File

@@ -1,6 +1,8 @@
[Unit]
Description=FrankenPHP server
After=network.target
Description=FrankenPHP - The modern PHP app server
Documentation=https://frankenphp.dev/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify

View File

@@ -32,10 +32,22 @@ if command -v setcap >/dev/null 2>&1; then
setcap cap_net_bind_service=+ep /usr/bin/frankenphp || :
fi
if [ -x /usr/bin/frankenphp ]; then
HOME=/var/lib/frankenphp /usr/bin/frankenphp run --config /dev/null &
FRANKENPHP_PID=$!
HOME=/var/lib/frankenphp /usr/bin/frankenphp trust || :
kill "$FRANKENPHP_PID" || :
wait "$FRANKENPHP_PID" 2>/dev/null || :
# check if 0.0.0.0:2019 or 127.0.0.1:2019 are in use
port_in_use() {
port_hex=$(printf '%04X' "$1")
grep -qE "(00000000|0100007F):${port_hex}" /proc/net/tcp 2>/dev/null
}
# trust frankenphp certificates if the admin api can start
if [ "$1" -eq 1 ] && [ -x /usr/bin/frankenphp ]; then
if ! port_in_use 2019; then
HOME=/var/lib/frankenphp /usr/bin/frankenphp run --config /dev/null &
FRANKENPHP_PID=$!
sleep 2
HOME=/var/lib/frankenphp /usr/bin/frankenphp trust || :
kill "$FRANKENPHP_PID" || :
wait "$FRANKENPHP_PID" 2>/dev/null || :
chown -R frankenphp:frankenphp /var/lib/frankenphp
fi
fi