From 09922b51a65e24e39b194e7d5eb9b36a6f9b5bc9 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Sun, 23 Mar 2025 09:41:06 +0700 Subject: [PATCH 01/11] add glibc based static builder to documentation --- docs/static.md | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/docs/static.md b/docs/static.md index 2aa768c35d..c643b58571 100644 --- a/docs/static.md +++ b/docs/static.md @@ -9,16 +9,37 @@ FrankenPHP also supports [embedding the PHP app in the static binary](embed.md). ## Linux -We provide a Docker image to build a Linux static binary: +We provide Docker images to build static Linux binaries: + +### musl-based static build (fully static) + +For a fully static binary that runs on any Linux distribution without dependencies but doesn't support dynamic loading of extensions: + +```console +docker buildx bake --load static-builder-musl +docker cp $(docker create --name static-builder-musl dunglas/frankenphp:static-builder-musl):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder-musl +``` + +For better performance in heavily concurrent scenarios, consider using the [mimalloc](https://github.com/microsoft/mimalloc) allocator. ```console -docker buildx bake --load static-builder -docker cp $(docker create --name static-builder-musl dunglas/frankenphp:static-builder-musl):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder +docker buildx bake --load --set static-builder-musl.args.MIMALLOC=1 static-builder-musl ``` +### glibc-based static build (with dynamic extension support) + +For a binary that supports loading PHP extensions dynamically while still having the selected extensions compiled statically: + +```console +docker buildx bake --load static-builder-gnu +docker cp $(docker create --name static-builder-gnu dunglas/frankenphp:static-builder-gnu):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder-gnu +``` + +This binary supports all glibc versions >= 2.17 but does not run on musl-based systems (like Alpine Linux). + The resulting static binary is named `frankenphp` and is available in the current directory. -If you want to build the static binary without Docker, take a look at the macOS instructions, which also works for Linux. +If you want to build the static binary without Docker, take a look at the macOS instructions, which also work for Linux. ### Custom Extensions @@ -29,7 +50,7 @@ To reduce the size of the binary and to reduce the attack surface, you can choos For instance, run the following command to only build the `opcache` extension: ```console -docker buildx bake --load --set static-builder.args.PHP_EXTENSIONS=opcache,pdo_sqlite static-builder +docker buildx bake --load --set static-builder-musl.args.PHP_EXTENSIONS=opcache,pdo_sqlite static-builder-musl # ... ``` @@ -38,9 +59,9 @@ To add libraries enabling additional functionality to the extensions you've enab ```console docker buildx bake \ --load \ - --set static-builder.args.PHP_EXTENSIONS=gd \ - --set static-builder.args.PHP_EXTENSION_LIBS=libjpeg,libwebp \ - static-builder + --set static-builder-musl.args.PHP_EXTENSIONS=gd \ + --set static-builder-musl.args.PHP_EXTENSION_LIBS=libjpeg,libwebp \ + static-builder-musl ``` ### Extra Caddy Modules @@ -50,8 +71,8 @@ To add extra Caddy modules or pass other arguments to [xcaddy](https://github.co ```console docker buildx bake \ --load \ - --set static-builder.args.XCADDY_ARGS="--with github.com/darkweak/souin/plugins/caddy --with github.com/dunglas/caddy-cbrotli --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy" \ - static-builder + --set static-builder-musl.args.XCADDY_ARGS="--with github.com/darkweak/souin/plugins/caddy --with github.com/dunglas/caddy-cbrotli --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy" \ + static-builder-musl ``` In this example, we add the [Souin](https://souin.io) HTTP cache module for Caddy as well as the [cbrotli](https://github.com/dunglas/caddy-cbrotli), [Mercure](https://mercure.rocks) and [Vulcain](https://vulcain.rocks) modules. @@ -68,7 +89,7 @@ See also how to [customize the build](#customizing-the-build) If you hit the GitHub API rate limit, set a GitHub Personal Access Token in an environment variable named `GITHUB_TOKEN`: ```console -GITHUB_TOKEN="xxx" docker --load buildx bake static-builder +GITHUB_TOKEN="xxx" docker --load buildx bake static-builder-musl # ... ``` @@ -82,7 +103,7 @@ cd frankenphp ./build-static.sh ``` -Note: this script also works on Linux (and probably on other Unixes), and is used internally by the Docker based static builder we provide. +Note: this script also works on Linux, and is used internally by the Docker images we provide. ## Customizing The Build @@ -98,5 +119,5 @@ script to customize the static build: * `CLEAN`: when set, libphp and all its dependencies are built from scratch (no cache) * `NO_COMPRESS`: don't compress the resulting binary using UPX * `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added within the binary -* `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance +* `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance. We only recommend using this for musl targeting builds, for glibc prefer disabling this option and using LD_PRELOAD when you run your binary instead. * `RELEASE`: (maintainers only) when set, the resulting binary will be uploaded on GitHub From 580e2a5acdb14abe86d7c58ee638d2c8e575a461 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Sun, 23 Mar 2025 12:48:55 +0700 Subject: [PATCH 02/11] english docs for gnu/extensions --- docs/performance.md | 15 +++++++-------- docs/static.md | 27 +++++++++++++++++++++++++++ static-builder-gnu.Dockerfile | 3 +-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/docs/performance.md b/docs/performance.md index 6e6d55e6ad..876b10fe86 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -32,21 +32,20 @@ Enabling [the worker mode](worker.md) dramatically improves performance, but your app must be adapted to be compatible with this mode: you need to create a worker script and to be sure that the app is not leaking memory. -## Don't Use musl +## Don't use musl with the default allocator -The static binaries we provide and the Alpine Linux variant of the official Docker images -are using [the musl libc](https://musl.libc.org). +The Alpine Linux variant of the official Docker images and the default frankenphp-arch binaries on our Releases page are using [the musl libc](https://musl.libc.org). -PHP is known to be [significantly slower](https://gitlab.alpinelinux.org/alpine/aports/-/issues/14381) when using this alternative C library instead of the traditional GNU library, -especially when compiled in ZTS mode (thread-safe), which is required for FrankenPHP. +PHP is known to be [slower](https://gitlab.alpinelinux.org/alpine/aports/-/issues/14381) when using this alternative C library instead of the traditional GNU library, +especially when compiled in ZTS mode (thread-safe), which is required for FrankenPHP. The difference can be significant in a heavily threaded environment. Also, [some bugs only happen when using musl](https://github.com/php/php-src/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen+label%3ABug+musl). -In production environments, we strongly recommend to use the glibc. +In production environments, we recommend using FrankenPHP linked against glibc. -This can be achieved by using the Debian Docker images (the default) and [by compiling FrankenPHP from sources](compile.md). +This can be achieved by using the Debian Docker images (the default), downloading the -gnu suffix binary from our [Releases](https://github.com/dunglas/frankenphp/releases), or by [compiling FrankenPHP from sources](compile.md). -Alternatively, we provide static binaries compiled with [the mimalloc allocator](https://github.com/microsoft/mimalloc), which makes FrankenPHP+musl faster (but still slower than FrankenPHP+glibc). +Alternatively, we provide static musl binaries compiled with [the mimalloc allocator](https://github.com/microsoft/mimalloc), which alleviates the problems in threaded scenarios. ## Go Runtime Configuration diff --git a/docs/static.md b/docs/static.md index c643b58571..baffcb6b38 100644 --- a/docs/static.md +++ b/docs/static.md @@ -121,3 +121,30 @@ script to customize the static build: * `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added within the binary * `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance. We only recommend using this for musl targeting builds, for glibc prefer disabling this option and using LD_PRELOAD when you run your binary instead. * `RELEASE`: (maintainers only) when set, the resulting binary will be uploaded on GitHub + +## Extensions + +With the glibc or mac based binaries, you can load PHP extensions dynamically. However, these extensions will have to be compiled with ZTS support. +Since most package managers do not currently offer ZTS versions of their extensions, you will have to compile them yourself. + +For this, you can create a the static-builder-gnu Docker container, remote into it and compile the extensions with `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config`. + +Example steps: +- `docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 .` +- `docker create --name static-builder-gnu -it gnu-ext /bin/sh` +- `docker start static-builder-gnu` +- `docker exec -it static-builder-gnu /bin/sh` +- `cd /go/src/app/dist/static-php-cli/buildroot/bin` +- `git clone https://github.com/xdebug/xdebug.git && cd xdebug` +- `source scl_source enable devtoolset-10` +- `../phpize` +- `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config` +- `make` +- `exit` +- `docker cp static-builder-gnu:/go/src/app/dist/static-php-cli/buildroot/bin/xdebug/modules/xdebug.so xdebug-zts.so` +- `docker cp static-builder-gnu:/go/src/app/dist/frankenphp-linux-$(uname -m) ./frankenphp` +- `docker stop static-builder-gnu` +- `docker rm static-builder-gnu` +- `docker rmi gnu-ext` + +This will have created `frankenphp` and `xdebug-zts.so` in the current directory. If you move the `xdebug-zts.so` into your extension directory, add `zend_extension=xdebug-zts.so` to your php.ini and run FrankenPHP, it will load xdebug. \ No newline at end of file diff --git a/static-builder-gnu.Dockerfile b/static-builder-gnu.Dockerfile index 120126bb0c..d6b08dc501 100644 --- a/static-builder-gnu.Dockerfile +++ b/static-builder-gnu.Dockerfile @@ -131,5 +131,4 @@ COPY --link *.* ./ COPY --link caddy caddy COPY --link internal internal -RUN --mount=type=secret,id=github-token ./build-static.sh && \ - rm -Rf dist/static-php-cli/source/* +RUN --mount=type=secret,id=github-token ./build-static.sh \ No newline at end of file From bfca953e688fdd2e0d63baca27940c3dc480312f Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Sun, 23 Mar 2025 12:57:59 +0700 Subject: [PATCH 03/11] remove source again --- static-builder-gnu.Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static-builder-gnu.Dockerfile b/static-builder-gnu.Dockerfile index d6b08dc501..8667d8d4d9 100644 --- a/static-builder-gnu.Dockerfile +++ b/static-builder-gnu.Dockerfile @@ -131,4 +131,5 @@ COPY --link *.* ./ COPY --link caddy caddy COPY --link internal internal -RUN --mount=type=secret,id=github-token ./build-static.sh \ No newline at end of file +RUN --mount=type=secret,id=github-token ./build-static.sh && \ + rm -Rf dist/static-php-cli/source/* \ No newline at end of file From 8b902a17bc9df577616076aca87512f224eda332 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Sun, 23 Mar 2025 13:00:37 +0700 Subject: [PATCH 04/11] lint fixes --- docs/static.md | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/docs/static.md b/docs/static.md index baffcb6b38..486a4e6d7a 100644 --- a/docs/static.md +++ b/docs/static.md @@ -130,21 +130,23 @@ Since most package managers do not currently offer ZTS versions of their extensi For this, you can create a the static-builder-gnu Docker container, remote into it and compile the extensions with `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config`. Example steps: -- `docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 .` -- `docker create --name static-builder-gnu -it gnu-ext /bin/sh` -- `docker start static-builder-gnu` -- `docker exec -it static-builder-gnu /bin/sh` -- `cd /go/src/app/dist/static-php-cli/buildroot/bin` -- `git clone https://github.com/xdebug/xdebug.git && cd xdebug` -- `source scl_source enable devtoolset-10` -- `../phpize` -- `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config` -- `make` -- `exit` -- `docker cp static-builder-gnu:/go/src/app/dist/static-php-cli/buildroot/bin/xdebug/modules/xdebug.so xdebug-zts.so` -- `docker cp static-builder-gnu:/go/src/app/dist/frankenphp-linux-$(uname -m) ./frankenphp` -- `docker stop static-builder-gnu` -- `docker rm static-builder-gnu` -- `docker rmi gnu-ext` - -This will have created `frankenphp` and `xdebug-zts.so` in the current directory. If you move the `xdebug-zts.so` into your extension directory, add `zend_extension=xdebug-zts.so` to your php.ini and run FrankenPHP, it will load xdebug. \ No newline at end of file + +* `docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 .` +* `docker create --name static-builder-gnu -it gnu-ext /bin/sh` +* `docker start static-builder-gnu` +* `docker exec -it static-builder-gnu /bin/sh` +* `cd /go/src/app/dist/static-php-cli/buildroot/bin` +* `git clone https://github.com/xdebug/xdebug.git && cd xdebug` +* `source scl_source enable devtoolset-10` +* `../phpize` +* `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config` +* `make` +* `exit` +* `docker cp static-builder-gnu:/go/src/app/dist/static-php-cli/buildroot/bin/xdebug/modules/xdebug.so xdebug-zts.so` +* `docker cp static-builder-gnu:/go/src/app/dist/frankenphp-linux-$(uname -m) ./frankenphp` +* `docker stop static-builder-gnu` +* `docker rm static-builder-gnu` +* `docker rmi gnu-ext` + +This will have created `frankenphp` and `xdebug-zts.so` in the current directory. +If you move the `xdebug-zts.so` into your extension directory, add `zend_extension=xdebug-zts.so` to your php.ini and run FrankenPHP, it will load xdebug. From 0b4d8b97799baa8866d37d323c5671de2c536857 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Sun, 23 Mar 2025 13:10:34 +0700 Subject: [PATCH 05/11] why is there no .editorconfig :( --- static-builder-gnu.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static-builder-gnu.Dockerfile b/static-builder-gnu.Dockerfile index 8667d8d4d9..a3d0e25a0d 100644 --- a/static-builder-gnu.Dockerfile +++ b/static-builder-gnu.Dockerfile @@ -132,4 +132,4 @@ COPY --link caddy caddy COPY --link internal internal RUN --mount=type=secret,id=github-token ./build-static.sh && \ - rm -Rf dist/static-php-cli/source/* \ No newline at end of file + rm -Rf dist/static-php-cli/source/* \ From 92d3a88f6b71f52b61fb307a42d4b4e737797391 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Mon, 24 Mar 2025 17:00:54 +0700 Subject: [PATCH 06/11] apply suggestions --- docs/performance.md | 4 ++-- docs/static.md | 14 ++++++++------ static-builder-gnu.Dockerfile | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/performance.md b/docs/performance.md index 876b10fe86..4b1cc0c166 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -32,9 +32,9 @@ Enabling [the worker mode](worker.md) dramatically improves performance, but your app must be adapted to be compatible with this mode: you need to create a worker script and to be sure that the app is not leaking memory. -## Don't use musl with the default allocator +## Don't use musl -The Alpine Linux variant of the official Docker images and the default frankenphp-arch binaries on our Releases page are using [the musl libc](https://musl.libc.org). +The Alpine Linux variant of the official Docker images and the default binaries we provide are using [the musl libc](https://musl.libc.org). PHP is known to be [slower](https://gitlab.alpinelinux.org/alpine/aports/-/issues/14381) when using this alternative C library instead of the traditional GNU library, especially when compiled in ZTS mode (thread-safe), which is required for FrankenPHP. The difference can be significant in a heavily threaded environment. diff --git a/docs/static.md b/docs/static.md index 486a4e6d7a..fe8714c147 100644 --- a/docs/static.md +++ b/docs/static.md @@ -26,7 +26,7 @@ For better performance in heavily concurrent scenarios, consider using the [mima docker buildx bake --load --set static-builder-musl.args.MIMALLOC=1 static-builder-musl ``` -### glibc-based static build (with dynamic extension support) +### glibc-Based Static Build (With Dynamic Extension Support) For a binary that supports loading PHP extensions dynamically while still having the selected extensions compiled statically: @@ -35,7 +35,7 @@ docker buildx bake --load static-builder-gnu docker cp $(docker create --name static-builder-gnu dunglas/frankenphp:static-builder-gnu):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder-gnu ``` -This binary supports all glibc versions >= 2.17 but does not run on musl-based systems (like Alpine Linux). +This binary supports all glibc versions 2.17 and superior but does not run on musl-based systems (like Alpine Linux). The resulting static binary is named `frankenphp` and is available in the current directory. @@ -103,7 +103,7 @@ cd frankenphp ./build-static.sh ``` -Note: this script also works on Linux, and is used internally by the Docker images we provide. +Note: this script also works on Linux (and probably on other Unixes), and is used internally by the Docker images we provide. ## Customizing The Build @@ -124,13 +124,14 @@ script to customize the static build: ## Extensions -With the glibc or mac based binaries, you can load PHP extensions dynamically. However, these extensions will have to be compiled with ZTS support. +With the glibc or macOS-based binaries, you can load PHP extensions dynamically. However, these extensions will have to be compiled with ZTS support. Since most package managers do not currently offer ZTS versions of their extensions, you will have to compile them yourself. -For this, you can create a the static-builder-gnu Docker container, remote into it and compile the extensions with `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config`. +For this, you can build and run the `static-builder-gnu` Docker container, remote into it, and compile the extensions with `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config`. -Example steps: +Example steps for [the Xdebug extension](https://xdebug.org): +```console * `docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 .` * `docker create --name static-builder-gnu -it gnu-ext /bin/sh` * `docker start static-builder-gnu` @@ -147,6 +148,7 @@ Example steps: * `docker stop static-builder-gnu` * `docker rm static-builder-gnu` * `docker rmi gnu-ext` +``` This will have created `frankenphp` and `xdebug-zts.so` in the current directory. If you move the `xdebug-zts.so` into your extension directory, add `zend_extension=xdebug-zts.so` to your php.ini and run FrankenPHP, it will load xdebug. diff --git a/static-builder-gnu.Dockerfile b/static-builder-gnu.Dockerfile index a3d0e25a0d..120126bb0c 100644 --- a/static-builder-gnu.Dockerfile +++ b/static-builder-gnu.Dockerfile @@ -132,4 +132,4 @@ COPY --link caddy caddy COPY --link internal internal RUN --mount=type=secret,id=github-token ./build-static.sh && \ - rm -Rf dist/static-php-cli/source/* \ + rm -Rf dist/static-php-cli/source/* From a6e4242086a17914495043be681e8cdf4aef3143 Mon Sep 17 00:00:00 2001 From: Marc Date: Mon, 24 Mar 2025 17:03:27 +0700 Subject: [PATCH 07/11] Update docs/static.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kévin Dunglas --- docs/static.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/static.md b/docs/static.md index fe8714c147..7003fdccb4 100644 --- a/docs/static.md +++ b/docs/static.md @@ -119,7 +119,7 @@ script to customize the static build: * `CLEAN`: when set, libphp and all its dependencies are built from scratch (no cache) * `NO_COMPRESS`: don't compress the resulting binary using UPX * `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added within the binary -* `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance. We only recommend using this for musl targeting builds, for glibc prefer disabling this option and using LD_PRELOAD when you run your binary instead. +* `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance. We only recommend using this for musl targeting builds, for glibc prefer disabling this option and using [`LD_PRELOAD`](https://microsoft.github.io/mimalloc/overrides.html) when you run your binary instead. * `RELEASE`: (maintainers only) when set, the resulting binary will be uploaded on GitHub ## Extensions From 4ce1956587c031512d09d64583599e5c257faea2 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Mon, 24 Mar 2025 17:06:22 +0700 Subject: [PATCH 08/11] remove list --- docs/static.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/static.md b/docs/static.md index 7003fdccb4..792ff0c013 100644 --- a/docs/static.md +++ b/docs/static.md @@ -132,22 +132,22 @@ For this, you can build and run the `static-builder-gnu` Docker container, remot Example steps for [the Xdebug extension](https://xdebug.org): ```console -* `docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 .` -* `docker create --name static-builder-gnu -it gnu-ext /bin/sh` -* `docker start static-builder-gnu` -* `docker exec -it static-builder-gnu /bin/sh` -* `cd /go/src/app/dist/static-php-cli/buildroot/bin` -* `git clone https://github.com/xdebug/xdebug.git && cd xdebug` -* `source scl_source enable devtoolset-10` -* `../phpize` -* `./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config` -* `make` -* `exit` -* `docker cp static-builder-gnu:/go/src/app/dist/static-php-cli/buildroot/bin/xdebug/modules/xdebug.so xdebug-zts.so` -* `docker cp static-builder-gnu:/go/src/app/dist/frankenphp-linux-$(uname -m) ./frankenphp` -* `docker stop static-builder-gnu` -* `docker rm static-builder-gnu` -* `docker rmi gnu-ext` +docker build -t gnu-ext -f static-builder-gnu.Dockerfile --build-arg FRANKENPHP_VERSION=1.0 . +docker create --name static-builder-gnu -it gnu-ext /bin/sh +docker start static-builder-gnu +docker exec -it static-builder-gnu /bin/sh +cd /go/src/app/dist/static-php-cli/buildroot/bin +git clone https://github.com/xdebug/xdebug.git && cd xdebug +source scl_source enable devtoolset-10 +../phpize +./configure --with-php-config=/go/src/app/dist/static-php-cli/buildroot/bin/php-config +make +exit +docker cp static-builder-gnu:/go/src/app/dist/static-php-cli/buildroot/bin/xdebug/modules/xdebug.so xdebug-zts.so +docker cp static-builder-gnu:/go/src/app/dist/frankenphp-linux-$(uname -m) ./frankenphp +docker stop static-builder-gnu +docker rm static-builder-gnu +docker rmi gnu-ext ``` This will have created `frankenphp` and `xdebug-zts.so` in the current directory. From 19babb50c47c4ee9a4925006952c23164da322b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 24 Mar 2025 11:32:44 +0100 Subject: [PATCH 09/11] Update performance.md --- docs/performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/performance.md b/docs/performance.md index 4b1cc0c166..2f111522ac 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -32,7 +32,7 @@ Enabling [the worker mode](worker.md) dramatically improves performance, but your app must be adapted to be compatible with this mode: you need to create a worker script and to be sure that the app is not leaking memory. -## Don't use musl +## Don't Use musl The Alpine Linux variant of the official Docker images and the default binaries we provide are using [the musl libc](https://musl.libc.org). From f79d04394c14ada3e3e045baf769d1c52eda8ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 24 Mar 2025 11:45:27 +0100 Subject: [PATCH 10/11] Update static.md --- docs/static.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/static.md b/docs/static.md index 792ff0c013..00c7dee5b3 100644 --- a/docs/static.md +++ b/docs/static.md @@ -1,9 +1,9 @@ # Create a Static Build Instead of using a local installation of the PHP library, -it's possible to create a static build of FrankenPHP thanks to the great [static-php-cli project](https://github.com/crazywhalecc/static-php-cli) (despite its name, this project support all SAPIs, not only CLI). +it's possible to create a static build of FrankenPHP thanks to the great [static-php-cli project](https://github.com/crazywhalecc/static-php-cli) (despite its name, this project supports all SAPIs, not only CLI). -With this method, a single, portable, binary will contain the PHP interpreter, the Caddy web server and FrankenPHP! +With this method, a single, portable, binary will contain the PHP interpreter, the Caddy web server, and FrankenPHP! FrankenPHP also supports [embedding the PHP app in the static binary](embed.md). @@ -11,9 +11,9 @@ FrankenPHP also supports [embedding the PHP app in the static binary](embed.md). We provide Docker images to build static Linux binaries: -### musl-based static build (fully static) +### musl-Based, Fully Static Build -For a fully static binary that runs on any Linux distribution without dependencies but doesn't support dynamic loading of extensions: +For a fully-static binary that runs on any Linux distribution without dependencies but doesn't support dynamic loading of extensions: ```console docker buildx bake --load static-builder-musl @@ -26,7 +26,7 @@ For better performance in heavily concurrent scenarios, consider using the [mima docker buildx bake --load --set static-builder-musl.args.MIMALLOC=1 static-builder-musl ``` -### glibc-Based Static Build (With Dynamic Extension Support) +### glibc-Based, Mostly Static Build (With Dynamic Extension Support) For a binary that supports loading PHP extensions dynamically while still having the selected extensions compiled statically: @@ -37,13 +37,13 @@ docker cp $(docker create --name static-builder-gnu dunglas/frankenphp:static-bu This binary supports all glibc versions 2.17 and superior but does not run on musl-based systems (like Alpine Linux). -The resulting static binary is named `frankenphp` and is available in the current directory. +The resulting mostly static (except `glibc`) binary is named `frankenphp` and is available in the current directory. If you want to build the static binary without Docker, take a look at the macOS instructions, which also work for Linux. ### Custom Extensions -By default, most popular PHP extensions are compiled. +By default, the most popular PHP extensions are compiled. To reduce the size of the binary and to reduce the attack surface, you can choose the list of extensions to build using the `PHP_EXTENSIONS` Docker ARG. @@ -54,7 +54,7 @@ docker buildx bake --load --set static-builder-musl.args.PHP_EXTENSIONS=opcache, # ... ``` -To add libraries enabling additional functionality to the extensions you've enabled, you can pass use the `PHP_EXTENSION_LIBS` Docker ARG: +To add libraries enabling additional functionality to the extensions you've enabled, you can pass the `PHP_EXTENSION_LIBS` Docker ARG: ```console docker buildx bake \ @@ -79,7 +79,7 @@ In this example, we add the [Souin](https://souin.io) HTTP cache module for Cadd > [!TIP] > -> The cbrotli, Mercure and Vulcain modules are included by default if `XCADDY_ARGS` is empty or not set. +> The cbrotli, Mercure, and Vulcain modules are included by default if `XCADDY_ARGS` is empty or not set. > If you customize the value of `XCADDY_ARGS`, you must include them explicitly if you want them to be included. See also how to [customize the build](#customizing-the-build) @@ -118,7 +118,7 @@ script to customize the static build: * `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) * `NO_COMPRESS`: don't compress the resulting binary using UPX -* `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added within the binary +* `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added to the binary * `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance. We only recommend using this for musl targeting builds, for glibc prefer disabling this option and using [`LD_PRELOAD`](https://microsoft.github.io/mimalloc/overrides.html) when you run your binary instead. * `RELEASE`: (maintainers only) when set, the resulting binary will be uploaded on GitHub @@ -151,4 +151,4 @@ docker rmi gnu-ext ``` This will have created `frankenphp` and `xdebug-zts.so` in the current directory. -If you move the `xdebug-zts.so` into your extension directory, add `zend_extension=xdebug-zts.so` to your php.ini and run FrankenPHP, it will load xdebug. +If you move the `xdebug-zts.so` into your extension directory, add `zend_extension=xdebug-zts.so` to your php.ini and run FrankenPHP, it will load Xdebug. From bc26311150f075f6e10b2522dd9de443f0c3c947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 24 Mar 2025 11:55:51 +0100 Subject: [PATCH 11/11] Update static.md --- docs/static.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/static.md b/docs/static.md index 00c7dee5b3..781edaecb7 100644 --- a/docs/static.md +++ b/docs/static.md @@ -1,10 +1,17 @@ # Create a Static Build Instead of using a local installation of the PHP library, -it's possible to create a static build of FrankenPHP thanks to the great [static-php-cli project](https://github.com/crazywhalecc/static-php-cli) (despite its name, this project supports all SAPIs, not only CLI). +it's possible to create a static or mostly static build of FrankenPHP thanks to the great [static-php-cli project](https://github.com/crazywhalecc/static-php-cli) (despite its name, this project supports all SAPIs, not only CLI). With this method, a single, portable, binary will contain the PHP interpreter, the Caddy web server, and FrankenPHP! +Fully static native executables require no dependencies at all and can even be run on [`scratch` Docker image](https://docs.docker.com/build/building/base-images/#create-a-minimal-base-image-using-scratch). +However, they can't load dynamic PHP extensions (such as Xdebug) and have some limitations because they are using the musl libc. + +Mostly static binaries only require `glibc` and can load dynamic extensions. + +When possible, we recommend using glibc-based, mostly static builds. + FrankenPHP also supports [embedding the PHP app in the static binary](embed.md). ## Linux