dotlinux blog

How to Install FrankenPHP App Server in Ubuntu 24.04

FrankenPHP is a modern, high-performance app server for PHP built on top of Caddy, a powerful web server with native HTTP/2, HTTP/3, and QUIC support. It combines the speed of Caddy with its own PHP SAPI (replacing PHP-FPM), making it an excellent choice for hosting PHP applications with improved performance, security, and scalability.

Whether you're running a small blog, a complex e-commerce platform, or a microservice, FrankenPHP simplifies deployment with features like automatic TLS (Let's Encrypt), worker mode for up to 3.5x faster request handling, and seamless integration with PHP frameworks (e.g., Laravel, Symfony, WordPress).

In this guide, we'll walk through three methods to install FrankenPHP on Ubuntu 24.04: via the official install script (recommended for most users), via native deb packages, and via Docker (for containerized environments). We'll also cover verifying the installation, running a demo PHP app, and setting up a systemd service for auto-start.

Last Updated: 2026-03

Table of Contents#

  1. Prerequisites
  2. Method 1: Install FrankenPHP via the Install Script
  3. Method 2: Install FrankenPHP via deb Packages
  4. Method 3: Install FrankenPHP via Docker
  5. Running a Demo PHP Application
  6. Setting Up FrankenPHP as a Systemd Service
  7. Troubleshooting Common Issues
  8. Conclusion
  9. References

Prerequisites#

Before starting, ensure your system meets the following requirements:

  • Ubuntu 24.04 LTS (verify with lsb_release -a).
  • A user account with sudo privileges.
  • Internet access to download packages and binaries.
  • For the binary method: curl (usually preinstalled).
  • For the Docker method: Docker Engine (we'll install this in Step 1 of Method 3).

Method 1: Install FrankenPHP via the Install Script#

This method is recommended for most users. The official install script downloads a statically linked binary that contains PHP 8.5 and requires no external dependencies.

Step 1: Update System Packages#

First, update your system's package index to ensure you have the latest versions of existing packages:

sudo apt update && sudo apt upgrade -y

Step 2: Run the Install Script#

Download and run the official FrankenPHP install script:

curl https://frankenphp.dev/install.sh | sh

This downloads the latest FrankenPHP binary for your platform. The Linux binary is statically linked and includes PHP 8.5 with most popular PHP extensions.

Move the binary to a directory in your system PATH for easy access:

sudo mv frankenphp /usr/local/bin/

Step 3: Verify Installation#

To confirm FrankenPHP is installed correctly, run:

frankenphp --version

You should see output similar to:

frankenphp v1.12.4 (caddy 2.11.4, php 8.5.x)

If you see this, the installation is successful!

Method 2: Install FrankenPHP via deb Packages#

FrankenPHP provides native deb packages for Debian-based systems like Ubuntu. This method installs FrankenPHP as a system service with automatic updates via apt.

First, add the FrankenPHP package repository:

VERSION=85 # PHP version: 82, 83, 84, or 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

After installation, you can start the service immediately:

sudo systemctl start frankenphp
sudo systemctl status frankenphp

To install additional PHP extensions:

sudo apt install php-zts-<extension>

For extensions not available by default, use PIE:

sudo apt install pie-zts
sudo pie-zts install <extension-package>

Method 3: Install FrankenPHP via Docker#

If you prefer containerized deployments, use the official FrankenPHP Docker image.

Step 1: Install Docker on Ubuntu 24.04#

If Docker isn't already installed, follow these steps:

# Add Docker GPG key
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
 
# Add Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
 
# Install Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
# Verify Docker installation
sudo docker --version

You should see output like Docker version 27.x.x, build xxxxxxx.

Step 2: Pull the FrankenPHP Docker Image#

The official FrankenPHP image is hosted on Docker Hub. Pull the latest version:

sudo docker pull dunglas/frankenphp:latest

Docker images are available for PHP 8.2, 8.3, 8.4, and 8.5. To pull a specific PHP version:

sudo docker pull dunglas/frankenphp:latest-php8.5

To check the image, run:

sudo docker images | grep frankenphp

Step 3: Run FrankenPHP in a Container#

Start a FrankenPHP container with PHP enabled. For example, to serve a PHP app from your local directory:

# Replace /path/to/your/php/app with the path to your PHP project
sudo docker run -p 80:80 -p 443:443 -p 443:443/udp \
  -v /path/to/your/php/app:/app/public \
  dunglas/frankenphp:latest
  • -p 80:80: Maps HTTP port 80 on your host to the container.
  • -p 443:443: Maps HTTPS port 443 on your host to the container.
  • -p 443:443/udp: Enables HTTP/3 via UDP.
  • -v /path/to/your/php/app:/app/public: Mounts your local PHP app directory to /app/public in the container.

Tip: 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 to change the domain.

Running a Demo PHP Application#

Let's test FrankenPHP with a simple "Hello World" PHP app.

Option 1: With the Binary Installation#

  1. Create a project directory and an index.php file:

    mkdir -p ~/frankenphp-demo
    cd ~/frankenphp-demo
    echo '<?php echo "Hello, FrankenPHP!"; ?>' > index.php
  2. Start FrankenPHP to serve the current directory:

    frankenphp php-server
  3. Open a browser and navigate to http://localhost. You should see:

    Hello, FrankenPHP!
    

Option 2: With the Docker Installation#

  1. Create a local directory for your app:

    mkdir -p ~/frankenphp-demo-docker
    cd ~/frankenphp-demo-docker
    echo '<?php echo "Hello, FrankenPHP (Docker)!"; ?>' > index.php
  2. Run the Docker container, mounting your local directory:

    sudo docker run -p 80:80 -p 443:443 \
      -v $(pwd):/app/public \
      dunglas/frankenphp:latest
  3. Visit https://localhost in your browser (accept the self-signed certificate). You'll see:

    Hello, FrankenPHP (Docker)!
    

Setting Up FrankenPHP as a Systemd Service#

To ensure FrankenPHP starts automatically on system boot (recommended for production), create a systemd service file.

Note: If you installed FrankenPHP via the deb package (Method 2), a systemd service is already included. You can skip this section and use sudo systemctl start frankenphp directly.

Step 1: Create a Systemd Service File#

Create a new service file at /etc/systemd/system/frankenphp.service:

sudo nano /etc/systemd/system/frankenphp.service

Paste the following content (adjust paths and user as needed):

[Unit]
Description=FrankenPHP App Server
After=network.target
 
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/your-app
ExecStart=/usr/local/bin/frankenphp php-server
Restart=always
RestartSec=3
 
[Install]
WantedBy=multi-user.target

Step 2: Reload Systemd and Start the Service#

sudo systemctl daemon-reload
sudo systemctl enable frankenphp  # Auto-start on boot
sudo systemctl start frankenphp

Check the service status:

sudo systemctl status frankenphp

You should see active (running) in the output.

Troubleshooting Common Issues#

  • Port 80 or 443 is already in use: Stop the conflicting service (e.g., sudo systemctl stop nginx) or use a different port with frankenphp php-server -p 8080.
  • Permission errors: Ensure the www-data user has read access to your PHP app directory:
    sudo chown -R www-data:www-data /path/to/your/php/app
    sudo chmod -R 755 /path/to/your/php/app
  • Docker container not starting: Check logs with sudo docker logs <container-id>.
  • HTTPS certificate warnings: When accessing https://localhost in Docker, accept the self-signed certificate. Do not use https://127.0.0.1.
  • Worker mode issues: Refer to the official worker mode documentation for configuration details.

Conclusion#

FrankenPHP is a powerful, modern app server that simplifies PHP deployment with built-in features like HTTP/3, automatic TLS, and worker mode. In this guide, we covered three installation methods (install script, deb packages, and Docker), verified the setup, ran a demo app, and configured auto-start with systemd.

Whether you're building a small site or a large application, FrankenPHP's performance and ease of use make it a compelling alternative to traditional PHP-FPM setups. For advanced configuration, refer to the official FrankenPHP documentation.

References#