From d44661bfeff6484fa1eb80d514132e82296b9089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 26 Mar 2026 12:01:51 +0100 Subject: [PATCH] docs: add Symfony-specific page (#2307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docs for the Symfony integration, as for Laravel and WordPress. --------- Signed-off-by: Kévin Dunglas --- CONTRIBUTING.md | 68 ++++++++-------- README.md | 7 +- docs/symfony.md | 197 +++++++++++++++++++++++++++++++++++++++++++++ docs/worker.md | 23 +----- docs/x-sendfile.md | 12 +-- 5 files changed, 238 insertions(+), 69 deletions(-) create mode 100644 docs/symfony.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff68f1b2..260d076c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,60 +90,60 @@ curl -v http://127.0.0.1:8080/phpinfo.php 1. Configure Git to always use `lf` line endings - ```powershell - git config --global core.autocrlf false - git config --global core.eol lf - ``` + ```powershell + git config --global core.autocrlf false + git config --global core.eol lf + ``` 2. Install Visual Studio, Git, and Go: - ```powershell - winget install -e --id Microsoft.VisualStudio.2022.Community --override "--passive --wait --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --includeRecommended" - winget install -e --id GoLang.Go - winget install -e --id Git.Git - ``` + ```powershell + winget install -e --id Microsoft.VisualStudio.2022.Community --override "--passive --wait --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --includeRecommended" + winget install -e --id GoLang.Go + winget install -e --id Git.Git + ``` 3. Install vcpkg: - ```powershell - cd C:\ - git clone https://github.com/microsoft/vcpkg - .\vcpkg\bootstrap-vcpkg.bat - ``` + ```powershell + cd C:\ + git clone https://github.com/microsoft/vcpkg + .\vcpkg\bootstrap-vcpkg.bat + ``` 4. [Download the latest version of the watcher library for Windows](https://github.com/e-dant/watcher/releases) and extract it to a directory named `C:\watcher` 5. [Download the latest **Thread Safe** version of PHP and of the PHP SDK for Windows](https://windows.php.net/download/), extract them in directories named `C:\php` and `C:\php-devel` 6. Clone the FrankenPHP Git repository: - ```powershell - git clone https://github.com/php/frankenphp C:\frankenphp - cd C:\frankenphp - ``` + ```powershell + git clone https://github.com/php/frankenphp C:\frankenphp + cd C:\frankenphp + ``` 7. Install the dependencies: - ```powershell - C:\vcpkg\vcpkg.exe install - ``` + ```powershell + C:\vcpkg\vcpkg.exe install + ``` 8. Configure the needed environment variables (PowerShell): - ```powershell - $env:PATH += ';C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\bin' - $env:CC = 'clang' - $env:CXX = 'clang++' - $env:CGO_CFLAGS = "-O0 -g -IC:\frankenphp\vcpkg_installed\x64-windows\include -IC:\watcher -IC:\php-devel\include -IC:\php-devel\include\main -IC:\php-devel\include\TSRM -IC:\php-devel\include\Zend -IC:\php-devel\include\ext" - $env:CGO_LDFLAGS = '-LC:\frankenphp\vcpkg_installed\x64-windows\lib -lbrotlienc -LC:\watcher -llibwatcher-c -LC:\php -LC:\php-devel\lib -lphp8ts -lphp8embed' - ``` + ```powershell + $env:PATH += ';C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\bin' + $env:CC = 'clang' + $env:CXX = 'clang++' + $env:CGO_CFLAGS = "-O0 -g -IC:\frankenphp\vcpkg_installed\x64-windows\include -IC:\watcher -IC:\php-devel\include -IC:\php-devel\include\main -IC:\php-devel\include\TSRM -IC:\php-devel\include\Zend -IC:\php-devel\include\ext" + $env:CGO_LDFLAGS = '-LC:\frankenphp\vcpkg_installed\x64-windows\lib -lbrotlienc -LC:\watcher -llibwatcher-c -LC:\php -LC:\php-devel\lib -lphp8ts -lphp8embed' + ``` 9. Run the tests: - ```powershell - go test -race -ldflags '-extldflags="-fuse-ld=lld"' ./... - cd caddy - go test -race -ldflags '-extldflags="-fuse-ld=lld"' -tags nobadger,nomysql,nopgx ./... - cd .. - ``` + ```powershell + go test -race -ldflags '-extldflags="-fuse-ld=lld"' ./... + cd caddy + go test -race -ldflags '-extldflags="-fuse-ld=lld"' -tags nobadger,nomysql,nopgx ./... + cd .. + ``` 10. Build the binary: diff --git a/README.md b/README.md index a2010a78..0ee36253 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,8 @@ Our maintainers offer apk packages for all systems using `apk`. To install, run: VERSION=85 # 82-85 available echo "https://pkg.henderkes.com/api/packages/${VERSION}/alpine/main/php-zts" | sudo tee -a /etc/apk/repositories KEYFILE=$(curl -sJOw '%{filename_effective}' https://pkg.henderkes.com/api/packages/${VERSION}/alpine/key) -sudo mv ${KEYFILE} /etc/apk/keys/ && -sudo apk update && +sudo mv ${KEYFILE} /etc/apk/keys/ && +sudo apk update && sudo apk add frankenphp ``` @@ -170,6 +170,7 @@ Go to `https://localhost`, and enjoy! - [Compile from sources](https://frankenphp.dev/docs/compile/) - [Monitoring FrankenPHP](https://frankenphp.dev/docs/metrics/) - [WordPress integration](https://frankenphp.dev/docs/wordpress/) +- [Symfony integration](https://frankenphp.dev/docs/symfony/) - [Laravel integration](https://frankenphp.dev/docs/laravel/) - [Known issues](https://frankenphp.dev/docs/known-issues/) - [Demo app (Symfony) and benchmarks](https://github.com/dunglas/frankenphp-demo) @@ -178,7 +179,7 @@ Go to `https://localhost`, and enjoy! ## Examples and Skeletons -- [Symfony](https://github.com/dunglas/symfony-docker) +- [Symfony](https://frankenphp.dev/docs/symfony/) - [API Platform](https://api-platform.com/docs/symfony) - [Laravel](https://frankenphp.dev/docs/laravel/) - [Sulu](https://sulu.io/blog/running-sulu-with-frankenphp) diff --git a/docs/symfony.md b/docs/symfony.md new file mode 100644 index 00000000..54acb5ce --- /dev/null +++ b/docs/symfony.md @@ -0,0 +1,197 @@ +# Symfony + +## Docker + +For [Symfony](https://symfony.com) projects, we recommend using [Symfony Docker](https://github.com/dunglas/symfony-docker), the official Symfony Docker setup maintained by FrankenPHP's author. It provides a complete Docker-based environment with FrankenPHP, automatic HTTPS, HTTP/2, HTTP/3, and worker mode support out of the box. + +## Local Installation + +Alternatively, you can run your Symfony projects with FrankenPHP from your local machine: + +1. [Install FrankenPHP](../#getting-started) +2. Add the following configuration to a file named `Caddyfile` in the root directory of your Symfony project: + + ```caddyfile + # The domain name of your server + localhost + + root public/ + php_server { + # Optional: Enable worker mode for better performance + worker ./public/index.php + } + ``` + + See the [performance documentation](performance.md) for further optimizations. + +3. Start FrankenPHP from the root directory of your Symfony project: `frankenphp run` + +## Worker Mode + +Since Symfony 7.4, FrankenPHP worker mode is natively supported. + +For older versions, install the FrankenPHP package of [PHP Runtime](https://github.com/php-runtime/runtime): + +```console +composer require runtime/frankenphp-symfony +``` + +Start your app server by defining the `APP_RUNTIME` environment variable to use the FrankenPHP Symfony Runtime: + +```console +docker run \ + -e FRANKENPHP_CONFIG="worker ./public/index.php" \ + -e APP_RUNTIME=Runtime\\FrankenPhpSymfony\\Runtime \ + -v $PWD:/app \ + -p 80:80 -p 443:443 -p 443:443/udp \ + dunglas/frankenphp +``` + +Learn more about [the worker mode](worker.md). + +## Hot Reload + +Hot reloading is enabled by default in [Symfony Docker](https://github.com/dunglas/symfony-docker). + +To use the [hot reload](hot-reload.md) feature without Symfony Docker, enable [Mercure](mercure.md) and add the `hot_reload` sub-directive to the `php_server` directive in your `Caddyfile`: + +```caddyfile +localhost + +mercure { + anonymous +} + +root public/ +php_server { + hot_reload + worker ./public/index.php +} +``` + +Then, add the following code to your `templates/base.html.twig` file: + +```twig +{% if app.request.server.has('FRANKENPHP_HOT_RELOAD') %} + + + +{% endif %} +``` + +Finally, run `frankenphp run` from the root directory of your Symfony project. + +## Pre-Compressing Assets + +Symfony's [AssetMapper component](https://symfony.com/doc/current/frontend/asset_mapper.html) can pre-compress assets with Brotli and Zstandard during deployment. FrankenPHP (through Caddy's `file_server`) can serve these pre-compressed files directly, avoiding on-the-fly compression overhead. + +1. Compile and compress your assets: + + ```console + php bin/console asset-map:compile + ``` + +2. Update your `Caddyfile` to serve pre-compressed assets: + + ```caddyfile + localhost + + @assets path /assets/* + file_server @assets { + precompressed zstd br gzip + } + + root public/ + php_server { + worker ./public/index.php + } + ``` + +The `precompressed` directive tells Caddy to look for pre-compressed versions of the requested file (e.g., `app.css.zst`, `app.css.br`) and serve them directly if the client supports it. + +## Serving Large Static Files (`X-Sendfile`) + +FrankenPHP supports [efficiently serving large static files](x-sendfile.md) after executing PHP code (for access control, statistics, etc.). + +Symfony HttpFoundation [natively supports this feature](https://symfony.com/doc/current/components/http_foundation.html#serving-files). +After [configuring your `Caddyfile`](x-sendfile.md#configuration), it will automatically determine the correct value for the `X-Accel-Redirect` header and add it to the response: + +```php +use Symfony\Component\HttpFoundation\BinaryFileResponse; + +BinaryFileResponse::trustXSendfileTypeHeader(); +$response = new BinaryFileResponse(__DIR__.'/../private-files/file.txt'); + +// ... +``` + +## Symfony Apps As Standalone Binaries + +Using [FrankenPHP's application embedding feature](embed.md), it's possible to distribute Symfony +apps as standalone binaries. + +Follow these steps to prepare and package your Symfony app: + +1. Prepare your app: + + ```console + # Export the project to get rid of .git/, etc + mkdir $TMPDIR/my-prepared-app + git archive HEAD | tar -x -C $TMPDIR/my-prepared-app + cd $TMPDIR/my-prepared-app + + # Set proper environment variables + echo APP_ENV=prod > .env.local + echo APP_DEBUG=0 >> .env.local + + # Remove the tests and other unneeded files to save space + # Alternatively, add these files with the export-ignore attribute in your .gitattributes file + rm -Rf tests/ + + # Install the dependencies + composer install --ignore-platform-reqs --no-dev -a + + # Optimize .env + composer dump-env prod + ``` + +2. Create a file named `static-build.Dockerfile` in the repository of your app: + + ```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 + + # Copy your app + WORKDIR /go/src/app/dist/app + COPY . . + + # Build the static binary + WORKDIR /go/src/app/ + RUN EMBED=dist/app/ ./build-static.sh + ``` + + > [!CAUTION] + > + > Some `.dockerignore` files (e.g. default [Symfony Docker `.dockerignore`](https://github.com/dunglas/symfony-docker/blob/main/.dockerignore)) + > will ignore the `vendor/` directory and `.env` files. Be sure to adjust or remove the `.dockerignore` file before the build. + +3. Build: + + ```console + docker build -t static-symfony-app -f static-build.Dockerfile . + ``` + +4. Extract the binary: + + ```console + docker cp $(docker create --name static-symfony-app-tmp static-symfony-app):/go/src/app/dist/frankenphp-linux-x86_64 my-app ; docker rm static-symfony-app-tmp + ``` + +5. Start the server: + + ```console + ./my-app php-server + ``` + +Learn more about the options available and how to build binaries for other OSes in the [applications embedding](embed.md) +documentation. diff --git a/docs/worker.md b/docs/worker.md index f952c305..65e7e3b0 100644 --- a/docs/worker.md +++ b/docs/worker.md @@ -37,28 +37,9 @@ frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to This feature is often used in combination with [hot reloading](hot-reload.md). -## Symfony Runtime +## Symfony -> [!TIP] -> The following section is only necessary prior to Symfony 7.4, where native support for FrankenPHP worker mode was introduced. - -The worker mode of FrankenPHP is supported by the [Symfony Runtime Component](https://symfony.com/doc/current/components/runtime.html). -To start any Symfony application in a worker, install the FrankenPHP package of [PHP Runtime](https://github.com/php-runtime/runtime): - -```console -composer require runtime/frankenphp-symfony -``` - -Start your app server by defining the `APP_RUNTIME` environment variable to use the FrankenPHP Symfony Runtime: - -```console -docker run \ - -e FRANKENPHP_CONFIG="worker ./public/index.php" \ - -e APP_RUNTIME=Runtime\\FrankenPhpSymfony\\Runtime \ - -v $PWD:/app \ - -p 80:80 -p 443:443 -p 443:443/udp \ - dunglas/frankenphp -``` +See [the dedicated documentation](symfony.md#worker-mode). ## Laravel Octane diff --git a/docs/x-sendfile.md b/docs/x-sendfile.md index 8017f3d5..f9513c34 100644 --- a/docs/x-sendfile.md +++ b/docs/x-sendfile.md @@ -58,14 +58,4 @@ header('X-Accel-Redirect: file.txt'); ## Projects using the Symfony HttpFoundation component (Symfony, Laravel, Drupal...) -Symfony HttpFoundation [natively supports this feature](https://symfony.com/doc/current/components/http_foundation.html#serving-files). -It will automatically determine the correct value for the `X-Accel-Redirect` header and add it to the response. - -```php -use Symfony\Component\HttpFoundation\BinaryFileResponse; - -BinaryFileResponse::trustXSendfileTypeHeader(); -$response = new BinaryFileResponse(__DIR__.'/../private-files/file.txt'); - -// ... -``` +See [the Symfony documentation](symfony.md#serving-large-static-files-x-sendfile) for details on using this feature with Symfony HttpFoundation.