docs: add FR translations and various EN improvements (#589)

* feat: add fr doc (#1)

* fix: fr translations

* fix: linter

* docs: various improvements

* fix: md links on readme fr

* fix: remove duplicate images

---------

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
This commit is contained in:
Laury S
2024-02-27 17:21:48 +01:00
committed by GitHub
parent a6fc22505c
commit 963b3e0f59
25 changed files with 1412 additions and 27 deletions

View File

@@ -6,7 +6,7 @@ FrankenPHP is a modern application server for PHP built on top of the [Caddy](ht
FrankenPHP gives superpowers to your PHP apps thanks to its stunning features: [*Early Hints*](https://frankenphp.dev/docs/early-hints/), [worker mode](https://frankenphp.dev/docs/worker/), [real-time capabilities](https://frankenphp.dev/docs/mercure/), automatic HTTPS, HTTP/2, and HTTP/3 support...
FrankenPHP works with any PHP app and makes your Symfony and Laravel projects faster than ever thanks to the provided integration with the worker mode.
FrankenPHP works with any PHP app and makes your Laravel and Symfony projects faster than ever thanks to their official integrations with the worker mode.
FrankenPHP can also be used as a standalone Go library to embed PHP in any app using `net/http`.

View File

@@ -6,7 +6,7 @@ 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:
In the Docker image, the `php.ini` file is not present, you can create it manually or copy an official template:
```dockerfile
FROM dunglas/frankenphp
@@ -88,7 +88,8 @@ other.example.com {
root * /path/to/other/public
php_server
}
...
# ...
```
Using the `php_server` directive is generally what you need,
@@ -122,7 +123,7 @@ The `php_server` and the `php` directives have the following options:
```caddyfile
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`
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`
resolve_root_symlink false # Disables resolving the `root` directory to its actual value by evaluating a symbolic link, if one exists (enabled by default).
env <key> <value> # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables.
}
@@ -136,9 +137,9 @@ The following environment variables can be used to inject Caddy directives in th
* `CADDY_GLOBAL_OPTIONS`: inject [global options](https://caddyserver.com/docs/caddyfile/options)
* `FRANKENPHP_CONFIG`: inject config under the `frankenphp` directive
Unlike with FPM and CLI SAPIs, environment variables are **not** exposed by default in superglobals `$_SERVER` and `$_ENV`.
As for FPM and CLI SAPIs, environment variables are exposed by default in the `$_SERVER` superglobal.
To propagate environment variables to `$_SERVER` and `$_ENV`, set the `php.ini` `variables_order` directive to `EGPCS`.
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.
## PHP config

View File

@@ -1,6 +1,8 @@
# Building Custom Docker Image
[FrankenPHP Docker images](https://hub.docker.com/r/dunglas/frankenphp) are based on [official PHP images](https://hub.docker.com/_/php/). Alpine Linux and Debian variants are provided for popular architectures. Variants for PHP 8.2 and PHP 8.3 are provided. [Browse tags](https://hub.docker.com/r/dunglas/frankenphp/tags).
[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 avariants are provided for popular architectures. Debian variants are recommended.
Variants for PHP 8.2 and PHP 8.3 are provided. [Browse tags](https://hub.docker.com/r/dunglas/frankenphp/tags).
## How to Use The Images
@@ -12,7 +14,7 @@ FROM dunglas/frankenphp
COPY . /app/public
```
Then, run the commands to build and run the Docker image:
Then, run these commands to build and run the Docker image:
```console
docker build -t my-php-app .
@@ -65,8 +67,8 @@ FROM dunglas/frankenphp AS runner
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
```
The `builder` image provided by FrankenPHP contains a compiled version of libphp.
[Builders images](https://hub.docker.com/r/dunglas/frankenphp/tags?name=builder) are provided for all versions of FrankenPHP and PHP, both for Alpine and Debian.
The `builder` image provided by FrankenPHP contains a compiled version of `libphp`.
[Builders images](https://hub.docker.com/r/dunglas/frankenphp/tags?name=builder) are provided for all versions of FrankenPHP and PHP, both for Debian and Alpine.
> [!TIP]
>

View File

@@ -4,7 +4,7 @@ FrankenPHP has the ability to embed the source code and assets of PHP applicatio
Thanks to this feature, PHP applications can be distributed as standalone binaries that include the application itself, the PHP interpreter and Caddy, a production-level web server.
Learn more about this feature [in the presentation made by Kévin at SymfonyCon](https://dunglas.dev/2023/12/php-and-symfony-apps-as-standalone-binaries/).
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/).
## Preparing Your App
@@ -65,7 +65,7 @@ The easiest way to create a Linux binary is to use the Docker-based builder we p
docker build -t static-app -f static-build.Dockerfile .
```
3. Extract the binary
3. Extract the binary:
```console
docker cp $(docker create --name static-app-tmp static-app):/go/src/app/dist/frankenphp-linux-x86_64 my-app ; docker rm static-app-tmp
@@ -121,7 +121,7 @@ You can also run the PHP CLI scripts embedded in your binary:
## Distributing The Binary
The created binary isn't compressed.
To reduce the size of the file before sending it, you can compress it.
On Linux, the created binary is compressed using [UPX](https://upx.github.io).
On Mac, to reduce the size of the file before sending it, you can compress it.
We recommend `xz`.

177
docs/fr/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,177 @@
# Contribuer
## Compiler PHP
### Avec Docker (Linux)
Construisez l'image Docker de développement :
```console
docker build -t frankenphp-dev -f dev.Dockerfile .
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8080:8080 -p 443:443 -p 443:443/udp -v $PWD:/go/src/app -it frankenphp-dev
```
L'image contient les outils de développement habituels (Go, GDB, Valgrind, Neovim...).
Si la version de Docker est inférieure à 23.0, la construction échoue à cause d'un [problème de pattern](https://github.com/moby/moby/pull/42676) dans `.dockerignore`. Ajoutez les répertoires à `.dockerignore`.
```patch
!testdata/*.php
!testdata/*.txt
+!caddy
+!C-Thread-Pool
+!internal
```
### Sans Docker (Linux et macOS)
[Suivez les instructions pour compiler à partir des sources](compile.md) et passez l'indicateur de configuration `--debug`.
## Exécution de la suite de tests
```console
go test -race -v ./...
```
## Module Caddy
Construire Caddy avec le module FrankenPHP :
```console
cd caddy/frankenphp/
go build
cd ../../
```
Exécuter Caddy avec le module FrankenPHP :
```console
cd testdata/
../caddy/frankenphp/frankenphp run
```
Le serveur est configuré pour écouter à l'adresse `127.0.0.1:8080`:
```console
curl -vk https://localhost/phpinfo.php
```
## Serveur de test minimal
Construire le serveur de test minimal :
```console
cd internal/testserver/
go build
cd ../../
```
Lancer le test serveur :
```console
cd testdata/
../internal/testserver/testserver
```
Le serveur est configuré pour écouter à l'adresse `127.0.0.1:8080`:
```console
curl -v http://127.0.0.1:8080/phpinfo.php
```
## Construire localement les images Docker
Afficher le plan de compilation :
```console
docker buildx bake -f docker-bake.hcl --print
```
Construire localement les images FrankenPHP pour amd64 :
```console
docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/amd64"
```
Construire localement les images FrankenPHP pour arm64 :
```console
docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/arm64"
```
Construire à partir de zéro les images FrankenPHP pour arm64 & amd64 et les pousser sur Docker Hub :
```console
docker buildx bake -f docker-bake.hcl --pull --no-cache --push
```
## Déboguer les erreurs de segmentation dans GitHub Actions
1. Ouvrir `.github/workflows/tests.yml`
2. Activer les symboles de débogage de la bibliothèque PHP
```patch
- uses: shivammathur/setup-php@v2
# ...
env:
phpts: ts
+ debug: true
```
3. Activer `tmate` pour se connecter au conteneur
```patch
-
name: Set CGO flags
run: echo "CGO_CFLAGS=$(php-config --includes)" >> "$GITHUB_ENV"
+ -
+ run: |
+ sudo apt install gdb
+ mkdir -p /home/runner/.config/gdb/
+ printf "set auto-load safe-path /\nhandle SIG34 nostop noprint pass" > /home/runner/.config/gdb/gdbinit
+ -
+ uses: mxschmitt/action-tmate@v3
```
4. Se connecter au conteneur
5. Ouvrir `frankenphp.go`
6. Activer `cgosymbolizer`
```patch
- //_ "github.com/ianlancetaylor/cgosymbolizer"
+ _ "github.com/ianlancetaylor/cgosymbolizer"
```
7. Télécharger le module : `go get`
8. Dans le conteneur, vous pouvez utiliser GDB et similaires :
```console
go test -c -ldflags=-w
gdb --args ./frankenphp.test -test.run ^MyTest$
```
9. Quand le bug est corrigé, annulez tous les changements
## Ressources Diverses pour le Développement
* [Intégration de PHP dans uWSGI](https://github.com/unbit/uwsgi/blob/master/plugins/php/php_plugin.c)
* [Intégration de PHP dans NGINX Unit](https://github.com/nginx/unit/blob/master/src/nxt_php_sapi.c)
* [Intégration de PHP dans Go (go-php)](https://github.com/deuill/go-php)
* [Intégration de PHP dans Go (GoEmPHP)](https://github.com/mikespook/goemphp)
* [Intégration de PHP dans C++](https://gist.github.com/paresy/3cbd4c6a469511ac7479aa0e7c42fea7)
* [Extending and Embedding PHP par Sara Golemon](https://books.google.fr/books?id=zMbGvK17_tYC&pg=PA254&lpg=PA254#v=onepage&q&f=false)
* [Qu'est-ce que TSRMLS_CC, au juste ?](http://blog.golemon.com/2006/06/what-heck-is-tsrmlscc-anyway.html)
* [Intégration de PHP sur Mac](https://gist.github.com/jonnywang/61427ffc0e8dde74fff40f479d147db4)
* [Bindings SDL](https://pkg.go.dev/github.com/veandco/go-sdl2@v0.4.21/sdl#Main)
## Ressources Liées à Docker
* [Définition du fichier Bake](https://docs.docker.com/build/customize/bake/file-definition/)
* [docker buildx build](https://docs.docker.com/engine/reference/commandline/buildx_build/)
## Commande utile
```console
apk add strace util-linux gdb
strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1
```

77
docs/fr/README.md Normal file
View File

@@ -0,0 +1,77 @@
# FrankenPHP : le serveur d'applications PHP moderne, écrit en Go
<h1 align="center"><a href="https://frankenphp.dev"><img src="../../frankenphp.png" alt="FrankenPHP" width="600"></a></h1>
FrankenPHP est un serveur d'applications moderne pour PHP construit à partir du serveur web [Caddy](https://caddyserver.com/).
FrankenPHP donne des super-pouvoirs à vos applications PHP grâce à ses fonctionnalités à la pointe : [*Early Hints*](early-hints.md), [mode worker](worker.md), [fonctionnalités en temps réel](mercure.md), HTTPS automatique, prise en charge de HTTP/2 et HTTP/3...
FrankenPHP fonctionne avec n'importe quelle application PHP et rend vos projets Laravel et Symfony plus rapides que jamais grâce à leurs intégrations officielles avec le mode worker.
FrankenPHP peut également être utilisé comme une bibliothèque Go autonome qui permet d'intégrer PHP dans n'importe quelle application en utilisant `net/http`.
Découvrez plus de détails sur ce serveur dapplication dans le replay de cette conférence donnée au Forum PHP 2022 :
<a href="https://dunglas.dev/2022/10/frankenphp-the-modern-php-app-server-written-in-go/"><img src="https://dunglas.dev/wp-content/uploads/2022/10/frankenphp.png" alt="Diapositives" width="600"></a>
## Pour Commencer
### Docker
```console
docker run -v $PWD:/app/public \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```
Rendez-vous sur `https://localhost`, c'est parti !
> [!TIP]
>
> Ne tentez pas d'utiliser `https://127.0.0.1`. Utilisez localhost et acceptez le certificat auto-signé.
> Utilisez [la variable d'environnement `SERVER_NAME`](config.md#environment-variables) pour changer le domaine à utiliser.
### Binaire autonome
Si vous préférez ne pas utiliser Docker, nous fournissons des binaires autonomes de FrankenPHP pour Linux et macOS
contenant [PHP 8.3](https://www.php.net/releases/8.3/fr.php) et la plupart des extensions PHP populaires : [Télécharger FrankenPHP](https://github.com/dunglas/frankenphp/releases)
Pour servir le contenu du répertoire courant, exécutez :
```console
./frankenphp php-server
```
Vous pouvez également exécuter des scripts en ligne de commande avec :
```console
./frankenphp php-cli /path/to/your/script.php
```
## Documentation
* [Le mode worker](worker.md)
* [Le support des Early Hints (code de statut HTTP 103)](early-hints.md)
* [Temps réel](mercure.md)
* [Configuration](config.md)
* [Images Docker](docker.md)
* [Déploiement en production](production.md)
* [Créer des applications PHP **standalone**, auto-exécutables](embed.md)
* [Créer un build statique](static.md)
* [Compiler depuis les sources](compile.md)
* [Intégration Laravel](laravel.md)
* [Problèmes connus](known-issues.md)
* [Application de démo (Symfony) et benchmarks](https://github.com/dunglas/frankenphp-demo)
* [Documentation de la bibliothèque Go](https://pkg.go.dev/github.com/dunglas/frankenphp)
* [Contribuer et débugger](CONTRIBUTING.md)
## Exemples et squelettes
* [Symfony](https://github.com/dunglas/symfony-docker)
* [API Platform](https://api-platform.com/docs/distribution/)
* [Laravel](laravel.md)
* [Sulu](https://sulu.io/blog/running-sulu-with-frankenphp)
* [WordPress](https://github.com/dunglas/frankenphp-wordpress)
* [Drupal](https://github.com/dunglas/frankenphp-drupal)
* [Joomla](https://github.com/alexandreelise/frankenphp-joomla)
* [TYPO3](https://github.com/ochorocho/franken-typo3)

101
docs/fr/compile.md Normal file
View File

@@ -0,0 +1,101 @@
# Compiler depuis les sources
Ce document explique comment créer un build FrankenPHP qui chargera PHP comme une bibliothèque dynamique. C'est la méthode recommandée.
En alternative, il est aussi possible de [créer des builds statiques](static.md).
## Installer PHP
FrankenPHP est compatible avec PHP 8.2 et versions ultérieures.
Tout d'abord, [téléchargez les sources de PHP](https://www.php.net/downloads.php) et extrayez-les :
```console
tar xf php-*
cd php-*/
```
Ensuite, configurez PHP pour votre système d'exploitation :
### Linux
```console
./configure \
--enable-embed \
--enable-zts \
--disable-zend-signals \
--enable-zend-max-execution-timers
```
Finalement, compilez et installez PHP :
```console
make -j$(nproc)
sudo make install
```
### Mac
Utilisez le gestionnaire de paquets [Homebrew](https://brew.sh/) pour installer `libiconv`, `bison`, `re2c` et `pkg-config` :
```console
brew install libiconv bison re2c pkg-config
echo 'export PATH="/opt/homebrew/opt/bison/bin:$PATH"' >> ~/.zshrc
```
Puis exécutez le script de configuration :
```console
./configure \
--enable-embed=static \
--enable-zts \
--disable-zend-signals \
--disable-opcache-jit \
--enable-static \
--enable-shared=no \
--with-iconv=/opt/homebrew/opt/libiconv/
```
Les options de configuration spécifiées sont nécessaires pour la compilation, mais vous pouvez également inclure d'autres options selon vos besoins, par exemple pour ajouter des extensions supplémentaires.
Finalement, compilez et installez PHP :
```console
make -j$(sysctl -n hw.logicalcpu)
sudo make install
```
## Compiler l'application Go
Vous pouvez maintenant utiliser la bibliothèque Go et compiler notre build de Caddy :
```console
curl -L https://github.com/dunglas/frankenphp/archive/refs/heads/main.tar.gz | tar x
cd frankenphp-main/caddy/frankenphp
CGO_CFLAGS=$(php-config --includes) CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" go build
```
### Utiliser xcaddy
Vous pouvez utiliser à la place [xcaddy](https://github.com/caddyserver/xcaddy) pour compiler FrankenPHP avec [des modules Caddy additionnels](https://caddyserver.com/docs/modules/):
```console
CGO_ENABLED=1 \
XCADDY_GO_BUILD_FLAGS="-ldflags '-w -s'" \
xcaddy build \
--output frankenphp \
--with github.com/dunglas/frankenphp/caddy \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy
# Add extra Caddy modules here
```
> [!TIP]
>
> Si vous utilisez musl libc (la bibliothèque par défaut sur Alpine Linux) et Symfony,
> vous pourriez avoir besoin d'augmenter la taille par défaut de la pile.
> Sinon, vous pourriez rencontrer des erreurs telles que `PHP Fatal error: Maximum call stack size of 83360 bytes reached during compilation. Try splitting expression`
>
> Pour ce faire, modifiez la variable d'environnement `XCADDY_GO_BUILD_FLAGS` en quelque chose comme
> `XCADDY_GO_BUILD_FLAGS=$'-ldflags "-w -s -extldflags \'-Wl,-z,stack-size=0x80000\'"'`
> (modifiez la valeur de la taille de la pile selon les besoins de votre application).

158
docs/fr/config.md Normal file
View File

@@ -0,0 +1,158 @@
# Configuration
FrankenPHP, Caddy ainsi que les modules Mercure et Vulcain peuvent être configurés en utilisant [les formats pris en charge par Caddy](https://caddyserver.com/docs/getting-started#your-first-config).
Dans l'image Docker, le chemin du `Caddyfile` est `/etc/caddy/Caddyfile`.
Vous pouvez également configurer PHP en utilisant `php.ini` comme d'habitude.
Dans l'image Docker, le fichier `php.ini` n'est pas présent, vous pouvez le créer manuellement ou copier un template officiel :
```dockerfile
FROM dunglas/frankenphp
# Développement :
RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini
# Ou production :
RUN cp $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
```
## Configuration du Caddyfile
Pour enregistrer l'exécutable de FrankenPHP, l'[option globale](https://caddyserver.com/docs/caddyfile/concepts#global-options) `frankenphp` doit être définie, puis les [directives HTTP](https://caddyserver.com/docs/caddyfile/concepts#directives) `php_server` ou `php` peuvent être utilisées dans les blocs de site pour servir votre application PHP.
Exemple minimal :
```caddyfile
{
# Activer FrankenPHP
frankenphp
# Configurer l'ordre d'exécution de la directive
order php_server before file_server
}
localhost {
# Activer la compression (optionnel)
encode zstd br gzip
# Exécuter les fichiers PHP dans le répertoire courant et servir les assets
php_server
}
```
En option, le nombre de threads à créer et les [workers](worker.md) à démarrer avec le serveur peuvent être spécifiés sous l'option globale.
```caddyfile
{
frankenphp {
num_threads <num_threads> # Définit le nombre de threads PHP à démarrer. Par défaut : 2x le nombre de CPUs disponibles.
worker {
file <path> # Définit le chemin vers le script worker.
num <num> # Définit le nombre de threads PHP à démarrer, par défaut 2x le nombre de CPUs disponibles.
env <key> <value> # Définit une variable d'environnement supplémentaire avec la valeur donnée. Peut être spécifié plusieurs fois pour régler plusieurs variables d'environnement.
}
}
}
# ...
```
Vous pouvez également utiliser la forme courte de l'option worker en une seule ligne :
```caddyfile
{
frankenphp {
worker <file> <num>
}
}
# ...
```
Vous pouvez aussi définir plusieurs workers si vous servez plusieurs applications sur le même serveur :
```caddyfile
{
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
}
# ...
```
L'utilisation de la directive `php_server` est généralement suffisante,
mais si vous avez besoin d'un contrôle total, vous pouvez utiliser la directive `php`, qui permet un plus grand niveau de finesse dans la configuration.
Utiliser la directive `php_server` est équivalent à cette configuration :
```caddyfile
route {
# Ajoute un slash final pour les requêtes de répertoire
@canonicalPath {
file {path}/index.php
not path */
}
redir @canonicalPath {path}/ 308
# Si le fichier demandé n'existe pas, essayer les fichiers index
@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
}
```
Les directives `php_server` et `php` disposent des options suivantes :
```caddyfile
php_server [<matcher>] {
root <directory> # Définit le dossier racine du le site. Par défaut : valeur de la directive `root` parente.
split_path <delim...> # Définit les sous-chaînes pour diviser l'URI en deux parties. La première sous-chaîne correspondante sera utilisée pour séparer le "path info" du chemin. La première partie est suffixée avec la sous-chaîne correspondante et sera considérée comme le nom réel de la ressource (script CGI). La seconde partie sera définie comme PATH_INFO pour utilisation par le script. Par défaut : `.php`
resolve_root_symlink false # Désactive la résolution du répertoire `root` vers sa valeur réelle en évaluant un lien symbolique, s'il existe (activé par défaut).
env <key> <value> # Définit une variable d'environnement supplémentaire avec la valeur donnée. Peut être spécifié plusieurs fois pour plusieurs variables d'environnement.
}
```
## Variables d'environnement
Les variables d'environnement suivantes peuvent être utilisées pour insérer des directives Caddy dans le `Caddyfile` sans le modifier :
* `SERVER_NAME` : change [les adresses sur lesquelles écouter](https://caddyserver.com/docs/caddyfile/concepts#addresses), les noms d'hôte fournis seront également utilisés pour le certificat TLS généré
* `CADDY_GLOBAL_OPTIONS` : injecte [des options globales](https://caddyserver.com/docs/caddyfile/options)
* `FRANKENPHP_CONFIG` : insère la configuration sous la directive `frankenphp`
Comme pour les SAPI FPM et CLI, les variables d'environnement ne sont exposées par défaut dans la superglobale `$_SERVER`.
La valeur `S` de [la directive `variables_order` de PHP](https://www.php.net/manual/fr/ini.core.php#ini.variables-order) est toujours équivalente à `ES`, que `E` soit défini ailleurs dans cette directive ou non.
## Configuration PHP
Pour charger [des fichiers de configuration PHP supplémentaires](https://www.php.net/manual/fr/configuration.file.php#configuration.file.scan), la variable d'environnement `PHP_INI_SCAN_DIR` peut être utilisée.
Lorsqu'elle est définie, PHP chargera tous les fichiers avec l'extension `.ini` présents dans les répertoires donnés.
## Activer le mode debug
Lors de l'utilisation de l'image Docker, définissez la variable d'environnement `CADDY_GLOBAL_OPTIONS` sur `debug` pour activer le mode debug :
```console
docker run -v $PWD:/app/public \
-e CADDY_GLOBAL_OPTIONS=debug \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```

165
docs/fr/docker.md Normal file
View File

@@ -0,0 +1,165 @@
# Création d'une image Docker personnalisée
Les images Docker de [FrankenPHP](https://hub.docker.com/r/dunglas/frankenphp) sont basées sur les [images PHP officielles](https://hub.docker.com/_/php/). Des variantes Debian et Alpine Linux sont fournies pour les architectures populaires. Les variantes Debian sont recommandées.
Des variantes pour PHP 8.2 et PHP 8.3 sont disponibles. [Parcourir les tags](https://hub.docker.com/r/dunglas/frankenphp/tags).
## Comment utiliser les images
Créez un `Dockerfile` dans votre projet :
```dockerfile
FROM dunglas/frankenphp
COPY . /app/public
```
Ensuite, exécutez ces commandes pour construire et exécuter l'image Docker :
```console
docker build -t my-php-app .
docker run -it --rm --name my-running-app my-php-app
```
## Comment installer plus d'extensions PHP
Le script [`docker-php-extension-installer`](https://github.com/mlocati/docker-php-extension-installer) est fourni dans l'image de base.
Il est facile d'ajouter des extensions PHP supplémentaires :
```dockerfile
FROM dunglas/frankenphp
# ajoutez des extensions supplémentaires ici :
RUN install-php-extensions \
pdo_mysql \
gd \
intl \
zip \
opcache
```
## Comment installer plus de modules Caddy
FrankenPHP est construit sur Caddy, et tous les [modules Caddy](https://caddyserver.com/docs/modules/) peuvent être utilisés avec FrankenPHP.
La manière la plus simple d'installer des modules Caddy personnalisés est d'utiliser [xcaddy](https://github.com/caddyserver/xcaddy):
```dockerfile
FROM dunglas/frankenphp:latest-builder AS builder
# Copier xcaddy dans l'image du constructeur
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
# CGO doit être activé pour construire FrankenPHP
ENV CGO_ENABLED=1 XCADDY_SETCAP=1 XCADDY_GO_BUILD_FLAGS="-ldflags '-w -s'"
RUN xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
# Mercure et Vulcain sont inclus dans la construction officielle, mais n'hésitez pas à les retirer
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy
# Ajoutez des modules Caddy supplémentaires ici
FROM dunglas/frankenphp AS runner
# Remplacer le binaire officiel par celui contenant vos modules personnalisés
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
```
L'image builder fournie par FrankenPHP contient une version compilée de `libphp`.
[Les images builder](https://hub.docker.com/r/dunglas/frankenphp/tags?name=builder) sont fournies pour toutes les versions de FrankenPHP et PHP, à la fois pour Debian et Alpine.
> [!TIP]
>
> Si vous utilisez Alpine Linux et Symfony,
> vous devrez peut-être [augmenter la taille de pile par défaut](compile.md#using-xcaddy).
## Activer le mode Worker par défaut
Définissez la variable d'environnement `FRANKENPHP_CONFIG` pour démarrer FrankenPHP avec un script worker :
```dockerfile
FROM dunglas/frankenphp
# ...
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
```
## Utiliser un volume en développement
Pour développer facilement avec FrankenPHP, montez le répertoire de l'hôte contenant le code source de l'application comme un volume dans le conteneur Docker :
```console
docker run -v $PWD:/app/public -p 80:80 -p 443:443 -p 443:443/udp --tty my-php-app
```
> ![TIP]
>
> L'option --tty permet d'avoir des logs lisibles par un humain au lieu de logs JSON.
Avec Docker Compose :
```yaml
# compose.yaml
services:
php:
image: dunglas/frankenphp
# décommentez la ligne suivante si vous souhaitez utiliser un Dockerfile personnalisé
#build: .
# décommentez la ligne suivante si vous souhaitez exécuter ceci dans un environnement de production
# restart: always
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "443:443/udp" # HTTP/3
volumes:
- ./:/app/public
- caddy_data:/data
- caddy_config:/config
# commentez la ligne suivante en production, elle permet d'avoir de beaux logs lisibles en dev
tty: true
# Volumes nécessaires pour les certificats et la configuration de Caddy
volumes:
caddy_data:
caddy_config:
```
## Exécution en tant qu'utilisateur non-root
FrankenPHP peut s'exécuter en tant qu'utilisateur non-root dans Docker.
Voici un exemple de `Dockerfile` le permettant :
```dockerfile
FROM dunglas/frankenphp
ARG USER=www-data
RUN \
# Utilisez "adduser -D ${USER}" pour les distributions basées sur Alpine
useradd -D ${USER}; \
# Ajouter la capacité supplémentaire de se lier aux ports 80 et 443
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \
# Donner l'accès en écriture à /data/caddy et /config/caddy
chown -R ${USER}:${USER} /data/caddy && chown -R ${USER}:${USER} /config/caddy;
USER ${USER}
```
## Mises à jour
Les images Docker sont construites :
* lorsqu'une nouvelle version est taguée
* tous les jours à 4h UTC, si de nouvelles versions des images officielles PHP sont disponibles
## Versions de développement
Les versions de développement sont disponibles dans le dépôt Docker [`dunglas/frankenphp-dev`](https://hub.docker.com/repository/docker/dunglas/frankenphp-dev). Un nouveau build est déclenché chaque fois qu'un commit est poussé sur la branche principale du dépôt GitHub.
Les tags `latest*` pointent vers la tête de la branche `main`.
Les tags sous la forme `sha-<hash-du-commit-git>` sont également disponibles.

21
docs/fr/early-hints.md Normal file
View File

@@ -0,0 +1,21 @@
# Early Hints
FrankenPHP prend nativement en charge le code de statut [103 Early Hints](https://developer.chrome.com/blog/early-hints/).
L'utilisation des Early Hints peut améliorer le temps de chargement de vos pages web de 30 %.
```php
<?php
header('Link: </style.css>; rel=preload; as=style');
headers_send(103);
// vos algorithmes lents et requêtes SQL 🤪
echo <<<'HTML'
<!DOCTYPE html>
<title>Hello FrankenPHP</title>
<link rel="stylesheet" href="style.css">
HTML;
```
Les Early Hints sont pris en charge à la fois par les modes "standard" et [worker](worker.md).

127
docs/fr/embed.md Normal file
View File

@@ -0,0 +1,127 @@
# Applications PHP en tant que binaires autonomes
FrankenPHP a la capacité d'incorporer le code source et les assets des applications PHP dans un binaire statique et autonome.
Grâce à cette fonctionnalité, les applications PHP peuvent être distribuées en tant que binaires autonomes qui incluent l'application elle-même, l'interpréteur PHP et Caddy, un serveur web de qualité production.
Pour en savoir plus sur cette fonctionnalité, consultez [la présentation faite par Kévin à la SymfonyCon 2023](https://dunglas.dev/2023/12/php-and-symfony-apps-as-standalone-binaries/).
## Préparer votre application
Avant de créer le binaire autonome, assurez-vous que votre application est prête à être intégrée.
Vous devrez probablement :
* Installer les dépendances de production de l'application
* Dumper l'autoloader
* Activer le mode production de votre application (si disponible)
* Supprimer les fichiers inutiles tels que `.git` ou les tests pour réduire la taille de votre binaire final
Par exemple, pour une application Symfony, lancez les commandes suivantes :
```console
# Exporter le projet pour se débarrasser de .git/, etc.
mkdir $TMPDIR/my-prepared-app
git archive HEAD | tar -x -C $TMPDIR/my-prepared-app
cd $TMPDIR/my-prepared-app
# Définir les variables d'environnement appropriées
echo APP_ENV=prod > .env.local
echo APP_DEBUG=0 >> .env.local
# Supprimer les tests
rm -Rf tests/
# Installer les dépendances
composer install --ignore-platform-reqs --no-dev -a
# Optimiser le .env
composer dump-env prod
```
## Créer un binaire Linux
La manière la plus simple de créer un binaire Linux est d'utiliser le builder basé sur Docker que nous fournissons.
1. Créez un fichier nommé `static-build.Dockerfile` dans le répertoire de votre application préparée :
```dockerfile
FROM --platform=linux/amd64 dunglas/frankenphp:static-builder
# Copy your app
WORKDIR /go/src/app/dist/app
COPY . .
# Build the static binary, be sure to select only the PHP extensions you want
WORKDIR /go/src/app/
RUN EMBED=dist/app/ \
PHP_EXTENSIONS=ctype,iconv,pdo_sqlite \
./build-static.sh
```
2. Construisez:
```console
docker build -t static-app -f static-build.Dockerfile .
```
3. Extrayez le binaire :
```console
docker cp $(docker create --name static-app-tmp static-app):/go/src/app/dist/frankenphp-linux-x86_64 my-app ; docker rm static-app-tmp
```
Le binaire généré sera nommé `my-app` dans le répertoire courant.
## Créer un binaire pour d'autres systèmes d'exploitation
Si vous ne souhaitez pas utiliser Docker, ou souhaitez construire un binaire macOS, utilisez le script shell que nous fournissons :
```console
git clone https://github.com/dunglas/frankenphp
cd frankenphp
EMBED=/path/to/your/app \
PHP_EXTENSIONS=ctype,iconv,pdo_sqlite \
./build-static.sh
```
Le binaire obtenu est le fichier nommé `frankenphp-<os>-<arch>` dans le répertoire `dist/`.
## Utiliser le binaire
C'est tout ! Le fichier `my-app` (ou `dist/frankenphp-<os>-<arch>` sur d'autres systèmes d'exploitation) contient votre application autonome !
Pour démarrer l'application web, exécutez :
```console
./my-app php-server
```
Si votre application contient un [script worker](worker.md), démarrez le worker avec quelque chose comme :
```console
./my-app php-server --worker public/index.php
```
Pour activer HTTPS (un certificat Let's Encrypt est automatiquement créé), HTTP/2 et HTTP/3, spécifiez le nom de domaine à utiliser :
```console
./my-app php-server --domain localhost
```
Vous pouvez également exécuter les scripts CLI PHP incorporés dans votre binaire :
```console
./my-app php-cli bin/console
```
## Personnaliser la compilation
[Consultez la documentation sur la compilation statique](static.md) pour voir comment personnaliser le binaire (extensions, version PHP...).
## Distribuer le binaire
Sous Linux, le binaire est compressé par défaut à l'aide de [UPX](https://upx.github.io).
Sous Mac, pour réduire la taille du fichier avant de l'envoyer, vous pouvez le compresser.
Nous recommandons `xz`.

31
docs/fr/github-actions.md Normal file
View File

@@ -0,0 +1,31 @@
# Utilisation de GitHub Actions
Ce dépôt construit et déploie l'image Docker sur [le Hub Docker](https://hub.docker.com/r/dunglas/frankenphp) pour
chaque pull request approuvée ou sur votre propre fork une fois configuré.
## Configuration de GitHub Actions
Dans les paramètres du dépôt, sous "secrets", ajoutez les secrets suivants :
- `REGISTRY_LOGIN_SERVER` : Le registre Docker à utiliser (par exemple, `docker.io`).
- `REGISTRY_USERNAME` : Le nom d'utilisateur à utiliser pour se connecter au registre (par exemple, `dunglas`).
- `REGISTRY_PASSWORD` : Le mot de passe à utiliser pour se connecter au registre (par exemple, une clé d'accès).
- `IMAGE_NAME` : Le nom de l'image (par exemple, `dunglas/frankenphp`).
## Construction et push de l'image
1. Créez une Pull Request ou poussez vers votre fork.
2. GitHub Actions va construire l'image et exécuter tous les tests.
3. Si la construction est réussie, l'image sera poussée vers le registre en utilisant le tag `pr-x`, où `x` est le numéro de la PR.
## Déploiement de l'image
1. Une fois la Pull Request fusionnée, GitHub Actions exécutera à nouveau les tests et construira une nouvelle image.
2. Si la construction est réussie, le tag `main` sera mis à jour dans le registre Docker.
## Releases
1. Créez un nouveau tag dans le dépôt.
2. GitHub Actions va construire l'image et exécuter tous les tests.
3. Si la compilation est réussie, l'image sera poussée vers le registre en utilisant le nom du tag comme tag (par exemple, `v1.2.3` et `v1.2` seront créés).
4. Le tag `latest` sera également mis à jour.

98
docs/fr/known-issues.md Normal file
View File

@@ -0,0 +1,98 @@
# Problèmes Connus
## Fibres
Appeller de fonctions et mots clefs PHP qui eux-mêmes appellent [cgo](https://go.dev/blog/cgo) dans des [Fibres](https://www.php.net/manual/fr/language.fibers.php) est connu pour provoquer des plantages.
Ce problème est [en cours de correction par le projet Go](https://github.com/golang/go/issues/62130).
En attendant, une solution consiste à ne pas utiliser de mots clefs (comme `echo`) et de fonctions (comme `header()`) qui délèguent à Go depuis l'intérieur de fibres.
Ce code risque de planter car il utilise `echo` dans une fibre :
```php
$fiber = new Fiber(function() {
echo 'Dans la fibre'.PHP_EOL;
echo 'Toujours dedans'.PHP_EOL;
});
$fiber->start();
```
A la place, retournez la valeur de la Fibre et utilisez-la à l'extérieur :
```php
$fiber = new Fiber(function() {
Fiber::suspend('Dans la fibre'.PHP_EOL));
Fiber::suspend('Toujours dedans'.PHP_EOL));
});
echo $fiber->start();
echo $fiber->resume();
$fiber->resume();
```
## Extensions PHP non prises en charge
Les extensions suivantes sont connues pour ne pas être compatibles avec FrankenPHP :
| Nom | Raison | Alternatives |
|-------------------------------------------------------------|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| [imap](https://www.php.net/manual/fr/imap.installation.php) | Non sécurisé pour l'exécution en parallèle | [javanile/php-imap2](https://github.com/javanile/php-imap2), [webklex/php-imap](https://github.com/Webklex/php-imap) |
## get_browser
La fonction [get_browser()](https://www.php.net/manual/fr/function.get-browser.php) semble avoir de mauvaises performances après un certain temps. Une solution est de mettre en cache (par exemple, avec [APCu](https://www.php.net/manual/en/book.apcu.php)) les résultats par agent utilisateur, car ils sont statiques.
## Binaire autonome et images Docker basées sur Alpine
Le binaire autonome et les images docker basées sur Alpine (`dunglas/frankenphp:*-alpine`) utilisent [musl libc](https://musl.libc.org/) au lieu de [glibc et ses amis](https://www.etalabs.net/compare_libcs.html), pour garder une taille de binaire plus petite. Cela peut entraîner des problèmes de compatibilité. En particulier, le drapeau glob `GLOB_BRACE` n'est [pas disponible](https://www.php.net/manual/fr/function.glob.php).
## Utilisation de `https://127.0.0.1` avec Docker
Par défaut, FrankenPHP génère un certificat TLS pour `localhost`.
C'est l'option est la plus simple et est recommandée pour le développement local.
Si vous voulez vraiment utiliser `127.0.0.1` comme hôte, il est possible de configure FrankenPHP pour générer un certificat pour cela en définissant le nom du serveur à `127.0.0.1`.
Malheureusement, cela ne suffit pas lors de l'utilisation de Docker à cause de [son système de gestion des réseaux](https://docs.docker.com/network/).
Vous obtiendrez une erreur TLS similaire à `curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error`.
Si vous utilisez Linux, une solution est d'utiliser [le pilote de réseau "hôte"](https://docs.docker.com/network/network-tutorial-host/) :
```console
docker run \
-e SERVER_NAME="127.0.0.1" \
-v $PWD:/app/public \
--network host \
dunglas/frankenphp
```
Le pilote de réseau "hôte" n'est pas pris en charge sur Mac et Windows. Sur ces plateformes, vous devrez deviner l'adresse IP du conteneur et l'inclure dans les noms de serveur.
Exécutez la commande `docker network inspect bridge` et inpectez la clef `Containers` pour identifier la dernière adresse IP attribuée sous la clef `IPv4Address`, puis incrémentez-la de un. Si aucun conteneur n'est en cours d'exécution, la première adresse IP attribuée est généralement `172.17.0.2`.
Ensuite, incluez ceci dans la variable d'environnement `SERVER_NAME` :
```console
docker run \
-e SERVER_NAME="127.0.0.1, 172.17.0.3" \
-v $PWD:/app/public \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```
> ![CAUTION]
>
> Assurez-vous de remplacer `172.17.0.3` par l'IP qui sera attribuée à votre conteneur.
Vous devriez maintenant pouvoir accéder à `https://127.0.0.1` depuis la machine hôte.
Si ce n'est pas le cas, lancez FrankenPHP en mode debug pour essayer de comprendre le problème :
```console
docker run \
-e CADDY_GLOBAL_OPTIONS="debug"
-e SERVER_NAME="127.0.0.1" \
-v $PWD:/app/public \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```

76
docs/fr/laravel.md Normal file
View File

@@ -0,0 +1,76 @@
# Laravel
## Docker
Déployer une application web [Laravel](https://laravel.com) avec FrankenPHP est très facile.
Il suffit de monter le projet dans le répertoire `/app` de l'image Docker officielle.
Exécutez cette commande depuis le répertoire principal de votre application Laravel :
```console
docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp
```
Et profitez !
## Installation Locale
Vous pouvez également exécuter vos projets Laravel avec FrankenPHP depuis votre machine locale :
1. [Téléchargez le binaire correspondant à votre système](https://github.com/dunglas/frankenphp/releases)
2. Ajoutez la configuration suivante dans un fichier nommé `Caddyfile` placé dans le répertoire racine de votre projet Laravel :
```caddyfile
{
frankenphp
order php_server before file_server
}
# Le nom de domaine de votre serveur
localhost {
# Définir le répertoire racine sur le dossier public/
root * public/
# Autoriser la compression (optionnel)
encode zstd br gzip
# Exécuter les scripts PHP du dossier public/ et servir les assets
php_server
}
```
3. Démarrez FrankenPHP depuis le répertoire racine de votre projet Laravel : `./frankenphp run`
## Laravel Octane
Octane peut être installé via le gestionnaire de paquets Composer :
```console
composer require laravel/octane
```
Après avoir installé Octane, vous pouvez exécuter la commande Artisan `octane:install`, qui installera le fichier de configuration d'Octane dans votre application :
```console
php artisan octane:install --server=frankenphp
```
Le serveur Octane peut être démarré via la commande Artisan `octane:start`.
```console
php artisan octane:start
```
La commande `octane:start` peut prendre les options suivantes :
* `--host` : L'adresse IP à laquelle le serveur doit se lier (par défaut : `127.0.0.1`)
* `--port` : Le port sur lequel le serveur doit être disponible (par défaut : `8000`)
* `--admin-port` : Le port sur lequel le serveur administratif doit être disponible (par défaut : `2019`)
* `--workers` : Le nombre de workers qui doivent être disponibles pour traiter les requêtes (par défaut : `auto`)
* `--max-requests` : Le nombre de requêtes à traiter avant de recharger le serveur (par défaut : `500`)
* `--caddyfile` : Le chemin vers le fichier `Caddyfile` de FrankenPHP
* `--https` : Activer HTTPS, HTTP/2, et HTTP/3, et générer automatiquement et renouveler les certificats
* `--http-redirect` : Activer la redirection HTTP vers HTTPS (uniquement activé si --https est passé)
* `--watch` : Recharger automatiquement le serveur lorsque l'application est modifiée
* `--poll` : Utiliser le sondage du système de fichiers pendant la surveillance pour surveiller les fichiers sur un réseau
* `--log-level` : Enregistrer les messages au niveau de journalisation spécifié ou au-dessus
En savoir plus sur Laravel Octane [dans sa documentation officielle](https://laravel.com/docs/octane).

12
docs/fr/mercure.md Normal file
View File

@@ -0,0 +1,12 @@
# Temps Réel
FrankenPHP est livré avec un hub [Mercure](https://mercure.rocks) intégré.
Mercure permet de pousser des événements en temps réel vers tous les appareils connectés : ils recevront un événement JavaScript instantanément.
Aucune bibliothèque JS ou SDK requis !
![Mercure](https://mercure.rocks/static/main.png)
Pour activer le hub Mercure, mettez à jour le `Caddyfile` comme décrit [sur le site de Mercure](https://mercure.rocks/docs/hub/config).
Pour pousser des mises à jour Mercure depuis votre code, nous recommandons le [Composant Mercure de Symfony](https://symfony.com/components/Mercure) (vous n'avez pas besoin du framework full stack Symfony pour l'utiliser).

136
docs/fr/production.md Normal file
View File

@@ -0,0 +1,136 @@
# Déploiement en Production
Dans ce tutoriel, nous apprendrons comment déployer une application PHP sur un serveur unique en utilisant Docker Compose.
Si vous utilisez Symfony, lisez plutôt la page de documentation "[Déployer en production](https://github.com/dunglas/symfony-docker/blob/main/docs/production.md)" du projet Symfony Docker (qui utilise FrankenPHP).
Si vous utilisez API Platform (qui utilise également FrankenPHP), référez-vous à [la documentation de déploiement du framework](https://api-platform.com/docs/deployment/).
## Préparer votre application
Tout d'abord, créez un `Dockerfile` dans le répertoire racine de votre projet PHP :
```dockerfile
FROM dunglas/frankenphp
# Assurez-vous de remplacer "your-domain-name.example.com" par votre nom de domaine
ENV SERVER_NAME=your-domain-name.example.com
# Si vous souhaitez désactiver HTTPS, utilisez cette valeur à la place :
#ENV SERVER_NAME=:80
# Activer les paramètres de production de PHP
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Copiez les fichiers PHP de votre projet dans le répertoire public
COPY . /app/public
# Si vous utilisez Symfony ou Laravel, vous devez copier l'intégralité du projet à la place :
#COPY . /app
```
Consultez "[Construire une image Docker personnalisée](docker.md)" pour plus de détails et d'options,
et pour apprendre à personnaliser la configuration, installer des extensions PHP et des modules Caddy.
Si votre projet utilise Composer, assurez-vous de l'inclure dans l'image Docker et d'installer vos dépendances.
Ensuite, ajoutez un fichier `compose.yaml` :
```yaml
services:
php:
image: dunglas/frankenphp
restart: always
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "443:443/udp" # HTTP/3
volumes:
- caddy_data:/data
- caddy_config:/config
# Volumes nécessaires pour les certificats et la configuration de Caddy
volumes:
caddy_data:
caddy_config:
```
> [!NOTE]
> Les exemples précédents sont destinés à une utilisation en production.
> En développement, vous pourriez vouloir utiliser un volume, une configuration PHP différente et une valeur différente pour la variable d'environnement `SERVER_NAME`.
>
> Jetez un œil au projet [Symfony Docker](https://github.com/dunglas/symfony-docker)
> (qui utilise FrankenPHP) pour un exemple plus avancé utilisant des images multi-étapes,
> Composer, des extensions PHP supplémentaires, etc.
Pour finir, si vous utilisez Git, commitez ces fichiers et poussez-les.
## Préparer un serveur
Pour déployer votre application en production, vous avez besoin d'un serveur.
Dans ce tutoriel, nous utiliserons une machine virtuelle fournie par DigitalOcean, mais n'importe quel serveur Linux peut fonctionner.
Si vous avez déjà un serveur Linux avec Docker installé, vous pouvez passer directement à [la section suivante](#configurer-un-nom-de-domaine).
Sinon, utilisez [ce lien affilié](https://m.do.co/c/5d8aabe3ab80) pour obtenir 200$ de crédit gratuit, créez un compte, puis cliquez sur "Créer un Droplet".
Ensuite, cliquez sur l'onglet "Marketplace" sous la section "Choisir une image" et recherchez l'application nommée "Docker".
Cela provisionnera un serveur Ubuntu avec les dernières versions de Docker et Docker Compose déjà installées !
Pour des fins de test, les plans les moins chers seront suffisants.
Pour une utilisation en production réelle, vous voudrez probablement choisir un plan dans la section "General Usage" pour répondre à vos besoins.
![Déployer FrankenPHP sur DigitalOcean avec Docker](../digitalocean-droplet.png)
Vous pouvez conserver les paramètres par défaut pour les autres paramètres, ou les ajuster selon vos besoins.
N'oubliez pas d'ajouter votre clé SSH ou de créer un mot de passe puis appuyez sur le bouton "Finalize and create".
Ensuite, attendez quelques secondes pendant que votre Droplet est en cours de provisionnement.
Lorsque votre Droplet est prêt, utilisez SSH pour vous connecter :
```console
ssh root@<droplet-ip>
```
## Configurer un nom de domaine
Dans la plupart des cas, vous souhaiterez associer un nom de domaine à votre site.
Si vous ne possédez pas encore de nom de domaine, vous devrez en acheter un via un registraire.
Ensuite, créez un enregistrement DNS de type `A` pour votre nom de domaine pointant vers l'adresse IP de votre serveur :
```dns
your-domain-name.example.com. IN A 207.154.233.113
```
Exemple avec le service DigitalOcean Domains ("Networking" > "Domains") :
![Configurer les DNS sur DigitalOcean](../digitalocean-dns.png)
> [!NOTE]
> Let's Encrypt, le service utilisé par défaut par FrankenPHP pour générer automatiquement un certificat TLS, ne prend pas en charge l'utilisation d'adresses IP nues. L'utilisation d'un nom de domaine est obligatoire pour utiliser Let's Encrypt.
## Déploiement
Copiez votre projet sur le serveur en utilisant `git clone`, `scp`, ou tout autre outil qui pourrait répondre à votre besoin.
Si vous utilisez GitHub, vous voudrez peut-être utiliser [une clef de déploiement](https://docs.github.com/en/free-pro-team@latest/developers/overview/managing-deploy-keys#deploy-keys).
Les clés de déploiement sont également [prises en charge par GitLab](https://docs.gitlab.com/ee/user/project/deploy_keys/).
Exemple avec Git :
```console
git clone git@github.com:<username>/<project-name>.git
```
Accédez au répertoire contenant votre projet (`<project-name>`), et démarrez l'application en mode production :
```console
docker compose up -d --wait
```
Votre serveur est opérationnel, et un certificat HTTPS a été automatiquement généré pour vous.
Rendez-vous sur `https://your-domain-name.example.com` !
> [!CAUTION]
> Docker peut avoir une couche de cache, assurez-vous d'avoir la bonne version de build pour chaque déploiement ou reconstruisez votre projet avec l'option `--no-cache` pour éviter les problèmes de cache.
## Déploiement sur Plusieurs Nœuds
Si vous souhaitez déployer votre application sur un cluster de machines, vous pouvez utiliser [Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/), qui est compatible avec les fichiers Compose fournis.
Pour un déploiement sur Kubernetes, jetez un œil au [Helm chart fourni avec API Platform](https://api-platform.com/docs/deployment/kubernetes/), qui utilise FrankenPHP.

79
docs/fr/static.md Normal file
View File

@@ -0,0 +1,79 @@
# Créer un binaire statique
Au lieu d'utiliser une installation locale de la bibliothèque PHP, il est possible de créer un build statique de FrankenPHP grâce à l'excellent projet [static-php-cli](https://github.com/crazywhalecc/static-php-cli) (malgré son nom, ce projet prend en charge tous les SAPIs, pas seulement CLI).
Avec cette méthode, un binaire portable unique contiendra l'interpréteur PHP, le serveur web Caddy et FrankenPHP !
FrankenPHP permet également [d'embarquer l'application PHP dans le binaire statique](embed.md).
## Linux
Nous fournissons une image Docker pour créer un binaire statique pour Linux :
```console
docker buildx bake --load static-builder
docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder
```
Le binaire statique résultant est nommé `frankenphp`, et il est disponible dans le répertoire courant.
Si vous souhaitez construire le binaire statique sans Docker, regardez les instructions pour macOS, qui fonctionnent également pour Linux.
### Extensions personnalisées
Par défaut, la plupart des extensions PHP populaires sont compilées.
Pour réduire la taille du binaire et diminuer la surface d'attaque, vous pouvez choisir la liste des extensions à construire en utilisant l'argument Docker `PHP_EXTENSIONS`.
Par exemple, exécutez la commande suivante pour ne construire que l'extension `opcache` :
```console
docker buildx bake --load --set static-builder.args.PHP_EXTENSIONS=opcache,pdo_sqlite static-builder
# ...
```
Pour ajouter des bibliothèques permettant des fonctionnalités supplémentaires aux extensions que vous avez activées, vous pouvez utiliser l'argument Docker `PHP_EXTENSION_LIBS` :
```console
docker buildx bake \
--load \
--set static-builder.args.PHP_EXTENSIONS=gd \
--set static-builder.args.PHP_EXTENSION_LIBS=libjpeg,libwebp \
static-builder
```
Voir aussi comment [personnaliser la construction](#personnalisation-de-la-construction)
### Jeton GitHub
Si vous atteignez la limite de taux d'appels de l'API GitHub, définissez un jeton d'accès personnel GitHub dans une variable d'environnement nommée `GITHUB_TOKEN` :
```console
GITHUB_TOKEN="xxx" docker --load buildx bake static-builder
# ...
```
## macOS
Exécutez le script suivant pour créer un binaire statique pour macOS (vous devez avoir [Homebrew](https://brew.sh/) d'installé) :
```console
git clone https://github.com/dunglas/frankenphp
cd frankenphp
./build-static.sh
```
Note : ce script fonctionne également sur Linux (et probablement sur d'autres Unix) et est utilisé en interne par le builder statique basé sur Docker que nous fournissons.
## Personnalisation de la construction
Les variables d'environnement suivantes peuvent être transmises à `docker build` et au script `build-static.sh` pour personnaliser la construction statique :
* `FRANKENPHP_VERSION` : la version de FrankenPHP à utiliser
* `PHP_VERSION` : la version de PHP à utiliser
* `PHP_EXTENSIONS` : les extensions PHP à construire ([liste des extensions prises en charge](https://static-php.dev/en/guide/extensions.html))
* `PHP_EXTENSION_LIBS` : bibliothèques supplémentaires à construire qui ajoutent des fonctionnalités aux extensions
* `EMBED` : chemin de l'application PHP à intégrer dans le binaire
* `CLEAN` : lorsque défini, `libphp` et toutes ses dépendances sont construites à partir de zéro (pas de cache)
* `DEBUG_SYMBOLS` : lorsque défini, les symboles de débogage ne seront pas supprimés et seront ajoutés dans le binaire
* `RELEASE` : (uniquement pour les mainteneurs) lorsque défini, le binaire résultant sera uploadé sur GitHub

119
docs/fr/worker.md Normal file
View File

@@ -0,0 +1,119 @@
# Utilisation des workers FrankenPHP
Démarrez votre application une fois et gardez-la en mémoire.
FrankenPHP traitera les requêtes entrantes en quelques millisecondes.
## Démarrage des scripts workers
### Docker
Définissez la valeur de la variable d'environnement `FRANKENPHP_CONFIG` à `worker /path/to/your/worker/script.php` :
```console
docker run \
-e FRANKENPHP_CONFIG="worker /app/path/to/your/worker/script.php" \
-v $PWD:/app \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```
### Binaire autonome
Utilisez l'option --worker de la commande php-server pour servir le contenu du répertoire courant en utilisant un worker :
```console
./frankenphp php-server --worker /path/to/your/worker/script.php
```
Si votre application PHP est [intégrée dans le binaire](embed.md), vous pouvez également ajouter un `Caddyfile` personnalisé dans le répertoire racine de l'application.
Il sera utilisé automatiquement.
## Runtime Symfony
Le mode worker de FrankenPHP est pris en charge par le [Composant Runtime de Symfony](https://symfony.com/doc/current/components/runtime.html).
Pour démarrer une application Symfony dans un worker, installez le package FrankenPHP de [PHP Runtime](https://github.com/php-runtime/runtime) :
```console
composer require runtime/frankenphp-symfony
```
Démarrez votre serveur d'application en définissant la variable d'environnement `APP_RUNTIME` pour utiliser le Runtime Symfony de FrankenPHP :
```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
```
## Laravel Octane
Voir [la documentation dédiée](laravel.md#laravel-octane).
## Applications Personnalisées
L'exemple suivant montre comment créer votre propre script worker sans dépendre d'une bibliothèque tierce :
```php
<?php
// public/index.php
// Empêcher la terminaison du script worker lorsqu'une connexion client est interrompue
ignore_user_abort(true);
// Démarrer votre application
require __DIR__.'/vendor/autoload.php';
$myApp = new \App\Kernel();
$myApp->boot();
// En dehors de la boucle pour de meilleures performances (moins de travail effectué)
$handler = static function () use ($myApp) {
// Appelé lorsqu'une requête est reçue,
// les superglobales, php://input, etc., sont réinitialisés
echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
};
for($nbRequests = 0, $running = true; isset($_SERVER['MAX_REQUESTS']) && ($nbRequests < ((int)$_SERVER['MAX_REQUESTS'])) && $running; ++$nbRequests) {
$running = \frankenphp_handle_request($handler);
// Faire quelque chose après l'envoi de la réponse HTTP
$myApp->terminate();
// Exécuter le ramasse-miettes pour réduire les chances qu'il soit déclenché au milieu de la génération d'une page
gc_collect_cycles();
}
// Nettoyage
$myApp->shutdown();
```
Ensuite, démarrez votre application et utilisez la variable d'environnement `FRANKENPHP_CONFIG` pour configurer votre worker :
```console
docker run \
-e FRANKENPHP_CONFIG="worker ./public/index.php" \
-v $PWD:/app \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```
Par défaut, 2 workers par CPU sont démarrés.
Vous pouvez également configurer le nombre de workers à démarrer :
```console
docker run \
-e FRANKENPHP_CONFIG="worker ./public/index.php 42" \
-v $PWD:/app \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphp
```
### Redémarrer le worker après un certain nombre de requêtes
Comme PHP n'a pas été initialement conçu pour des processus de longue durée, de nombreuses bibliothèques et codes anciens présentent encore des fuites de mémoire.
Une solution pour utiliser ce type de code en mode worker est de redémarrer le script worker après avoir traité un certain nombre de requêtes :
Le code du worker précédent permet de configurer un nombre maximal de requêtes à traiter en définissant une variable d'environnement nommée `MAX_REQUESTS`.

View File

@@ -12,15 +12,15 @@ In the repository settings, under secrets, add the following secrets:
- `REGISTRY_PASSWORD`: The password to use to login to the registry (e.g. an access key).
- `IMAGE_NAME`: The name of the image (e.g. `dunglas/frankenphp`).
## Building and pushing the image
## Building and Pushing the Image
1. Create a pull request or push to your fork.
1. Create a Pull Request or push to your fork.
2. GitHub Actions will build the image and run any tests.
3. If the build is successful, the image will be pushed to the registry using the `pr-x`, where `x` is the PR number, as the tag.
## Deploying the image
## Deploying the Image
1. Once the pull request is merged, GitHub Actions will again run the tests and build a new image.
1. Once the Pull Request is merged, GitHub Actions will again run the tests and build a new image.
2. If the build is successful, the `main` tag will be updated in the Docker registry.
## Releases

View File

@@ -40,7 +40,7 @@ The following extensions are known not to be compatible with FrankenPHP:
## get_browser
The [get_browser()](https://www.php.net/manual/en/function.get-browser.php) function seems to perform badly after a while. A workaround is to cache (e.g. with APCU) the results per User Agent, as they are static.
The [get_browser()](https://www.php.net/manual/en/function.get-browser.php) function seems to perform badly after a while. A workaround is to cache (e.g. with [APCu](https://www.php.net/manual/en/book.apcu.php)) the results per User Agent, as they are static.
## Standalone Binary and Alpine-based Docker Images

View File

@@ -27,11 +27,11 @@ Alternatively, you can run your Laravel projects with FrankenPHP from your local
# The domain name of your server
localhost {
# Set the webroot to the public/ dir
# Set the webroot to the public/ directory
root * public/
# Enable compression (optional)
encode zstd br gzip
# Execute PHP files in the current directory and serve assets
# Execute PHP files from the public/ directory and serve assets
php_server
}
```

View File

@@ -1,6 +1,6 @@
# Real-time
FrankenPHP comes with a built-in Mercure hub!
FrankenPHP comes with a built-in [Mercure](https://mercure.rocks) hub!
Mercure allows to push events in real-time to all the connected devices: they will receive a JavaScript event instantly.
No JS library or SDK required!

View File

@@ -129,10 +129,10 @@ Your server is up and running, and a HTTPS certificate has been automatically ge
Go to `https://your-domain-name.example.com` and enjoy!
> [!CAUTION]
> Docker can have a cache layer, make sure you have the right build for each deployment or rebuild your project with --no-cache option to avoid cache issue.
> Docker can have a cache layer, make sure you have the right build for each deployment or rebuild your project with `--no-cache` option to avoid cache issue.
## Deploying on Multiple Nodes
If you want to deploy your app on a cluster of machines, you can use [Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/),
which is compatible with the provided Compose files.
To deploy on Kubernetes, take a look at [the Helm chart provided with API Platform](https://api-platform.com/docs/deployment/kubernetes/), which can be easily adapted for use with Symfony Docker.
To deploy on Kubernetes, take a look at [the Helm chart provided with API Platform](https://api-platform.com/docs/deployment/kubernetes/), which uses FrankenPHP.

View File

@@ -43,7 +43,7 @@ docker buildx bake \
static-builder
```
See also: [customizing the build](#customizing-the-build)
See also how to [customize the build](#customizing-the-build)
### GitHub Token
@@ -74,7 +74,7 @@ script to customize the static build:
* `FRANKENPHP_VERSION`: the version of FrankenPHP to use
* `PHP_VERSION`: the version of PHP to use
* `PHP_EXTENSIONS`: the PHP extensions to build ([list of supported extensions](https://static-php.dev/en/guide/extensions.html))
* `PHP_EXTENSION_LIBS`: extra libraries to build that add extra features to the extensions
* `PHP_EXTENSION_LIBS`: extra libraries to build that add features to the extensions
* `EMBED`: path of the PHP application to embed in the binary
* `CLEAN`: when set, libphp and all its dependencies are built from scratch (no cache)
* `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added within the binary

View File

@@ -25,6 +25,9 @@ Use the `--worker` option of the `php-server` command to serve the content of th
./frankenphp php-server --worker /path/to/your/worker/script.php
```
If your PHP app is [embeded in the binary](embed.md), you can add a custom `Caddyfile` in the root directory of the app.
It will be used automatically.
## Symfony Runtime
The worker mode of FrankenPHP is supported by the [Symfony Runtime Component](https://symfony.com/doc/current/components/runtime.html).
@@ -72,6 +75,7 @@ $handler = static function () use ($myApp) {
// superglobals, php://input and the like are reset
echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
};
for($nbRequests = 0, $running = true; isset($_SERVER['MAX_REQUESTS']) && ($nbRequests < ((int)$_SERVER['MAX_REQUESTS'])) && $running; ++$nbRequests) {
$running = \frankenphp_handle_request($handler);
@@ -81,6 +85,7 @@ for($nbRequests = 0, $running = true; isset($_SERVER['MAX_REQUESTS']) && ($nbReq
// Call the garbage collector to reduce the chances of it being triggered in the middle of a page generation
gc_collect_cycles();
}
// Cleanup
$myApp->shutdown();
```
@@ -95,7 +100,7 @@ docker run \
dunglas/frankenphp
```
By default, one worker per CPU is started.
By default, 2 workers per CPU are started.
You can also configure the number of workers to start:
```console