FrankenPHP, Caddy as well as the Mercure and Vulcain modules can be configured using the formats supported by Caddy.
In the Docker image, the Caddyfile
is located at /etc/caddy/Caddyfile
.
You can also configure PHP using php.ini
as usual.
In the Docker image, the php.ini
file is not present, you can create it or COPY
manually.
If you copy php.ini
from $PHP_INI_DIR/php.ini-production
or $PHP_INI_DIR/php.ini-development
, you also must set the variable variables_order = "EGPCS"
, because the default value for variables_order
is "EGPCS"
, but in php.ini-production
and php.ini-development
we have "GPCS"
. And in this case, worker
does not work properly.
FROM dunglas/frankenphp
RUN cp $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini; \
sed -i 's/variables_order = "GPCS"/variables_order = "EGPCS"/' $PHP_INI_DIR/php.ini;
To register the FrankenPHP executor, the frankenphp
global option must be set, then the php_server
or the php
HTTP directives may be used within the site blocks to serve your PHP app.
Minimal example:
{
# Enable FrankenPHP
frankenphp
# Configure when the directive must be executed
order php_server before file_server
}
localhost {
# Enable compression (optional)
encode zstd br gzip
# Execute PHP files in the current directory and serve assets
php_server
}
Optionally, the number of threads to create and worker scripts to start with the server can be specified under the global option.
{
frankenphp {
num_threads <num_threads> # Sets the number of PHP threads to start. Default: 2x the number of available CPUs.
worker {
file <path> # Sets the path to the worker script.
num <num> # Sets the number of PHP threads to start, defaults to 2x the number of available CPUs.
env <key> <value> # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables.
}
}
}
# ...
Alternatively, you may use the one-line short form of the worker
option:
{
frankenphp {
worker <file> <num>
}
}
# ...
You can also define multiple workers if you serve multiple apps on the same server:
{
frankenphp {
worker /path/to/app/public/index.php <num>
worker /path/to/other/public/index.php <num>
}
}
app.example.com {
root * /path/to/app/public
php_server
}
other.example.com {
root * /path/to/other/public
php_server
}
...
Using the php_server
directive is generally what you need,
but if you need full control, you can use the lower level php
directive:
Using the php_server
directive is equivalent to this configuration:
route {
# Add trailing slash for directory requests
@canonicalPath {
file {path}/index.php
not path */
}
redir @canonicalPath {path}/ 308
# If the requested file does not exist, try index files
@indexFiles file {
try_files {path} {path}/index.php index.php
split_path .php
}
rewrite @indexFiles {http.matchers.file.relative}
# FrankenPHP!
@phpFiles path *.php
php @phpFiles
file_server
}
The php_server
and the php
directives have the following options:
php_server [<matcher>] {
root <directory> # Sets the root folder to the site. Default: `root` directive.
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 CGI script to use. Default: `.php`
resolve_root_symlink # Enables resolving the `root` directory to its actual value by evaluating a symbolic link, if one exists.
env <key> <value> # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables.
}
The following environment variables can be used to inject Caddy directives in the Caddyfile
without modifying it:
SERVER_NAME
: change the addresses on which to listen, the provided hostnames will also be used for the generated TLS certificateCADDY_GLOBAL_OPTIONS
: inject global optionsFRANKENPHP_CONFIG
: inject config under the frankenphp
directiveUnlike with FPM and CLI SAPIs, environment variables are not exposed by default in superglobals $_SERVER
and $_ENV
.
To propagate environment variables to $_SERVER
and $_ENV
, set the php.ini
variables_order
directive to EGPCS
.
To load additional PHP configuration files,
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 using the Docker image, set the CADDY_GLOBAL_OPTIONS
environment variable to debug
to enable the debug mode:
docker run -v $PWD:/app/public \
-e CADDY_GLOBAL_OPTIONS=debug \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp