2024-10-09 04:23:56 +09:00
#!/bin/sh
set -e
2025-11-21 14:31:43 +01:00
SUDO = ""
2024-10-09 04:23:56 +09:00
if [ -z " ${ BIN_DIR } " ] ; then
2024-10-08 21:52:56 +02:00
BIN_DIR = $( pwd )
2024-10-09 04:23:56 +09:00
fi
THE_ARCH_BIN = ""
DEST = ${ BIN_DIR } /frankenphp
OS = $( uname -s)
ARCH = $( uname -m)
2025-04-18 14:22:58 +02:00
GNU = ""
2024-10-09 04:23:56 +09:00
2025-11-21 14:31:43 +01:00
if ! command -v curl >/dev/null 2>& 1; then
2026-03-02 15:31:54 +01:00
echo "❗ Please install curl to download FrankenPHP"
2025-11-21 14:31:43 +01:00
exit 1
fi
2024-10-15 18:06:21 +02:00
if type "tput" >/dev/null 2>& 1; then
2024-10-16 14:23:26 +02:00
bold = $( tput bold || true )
italic = $( tput sitm || true )
normal = $( tput sgr0 || true )
2024-10-15 18:06:21 +02:00
fi
2024-10-09 04:23:56 +09:00
case ${ OS } in
2024-10-08 21:52:56 +02:00
Linux*)
2025-11-21 14:31:43 +01:00
if [ " ${ ARCH } " = "aarch64" ] || [ " ${ ARCH } " = "x86_64" ] ; then
if command -v dnf >/dev/null 2>& 1; then
echo "📦 Detected dnf. Installing FrankenPHP from RPM repository..."
2026-02-06 11:11:58 +01:00
if [ " $( id -u) " -ne 0 ] ; then
SUDO = "sudo"
2025-11-21 14:31:43 +01:00
echo "❗ Enter your password to grant sudo powers for package installation"
${ SUDO } -v || true
fi
2026-02-06 11:11:58 +01:00
${ 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
2025-11-21 14:31:43 +01:00
${ SUDO } dnf -y install frankenphp
echo
2025-11-26 14:19:27 +07:00
echo " 🥳 FrankenPHP installed to ${ italic } /usr/bin/frankenphp ${ normal } successfully. "
echo " ❗ The systemd service uses the Caddyfile in ${ italic } /etc/frankenphp/Caddyfile ${ normal } "
echo " ❗ Your php.ini is found in ${ italic } /etc/php-zts/php.ini ${ normal } "
2025-11-21 14:31:43 +01:00
echo
echo " ⭐ If you like FrankenPHP, please give it a star on GitHub: ${ italic } https://github.com/php/frankenphp ${ normal } "
exit 0
fi
2026-02-06 11:11:58 +01:00
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"
2025-11-21 14:31:43 +01:00
echo "❗ Enter your password to grant sudo powers for package installation"
${ SUDO } -v || true
fi
2026-02-06 11:11:58 +01:00
${ 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 } "
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
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"
2025-11-21 14:31:43 +01:00
else
2026-02-06 11:11:58 +01:00
${ SUDO } sh -c " echo \" $REPO_URL \" >> /etc/apk/repositories "
${ SUDO } apk update
echo "Repository added to /etc/apk/repositories"
2025-11-21 14:31:43 +01:00
fi
2026-02-06 11:11:58 +01:00
${ SUDO } apk add frankenphp
2025-11-21 14:31:43 +01:00
echo
2025-11-26 14:19:27 +07:00
echo " 🥳 FrankenPHP installed to ${ italic } /usr/bin/frankenphp ${ normal } successfully. "
2026-02-06 11:11:58 +01:00
echo " ❗ The OpenRC service uses the Caddyfile in ${ italic } /etc/frankenphp/Caddyfile ${ normal } "
2025-11-26 14:19:27 +07:00
echo " ❗ Your php.ini is found in ${ italic } /etc/php-zts/php.ini ${ normal } "
2025-11-21 14:31:43 +01:00
echo
echo " ⭐ If you like FrankenPHP, please give it a star on GitHub: ${ italic } https://github.com/php/frankenphp ${ normal } "
exit 0
fi
fi
2024-10-08 21:52:56 +02:00
case ${ ARCH } in
aarch64)
THE_ARCH_BIN = "frankenphp-linux-aarch64"
; ;
x86_64)
THE_ARCH_BIN = "frankenphp-linux-x86_64"
; ;
*)
THE_ARCH_BIN = ""
; ;
esac
2025-04-18 14:22:58 +02:00
if getconf GNU_LIBC_VERSION >/dev/null 2>& 1; then
THE_ARCH_BIN = " ${ THE_ARCH_BIN } -gnu "
GNU = " (glibc)"
fi
2024-10-08 21:52:56 +02:00
; ;
Darwin*)
case ${ ARCH } in
arm64)
THE_ARCH_BIN = "frankenphp-mac-arm64"
; ;
*)
THE_ARCH_BIN = "frankenphp-mac-x86_64"
; ;
esac
; ;
2026-03-02 15:31:54 +01:00
CYGWIN_NT* | MSYS_NT* | MINGW*)
if ! command -v unzip >/dev/null 2>& 1 && ! command -v powershell.exe >/dev/null 2>& 1; then
echo "❗ Please install unzip or ensure PowerShell is available to extract FrankenPHP"
exit 1
fi
WIN_ASSET = $( curl -s https://api.github.com/repos/php/frankenphp/releases/latest |
grep -o '"name": *"frankenphp-[^"]*-Win32-vs17-x64\.zip"' | head -1 |
sed 's/"name": *"//;s/"//' )
if [ -z " ${ WIN_ASSET } " ] ; then
echo "❗ Could not find a Windows release asset"
echo "❗ Check https://github.com/php/frankenphp/releases for available downloads"
exit 1
fi
echo " 📦 Downloading ${ bold } FrankenPHP ${ normal } for Windows (x64): "
TMPZIP = " /tmp/frankenphp-windows- $$ .zip "
curl -L --progress-bar " https://github.com/php/frankenphp/releases/latest/download/ ${ WIN_ASSET } " -o " ${ TMPZIP } "
echo " 📂 Extracting to ${ italic } ${ BIN_DIR } ${ normal } ... "
if command -v unzip >/dev/null 2>& 1; then
unzip -o -q " ${ TMPZIP } " -d " ${ BIN_DIR } "
else
powershell.exe -Command " Expand-Archive -Force -Path ' $( cygpath -w " ${ TMPZIP } " ) ' -DestinationPath ' $( cygpath -w " ${ BIN_DIR } " ) ' "
fi
rm -f " ${ TMPZIP } "
echo
echo " 🥳 FrankenPHP downloaded successfully to ${ italic } ${ BIN_DIR } ${ normal } "
echo " 🔧 Add ${ italic } $( cygpath -w " ${ BIN_DIR } " ) ${ normal } to your Windows PATH to use ${ italic } frankenphp.exe ${ normal } globally. "
echo
echo " ⭐ If you like FrankenPHP, please give it a star on GitHub: ${ italic } https://github.com/php/frankenphp ${ normal } "
exit 0
2024-10-08 21:52:56 +02:00
; ;
*)
THE_ARCH_BIN = ""
; ;
2024-10-09 04:23:56 +09:00
esac
if [ -z " ${ THE_ARCH_BIN } " ] ; then
2025-10-29 19:25:51 +01:00
echo " ❗ Precompiled binaries are not available for ${ ARCH } - ${ OS } "
echo "❗ You can compile from sources by following the documentation at: https://frankenphp.dev/docs/compile/"
2024-10-08 21:52:56 +02:00
exit 1
2024-10-09 04:23:56 +09:00
fi
2025-04-18 14:22:58 +02:00
echo " 📦 Downloading ${ bold } FrankenPHP ${ normal } for ${ OS } ${ GNU } ( ${ ARCH } ): "
2024-10-15 18:06:21 +02:00
2024-10-09 04:23:56 +09:00
# check if $DEST is writable and suppress an error message
touch " ${ DEST } " 2>/dev/null
# we need sudo powers to write to DEST
if [ $? -eq 1 ] ; then
2024-10-15 18:06:21 +02:00
echo " ❗ You do not have permission to write to ${ italic } ${ DEST } ${ normal } , enter your password to grant sudo powers "
2024-10-08 21:52:56 +02:00
SUDO = "sudo"
2024-10-09 04:23:56 +09:00
fi
2025-11-21 14:31:43 +01:00
curl -L --progress-bar " https://github.com/php/frankenphp/releases/latest/download/ ${ THE_ARCH_BIN } " -o " ${ DEST } "
2024-10-09 04:23:56 +09:00
${ SUDO } chmod +x " ${ DEST } "
2025-11-21 14:31:43 +01:00
# 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
2025-11-26 14:19:27 +07:00
echo "❗ install setcap (e.g. libcap2-bin) to allow FrankenPHP to bind to ports 80/443 without root:"
echo " ${ bold } sudo setcap 'cap_net_bind_service=+ep' \" ${ DEST } \" ${ normal } "
2025-11-21 14:31:43 +01:00
fi
2024-10-09 04:23:56 +09:00
2024-10-15 18:06:21 +02:00
echo
echo " 🥳 FrankenPHP downloaded successfully to ${ italic } ${ DEST } ${ normal } "
2025-11-26 14:19:27 +07:00
echo " ❗ It uses ${ italic } /etc/frankenphp/php.ini ${ normal } if found. "
case " : $PATH : " in
*" : $DEST : " *) ; ;
*)
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 } "
; ;
esac
2024-10-15 18:06:21 +02:00
echo
2025-07-01 16:29:55 +08:00
echo " ⭐ If you like FrankenPHP, please give it a star on GitHub: ${ italic } https://github.com/php/frankenphp ${ normal } "