Back to Koel

Running with FrankenPHP

docs/guide/running-with-frankenphp.md

9.3.54.0 KB
Original Source

Running with FrankenPHP

FrankenPHP is a PHP application server that packages a webserver (Caddy) and the PHP runtime into a single binary, with automatic HTTPS. Koel ships a Caddyfile.example at the project root to use with it.

::: tip Want a one-download install instead? The Standalone Binary distribution from koel/franken packages FrankenPHP, Koel, and a launcher into a single archive. This page is for installing FrankenPHP yourself as the runtime for an existing Koel install. :::

FrankenPHP is only the runtime. Install Koel first via Pre-Compiled Archive or Building from Source, then use FrankenPHP as the webserver.

Install FrankenPHP

Pre-built binaries are published at frankenphp.dev/docs/#install. On Linux, the one-line installer fetches the right binary for your architecture:

bash
curl https://frankenphp.dev/install.sh | sh
sudo mv frankenphp /usr/local/bin/

Configure the Caddyfile

From the Koel project root:

bash
cp Caddyfile.example Caddyfile

Edit Caddyfile and replace localhost with the domain you'll serve from. Using a real public domain enables automatic HTTPS via Let's Encrypt.

Run it

bash
frankenphp run

That's it — Koel is now served on port 443 (and 80, redirected to HTTPS).

Running artisan commands

FrankenPHP ships its own PHP, available via the php-cli subcommand. Any php artisan … from Koel's CLI documentation becomes:

bash
frankenphp php-cli artisan <command>

For example, frankenphp php-cli artisan migrate runs database migrations and frankenphp php-cli artisan koel:sync triggers a media scan. For convenience: alias artisan='frankenphp php-cli artisan'.

If you also have system PHP installed (e.g. for composer install), running php artisan <command> against it works the same — both share the same .env and database.

::: warning DB_HOST=localhost gotcha If your .env has DB_HOST=localhost with MySQL, FrankenPHP's PHP will fail to find the MySQL socket and you'll see Checking database connection … ERROR when running koel:init, even though HTTP serving works fine. Fix it one of two ways:

  • Override per-command: DB_HOST=127.0.0.1 frankenphp php-cli artisan <command>
  • Or change .env to DB_HOST=127.0.0.1. :::

For FrankenPHP CLI options not covered here (worker mode, multi-domain serving, custom PHP flags, etc.), refer to the official FrankenPHP documentation.

Run as a systemd service (Ubuntu)

For a production deployment, run FrankenPHP under systemd so it starts on boot and restarts on failure. Create /etc/systemd/system/koel.service:

ini
[Unit]
Description=Koel (FrankenPHP)
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/koel
ExecStart=/usr/local/bin/frankenphp run
Restart=on-failure
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Adjust WorkingDirectory and User to match where Koel lives on your host. Then enable and start it:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now koel
sudo journalctl -u koel -f

Behind a reverse proxy

If you're already running nginx (or another reverse proxy) and want to use FrankenPHP only as the PHP runtime, make two changes to your Caddyfile:

  1. Uncomment the auto_https off and servers { trusted_proxies … } block at the top — Caddyfile.example ships it commented and ready for this case. Adjust the trusted-proxies CIDR if the reverse proxy lives on a different host.
  2. Bind the site block to a local port — change localhost { to :8001 { and add bind 127.0.0.1 as the first line inside the block. Everything else inside the site block stays as-is.

Then point your existing reverse proxy at 127.0.0.1:8001 and let it terminate TLS as before.