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
68 changes: 34 additions & 34 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
197 changes: 197 additions & 0 deletions docs/symfony.md
Original file line number Diff line number Diff line change
@@ -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
}
```
Comment thread
dunglas marked this conversation as resolved.

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') %}
<meta name="frankenphp-hot-reload:url" content="{{ app.request.server.get('FRANKENPHP_HOT_RELOAD') }}">
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
{% 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.
23 changes: 2 additions & 21 deletions docs/worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 1 addition & 11 deletions docs/x-sendfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Loading