Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
/github/workspace/docs/mercure.md:jwt:88
/github/workspace/docs/mercure.md:jwt:90
/github/workspace/docs/mercure.md:jwt:95
Comment thread
dunglas marked this conversation as resolved.
Comment thread
dunglas marked this conversation as resolved.
Comment thread
dunglas marked this conversation as resolved.
Comment thread
dunglas marked this conversation as resolved.
Comment thread
dunglas marked this conversation as resolved.
Comment thread
dunglas marked this conversation as resolved.
2 changes: 2 additions & 0 deletions .markdown-lint.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
MD010: false
MD013: false
MD025:
front_matter_title: ""
MD033: false
MD060: false
7 changes: 6 additions & 1 deletion docs/classic.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Using Classic Mode
---
title: FrankenPHP classic mode: drop-in PHP-FPM replacement
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.
---

# Using classic mode

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.

Expand Down
17 changes: 11 additions & 6 deletions docs/compile.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Compile From Sources
---
title: Compile FrankenPHP from sources with libphp.so
description: Build FrankenPHP from source on Linux, macOS and FreeBSD, linking PHP as a shared library via xcaddy or go build, and add custom Caddy modules and extensions.
---

This document explains how to create a FrankenPHP binary that will load PHP as a dynamic library.
# Compile from sources

This document explains how to create a FrankenPHP binary that will load PHP as a shared library.
This is the recommended method.

Alternatively, [fully and mostly static builds](static.md) can also be created.
Expand All @@ -22,7 +27,7 @@ brew install shivammathur/php/php-zts brotli watcher
brew link --overwrite --force shivammathur/php/php-zts
```

### By Compiling PHP
### By compiling PHP

Alternatively, you can compile PHP from sources with the options needed by FrankenPHP by following these steps.

Expand All @@ -36,7 +41,7 @@ cd php-*/
Then, run the `configure` script with the options needed for your platform.
The following `./configure` flags are mandatory, but you can add others, for example, to compile extensions or additional features.

#### Linux
#### Linux and FreeBSD

```console
./configure \
Expand Down Expand Up @@ -74,7 +79,7 @@ make -j"$(getconf _NPROCESSORS_ONLN)"
sudo make install
```

## Install Optional Dependencies
## Install optional dependencies

Some FrankenPHP features depend on optional system dependencies that must be installed.
Alternatively, these features can be disabled by passing build tags to the Go compiler.
Expand All @@ -85,7 +90,7 @@ Alternatively, these features can be disabled by passing build tags to the Go co
| Restart workers on file change | [Watcher C](https://github.com/e-dant/watcher/tree/release/watcher-c) | nowatcher |
| [Mercure](mercure.md) | [Mercure Go library](https://pkg.go.dev/github.com/dunglas/mercure) (automatically installed, AGPL licensed) | nomercure |

## Compile the Go App
## Compile the Go app

You can now build the final binary.

Expand Down
27 changes: 15 additions & 12 deletions docs/config.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
title: Configuring FrankenPHP with Caddyfile, php.ini, and env vars
description: Configure FrankenPHP and Caddy via Caddyfile, JSON, or environment variables, including PHP runtime tuning, worker mode, file watching, and module options.
---

# Configuration

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).
Expand Down Expand Up @@ -73,7 +78,7 @@ PHP:
- PHP extensions: cannot be loaded, bundle them in the binary itself
- copy one of `php.ini-production` or `php.ini-development` provided [in the PHP sources](https://github.com/php/php-src/).

## Caddyfile Config
## Caddyfile config

The `php_server` or the `php` [HTTP directives](https://caddyserver.com/docs/caddyfile/concepts#directives) may be used within the site blocks to serve your PHP app.

Expand Down Expand Up @@ -196,7 +201,7 @@ php_server [<matcher>] {
}
```

### Watching for File Changes
### Watching for file changes

Since workers only boot your application once and keep it in memory, any changes
to your PHP files will not be reflected immediately.
Expand Down Expand Up @@ -243,7 +248,7 @@ where the FrankenPHP process was started. You can instead also specify one or mo

The file watcher is based on [e-dant/watcher](https://github.com/e-dant/watcher).

## Matching the Worker To a Path
## Matching the worker to a path

In traditional PHP applications, scripts are always placed in the public directory.
This is also true for worker scripts, which are treated like any other PHP script.
Expand All @@ -266,7 +271,7 @@ and otherwise forward the request to the worker matching the path pattern.
}
```

## Restarting Threads After a Number of Requests (Experimental)
## Restarting threads after a number of requests (experimental)

FrankenPHP can automatically restart PHP threads after they have handled a given number of requests.
When a thread reaches the limit, it is fully restarted,
Expand All @@ -285,7 +290,7 @@ But when the fix depends on a third party you don't control,
}
```

## Environment Variables
## Environment variables

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

Expand All @@ -302,7 +307,7 @@ The `S` value of [the `variables_order` PHP directive](https://www.php.net/manua

To load [additional PHP configuration files](https://www.php.net/manual/en/configuration.file.php#configuration.file.scan),
the `PHP_INI_SCAN_DIR` environment variable can be used.
When set, PHP will load all the file with the `.ini` extension present in the given directories.
When set, PHP will load all the files with the `.ini` extension present in the given directories.

You can also change the PHP configuration using the `php_ini` directive in the `Caddyfile`:

Expand All @@ -323,14 +328,14 @@ You can also change the PHP configuration using the `php_ini` directive in the `

### Disabling HTTPS

By default, FrankenPHP will automatically enable HTTPS using for all the hostnames, including `localhost`.
By default, FrankenPHP will automatically enable HTTPS for all the hostnames, including `localhost`.
If you want to disable HTTPS (for example in a development environment), you can set the `SERVER_NAME` environment variable to `http://` or `:80`:

Alternatively, you can use all other methods described in the [Caddy documentation](https://caddyserver.com/docs/automatic-https#activation).

If you want to use HTTPS with the `127.0.0.1` IP address instead of the `localhost` hostname, please read the [known issues](known-issues.md#using-https127001-with-docker) section.

### Full Duplex (HTTP/1)
### Full duplex (HTTP/1)

When using HTTP/1.x, it may be desirable to enable full-duplex mode to allow writing a response before the entire body
has been read. (for example: [Mercure](mercure.md), WebSocket, Server-Sent Events, etc.)
Expand Down Expand Up @@ -358,7 +363,7 @@ CADDY_GLOBAL_OPTIONS="servers {

You can find more information about this setting in the [Caddy documentation](https://caddyserver.com/docs/caddyfile/options#enable-full-duplex).

## Enable the Debug Mode
## Enable the debug mode

When using the Docker image, set the `CADDY_GLOBAL_OPTIONS` environment variable to `debug` to enable the debug mode:

Expand All @@ -369,7 +374,7 @@ docker run -v $PWD:/app/public \
dunglas/frankenphp
```

## Shell Completion
## Shell completion

FrankenPHP provides built-in shell completion support for Bash, Zsh, Fish, and PowerShell. This enables autocompletion for all commands (including custom commands like `php-server`, `php-cli`, and `extension-init`) and their flags.

Expand Down Expand Up @@ -441,5 +446,3 @@ Add-Content -Path $PROFILE -Value '. (Join-Path (Split-Path $PROFILE) "frankenph
```

You will need to start a new shell for this setup to take effect.

You will need to start a new shell for this setup to take effect.
33 changes: 19 additions & 14 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Building Custom Docker Image
---
title: FrankenPHP Docker image: build, configure, extend
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.
---

# Building a custom Docker image

[FrankenPHP Docker images](https://hub.docker.com/r/dunglas/frankenphp) are based on [official PHP images](https://hub.docker.com/_/php/).
Debian and Alpine Linux variants are provided for popular architectures.
Expand All @@ -13,7 +18,7 @@ The tags follow this pattern: `dunglas/frankenphp:<frankenphp-version>-php<php-v

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

## How to Use The Images
## How to use the FrankenPHP Docker images

Create a `Dockerfile` in your project:

Expand All @@ -30,12 +35,12 @@ docker build -t my-php-app .
docker run -it --rm --name my-running-app my-php-app
```

## How to Tweak the Configuration
## How to tweak the FrankenPHP Docker configuration

For convenience, [a default `Caddyfile`](https://github.com/php/frankenphp/blob/main/caddy/frankenphp/Caddyfile) containing
useful environment variables is provided in the image.

## How to Install More PHP Extensions
## How to install more PHP extensions

The [`docker-php-extension-installer`](https://github.com/mlocati/docker-php-extension-installer) script is provided in the base image.
Adding additional PHP extensions is straightforward:
Expand All @@ -52,7 +57,7 @@ RUN install-php-extensions \
opcache
```

## How to Install More Caddy Modules
## How to install more Caddy modules

FrankenPHP is built on top of Caddy, and all [Caddy modules](https://caddyserver.com/docs/modules/) can be used with FrankenPHP.

Expand Down Expand Up @@ -82,7 +87,7 @@ RUN CGO_ENABLED=1 \

FROM dunglas/frankenphp AS runner

# Replace the official binary by the one contained your custom modules
# Replace the official binary with the one containing your custom modules
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
```

Expand All @@ -94,7 +99,7 @@ The `builder` image provided by FrankenPHP contains a compiled version of `libph
> If you're using Alpine Linux and Symfony,
> you may need to [increase the default stack size](compile.md#using-xcaddy).

## Enabling the Worker Mode by Default
## Enabling the worker mode by default

Set the `FRANKENPHP_CONFIG` environment variable to start FrankenPHP with a worker script:

Expand All @@ -106,7 +111,7 @@ FROM dunglas/frankenphp
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
```

## Using a Volume in Development
## Using a volume in development

To develop easily with FrankenPHP, mount the directory from your host containing the source code of the app as a volume in the Docker container:

Expand Down Expand Up @@ -147,9 +152,9 @@ volumes:
caddy_config:
```

## Running as a Non-Root User
## Running as a non-root user

FrankenPHP can run as non-root user in Docker.
FrankenPHP can run as a non-root user in Docker.

Here is a sample `Dockerfile` doing this:

Expand All @@ -170,7 +175,7 @@ EOF
USER ${USER}
```

### Running With No Capabilities
### Running with no capabilities

Even when running rootless, FrankenPHP needs the `CAP_NET_BIND_SERVICE` capability to bind the
web server on privileged ports (80 and 443).
Expand Down Expand Up @@ -198,14 +203,14 @@ USER ${USER}
Next, set the `SERVER_NAME` environment variable to use an unprivileged port.
Example: `:8000`

## Updates
## FrankenPHP Docker image updates

The Docker images are built:

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

## Hardening Images
## Hardening images

To further reduce the attack surface and size of your FrankenPHP Docker images, it's also possible to build them on top of a
[Google distroless](https://github.com/GoogleContainerTools/distroless) or
Expand Down Expand Up @@ -265,7 +270,7 @@ WORKDIR /app
ENTRYPOINT ["/usr/local/bin/frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
```

## Development Versions
## Development versions

Development versions are available in the [`dunglas/frankenphp-dev`](https://hub.docker.com/repository/docker/dunglas/frankenphp-dev) Docker repository.
A new build is triggered every time a commit is pushed to the main branch of the GitHub repository.
Expand Down
5 changes: 5 additions & 0 deletions docs/early-hints.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
title: Sending HTTP 103 Early Hints from PHP with FrankenPHP
description: FrankenPHP natively supports the HTTP 103 Early Hints status code, letting PHP applications preload assets before the final response is ready.
---

# Early Hints

FrankenPHP natively supports the [103 Early Hints status code](https://developer.chrome.com/blog/early-hints/).
Expand Down
24 changes: 15 additions & 9 deletions docs/embed.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# PHP Apps As Standalone Binaries
---
title: Embedding PHP apps as standalone binaries with FrankenPHP
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.
---

# PHP apps as standalone binaries

FrankenPHP has the ability to embed the source code and assets of PHP applications in a static, self-contained binary.

Expand All @@ -8,7 +13,7 @@ Learn more about this feature [in the presentation made by Kévin at SymfonyCon

For embedding Laravel applications, [read this specific documentation entry](laravel.md#laravel-apps-as-standalone-binaries).

## Preparing Your App
## Preparing your app

Before creating the self-contained binary be sure that your app is ready for embedding.

Expand Down Expand Up @@ -42,18 +47,19 @@ composer install --ignore-platform-reqs --no-dev -a
composer dump-env prod
```

### Customizing the Configuration
### Customizing the configuration

To customize [the configuration](config.md), you can put a `Caddyfile` as well as a `php.ini` file
in the main directory of the app to be embedded (`$TMPDIR/my-prepared-app` in the previous example).

## Creating a Linux Binary
## Creating a Linux binary

The easiest way to create a Linux binary is to use the Docker-based builder we provide.

1. Create a file named `static-build.Dockerfile` in the repository of your app:

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

Expand Down Expand Up @@ -85,7 +91,7 @@ The easiest way to create a Linux binary is to use the Docker-based builder we p

The resulting binary is the file named `my-app` in the current directory.

## Creating a Binary for Other OSes
## Creating a binary for other OSes

If you don't want to use Docker, or want to build a macOS binary, use the shell script we provide:

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

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

## Using The Binary
## Using the binary

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

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

## PHP Extensions
## PHP extensions

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

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

## Customizing The Build
## Customizing the build

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

## Distributing The Binary
## Distributing the binary

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

Expand Down
Loading
Loading