Skip to content

Commit 26d07be

Browse files
committed
docs: add SEO frontmatter, llms.txt, and code-block hygiene
Add YAML frontmatter (title, description) to every English doc under docs/*.md, rename generic headings (## Setup, ## Configuration, etc.) to topic-specific ones, fix code-block language tags where wrong, and add filename or purpose comments on blocks that represent a real file. Add a root llms.txt index pointing AI agents at the canonical English docs (Core Concepts, Setup and Build, Worker Mode and Extensions, Frameworks, Real-Time and Performance, Production and Observability). Translations under docs/<lang>/ are intentionally left untouched and should be regenerated by running docs/translate.php.
1 parent 2ac6c41 commit 26d07be

26 files changed

Lines changed: 333 additions & 81 deletions

docs/classic.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: FrankenPHP Classic Mode: Drop-in PHP-FPM Replacement
3+
description: Run FrankenPHP in classic mode as a drop-in replacement for PHP-FPM or Apache mod_php, with a fixed or autoscaling thread pool serving PHP files directly.
4+
---
5+
16
# Using Classic Mode
27

38
Without any additional configuration, FrankenPHP operates in classic mode. In this mode, FrankenPHP functions like a traditional PHP server, directly serving PHP files. This makes it a seamless drop-in replacement for PHP-FPM or Apache with mod_php.

docs/compile.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: Compile FrankenPHP From Sources With PHP as a Library
3+
description: Build FrankenPHP from source on Linux, macOS and FreeBSD, link PHP as a dynamic library via xcaddy or go build, and add custom Caddy modules and extensions.
4+
---
5+
16
# Compile From Sources
27

38
This document explains how to create a FrankenPHP binary that will load PHP as a dynamic library.
@@ -36,7 +41,7 @@ cd php-*/
3641
Then, run the `configure` script with the options needed for your platform.
3742
The following `./configure` flags are mandatory, but you can add others, for example, to compile extensions or additional features.
3843

39-
#### Linux
44+
#### Linux and FreeBSD
4045

4146
```console
4247
./configure \

docs/config.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: Configuring FrankenPHP With Caddyfile, php.ini, and Env Vars
3+
description: Configure FrankenPHP and Caddy via Caddyfile, JSON, or environment variables, including PHP runtime tuning, worker mode, file watching, and module options.
4+
---
5+
16
# Configuration
27

38
FrankenPHP, Caddy as well as the [Mercure](mercure.md) and [Vulcain](https://vulcain.rocks) modules can be configured using [the formats supported by Caddy](https://caddyserver.com/docs/getting-started#your-first-config).
@@ -9,6 +14,7 @@ You can specify a custom path with the `-c` or `--config` option.
914
A minimal `Caddyfile` to serve a PHP application is shown below:
1015

1116
```caddyfile
17+
# Caddyfile
1218
# The hostname to respond to
1319
localhost
1420
@@ -39,6 +45,7 @@ PHP:
3945
- You should copy an official template provided by the PHP project:
4046

4147
```dockerfile
48+
# Dockerfile
4249
FROM dunglas/frankenphp
4350

4451
# Production:
@@ -80,6 +87,7 @@ The `php_server` or the `php` [HTTP directives](https://caddyserver.com/docs/cad
8087
Minimal example:
8188

8289
```caddyfile
90+
# Caddyfile
8391
localhost {
8492
# Enable compression (optional)
8593
encode zstd br gzip
@@ -91,6 +99,7 @@ localhost {
9199
You can also explicitly configure FrankenPHP using the [global option](https://caddyserver.com/docs/caddyfile/concepts#global-options) `frankenphp`:
92100

93101
```caddyfile
102+
# Caddyfile
94103
{
95104
frankenphp {
96105
num_threads <num_threads> # Sets the number of PHP threads to start. Default: 2x the number of available CPUs.
@@ -116,6 +125,7 @@ You can also explicitly configure FrankenPHP using the [global option](https://c
116125
Alternatively, you may use the one-line short form of the `worker` option:
117126

118127
```caddyfile
128+
# Caddyfile
119129
{
120130
frankenphp {
121131
worker <file> <num>
@@ -128,6 +138,7 @@ Alternatively, you may use the one-line short form of the `worker` option:
128138
You can also define multiple workers if you serve multiple apps on the same server:
129139

130140
```caddyfile
141+
# Caddyfile
131142
app.example.com {
132143
root /path/to/app/public
133144
php_server {
@@ -155,6 +166,7 @@ it's a PHP file or not. Read more about it in the [performance page](performance
155166
Using the `php_server` directive is equivalent to this configuration:
156167

157168
```caddyfile
169+
# Caddyfile
158170
route {
159171
# Add trailing slash for directory requests
160172
@canonicalPath {
@@ -178,6 +190,7 @@ route {
178190
The `php_server` and the `php` directives have the following options:
179191

180192
```caddyfile
193+
# Caddyfile
181194
php_server [<matcher>] {
182195
root <directory> # Sets the root folder to the site. Default: `root` directive.
183196
split_path <delim...> # Sets the substrings for splitting the URI into two parts. The first matching substring will be used to split the "path info" from the path. The first piece is suffixed with the matching substring and will be assumed as the actual resource (CGI script) name. The second piece will be set to PATH_INFO for the script to use. Default: `.php`
@@ -205,6 +218,7 @@ Workers can instead be restarted on file changes via the `watch` directive.
205218
This is useful for development environments.
206219

207220
```caddyfile
221+
# Caddyfile
208222
{
209223
frankenphp {
210224
worker {
@@ -223,6 +237,7 @@ where the FrankenPHP process was started. You can instead also specify one or mo
223237
[shell filename pattern](https://pkg.go.dev/path/filepath#Match):
224238

225239
```caddyfile
240+
# Caddyfile
226241
{
227242
frankenphp {
228243
worker {
@@ -254,6 +269,7 @@ The following example will always serve a file in the public directory if presen
254269
and otherwise forward the request to the worker matching the path pattern.
255270

256271
```caddyfile
272+
# Caddyfile
257273
{
258274
frankenphp {
259275
php_server {
@@ -278,14 +294,15 @@ But when the fix depends on a third party you don't control,
278294
`max_requests` provides a pragmatic and hopefully temporary workaround for production:
279295

280296
```caddyfile
297+
# Caddyfile
281298
{
282299
frankenphp {
283300
max_requests 500
284301
}
285302
}
286303
```
287304

288-
## Environment Variables
305+
## FrankenPHP Environment Variables
289306

290307
The following environment variables can be used to inject Caddy directives in the `Caddyfile` without modifying it:
291308

@@ -298,7 +315,7 @@ As for FPM and CLI SAPIs, environment variables are exposed by default in the `$
298315

299316
The `S` value of [the `variables_order` PHP directive](https://www.php.net/manual/en/ini.core.php#ini.variables-order) is always equivalent to `ES` regardless of the placement of `E` elsewhere in this directive.
300317

301-
## PHP config
318+
## PHP Configuration in FrankenPHP
302319

303320
To load [additional PHP configuration files](https://www.php.net/manual/en/configuration.file.php#configuration.file.scan),
304321
the `PHP_INI_SCAN_DIR` environment variable can be used.
@@ -307,6 +324,7 @@ When set, PHP will load all the file with the `.ini` extension present in the gi
307324
You can also change the PHP configuration using the `php_ini` directive in the `Caddyfile`:
308325

309326
```caddyfile
327+
# Caddyfile
310328
{
311329
frankenphp {
312330
php_ini memory_limit 256M
@@ -338,6 +356,7 @@ has been read. (for example: [Mercure](mercure.md), WebSocket, Server-Sent Event
338356
This is an opt-in configuration that needs to be added to the global options in the `Caddyfile`:
339357

340358
```caddyfile
359+
# Caddyfile
341360
{
342361
servers {
343362
enable_full_duplex

docs/docker.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: FrankenPHP Docker Image: Build, Configure, Extend
3+
description: Build custom FrankenPHP Docker images, install PHP extensions and Caddy modules, run as non-root, harden with distroless, and enable worker mode by default.
4+
---
5+
16
# Building Custom Docker Image
27

38
[FrankenPHP Docker images](https://hub.docker.com/r/dunglas/frankenphp) are based on [official PHP images](https://hub.docker.com/_/php/).
@@ -13,11 +18,12 @@ The tags follow this pattern: `dunglas/frankenphp:<frankenphp-version>-php<php-v
1318

1419
[Browse tags](https://hub.docker.com/r/dunglas/frankenphp/tags).
1520

16-
## How to Use The Images
21+
## How to Use the FrankenPHP Docker Images
1722

1823
Create a `Dockerfile` in your project:
1924

2025
```dockerfile
26+
# Dockerfile
2127
FROM dunglas/frankenphp
2228

2329
COPY . /app/public
@@ -30,7 +36,7 @@ docker build -t my-php-app .
3036
docker run -it --rm --name my-running-app my-php-app
3137
```
3238

33-
## How to Tweak the Configuration
39+
## How to Tweak the FrankenPHP Docker Configuration
3440

3541
For convenience, [a default `Caddyfile`](https://github.com/php/frankenphp/blob/main/caddy/frankenphp/Caddyfile) containing
3642
useful environment variables is provided in the image.
@@ -41,6 +47,7 @@ The [`docker-php-extension-installer`](https://github.com/mlocati/docker-php-ext
4147
Adding additional PHP extensions is straightforward:
4248

4349
```dockerfile
50+
# Dockerfile
4451
FROM dunglas/frankenphp
4552

4653
# add additional extensions here:
@@ -59,6 +66,7 @@ FrankenPHP is built on top of Caddy, and all [Caddy modules](https://caddyserver
5966
The easiest way to install custom Caddy modules is to use [xcaddy](https://github.com/caddyserver/xcaddy):
6067

6168
```dockerfile
69+
# Dockerfile
6270
FROM dunglas/frankenphp:builder AS builder
6371

6472
# Copy xcaddy in the builder image
@@ -99,6 +107,7 @@ The `builder` image provided by FrankenPHP contains a compiled version of `libph
99107
Set the `FRANKENPHP_CONFIG` environment variable to start FrankenPHP with a worker script:
100108

101109
```dockerfile
110+
# Dockerfile
102111
FROM dunglas/frankenphp
103112

104113
# ...
@@ -154,6 +163,7 @@ FrankenPHP can run as non-root user in Docker.
154163
Here is a sample `Dockerfile` doing this:
155164

156165
```dockerfile
166+
# Dockerfile
157167
FROM dunglas/frankenphp
158168
159169
ARG USER=appuser
@@ -179,6 +189,7 @@ If you expose FrankenPHP on a non-privileged port (1024 and above), it's possibl
179189
the webserver as a non-root user, and without the need for any capability:
180190

181191
```dockerfile
192+
# Dockerfile
182193
FROM dunglas/frankenphp
183194
184195
ARG USER=appuser
@@ -198,14 +209,14 @@ USER ${USER}
198209
Next, set the `SERVER_NAME` environment variable to use an unprivileged port.
199210
Example: `:8000`
200211

201-
## Updates
212+
## FrankenPHP Docker Image Updates
202213

203214
The Docker images are built:
204215

205216
- when a new release is tagged
206217
- daily at 4 am UTC, if new versions of the official PHP images are available
207218

208-
## Hardening Images
219+
## Hardening FrankenPHP Docker Images
209220

210221
To further reduce the attack surface and size of your FrankenPHP Docker images, it's also possible to build them on top of a
211222
[Google distroless](https://github.com/GoogleContainerTools/distroless) or
@@ -218,6 +229,7 @@ To further reduce the attack surface and size of your FrankenPHP Docker images,
218229
When adding additional PHP extensions, you will need an intermediate build stage:
219230

220231
```dockerfile
232+
# Dockerfile
221233
FROM dunglas/frankenphp AS builder
222234
223235
# Add additional PHP extensions here

docs/early-hints.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
---
2+
title: Sending HTTP 103 Early Hints from PHP with FrankenPHP
3+
description: FrankenPHP natively supports the HTTP 103 Early Hints status code, letting PHP applications preload assets before the final response is ready.
4+
---
5+
16
# Early Hints
27

3-
FrankenPHP natively supports the [103 Early Hints status code](https://developer.chrome.com/blog/early-hints/).
8+
FrankenPHP natively supports the [103 Early Hints status code](https://developer.mozilla.org/docs/Web/HTTP/Reference/Status/103).
49
Using Early Hints can improve the load time of your web pages by 30%.
510

611
```php

docs/embed.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: Embedding PHP Apps as Standalone Binaries with FrankenPHP
3+
description: How to package a PHP application (including Symfony or Laravel) as a self-contained static binary with FrankenPHP, the PHP interpreter, PHP extensions and Caddy.
4+
---
5+
16
# PHP Apps As Standalone Binaries
27

38
FrankenPHP has the ability to embed the source code and assets of PHP applications in a static, self-contained binary.
@@ -6,7 +11,7 @@ Thanks to this feature, PHP applications can be distributed as standalone binari
611

712
Learn more about this feature [in the presentation made by Kévin at SymfonyCon 2023](https://dunglas.dev/2023/12/php-and-symfony-apps-as-standalone-binaries/).
813

9-
For embedding Laravel applications, [read this specific documentation entry](laravel.md#laravel-apps-as-standalone-binaries).
14+
For embedding Laravel applications, see [the Laravel-specific embedding instructions](laravel.md#laravel-apps-as-standalone-binaries).
1015

1116
## Preparing Your App
1217

@@ -42,7 +47,7 @@ composer install --ignore-platform-reqs --no-dev -a
4247
composer dump-env prod
4348
```
4449

45-
### Customizing the Configuration
50+
### Customizing the Embedded FrankenPHP Configuration
4651

4752
To customize [the configuration](config.md), you can put a `Caddyfile` as well as a `php.ini` file
4853
in the main directory of the app to be embedded (`$TMPDIR/my-prepared-app` in the previous example).
@@ -54,6 +59,7 @@ The easiest way to create a Linux binary is to use the Docker-based builder we p
5459
1. Create a file named `static-build.Dockerfile` in the repository of your app:
5560

5661
```dockerfile
62+
# static-build.Dockerfile
5763
FROM --platform=linux/amd64 dunglas/frankenphp:static-builder-gnu
5864
# If you intend to run the binary on musl-libc systems, use static-builder-musl instead
5965

@@ -97,7 +103,7 @@ EMBED=/path/to/your/app ./build-static.sh
97103

98104
The resulting binary is the file named `frankenphp-<os>-<arch>` in the `dist/` directory.
99105

100-
## Using The Binary
106+
## Using the Embedded FrankenPHP Binary
101107

102108
This is it! The `my-app` file (or `dist/frankenphp-<os>-<arch>` on other OSes) contains your self-contained app!
103109

@@ -125,18 +131,18 @@ You can also run the PHP CLI scripts embedded in your binary:
125131
./my-app php-cli bin/console
126132
```
127133

128-
## PHP Extensions
134+
## PHP Extensions in the Embedded Binary
129135

130136
By default, the script will build extensions required by the `composer.json` file of your project, if any.
131137
If the `composer.json` file doesn't exist, the default extensions are built, as documented in [the static builds entry](static.md).
132138

133139
To customize the extensions, use the `PHP_EXTENSIONS` environment variable.
134140

135-
## Customizing The Build
141+
## Customizing the Embedded Binary Build
136142

137143
[Read the static build documentation](static.md) to see how to customize the binary (extensions, PHP version...).
138144

139-
## Distributing The Binary
145+
## Distributing the Embedded Binary
140146

141147
On Linux, the created binary is compressed using [UPX](https://upx.github.io).
142148

0 commit comments

Comments
 (0)