From b928a316bdb4d4e82372ce22a3d4167109bc650b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 27 Oct 2026 00:22:18 +0100 Subject: [PATCH 1/3] Avoid unneeded build dependencies to speed up Docker build --- docs/best-practices/deployment.md | 4 ++-- tests/integration/Dockerfile-production | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/best-practices/deployment.md b/docs/best-practices/deployment.md index dffa44d..baf3bad 100644 --- a/docs/best-practices/deployment.md +++ b/docs/best-practices/deployment.md @@ -716,11 +716,11 @@ be achieved by using a `Dockerfile` with the following contents: FROM php:8.5-alpine # recommended: install optional extensions ext-ev and ext-sockets - RUN apk --no-cache add ${PHPIZE_DEPS} libev linux-headers \ + RUN apk --no-cache add --virtual .phpize-deps autoconf gcc libc-dev linux-headers make \ && pecl install ev \ && docker-php-ext-enable ev \ && docker-php-ext-install sockets \ - && apk del ${PHPIZE_DEPS} linux-headers \ + && apk del --no-network .phpize-deps \ && echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" WORKDIR /app/ diff --git a/tests/integration/Dockerfile-production b/tests/integration/Dockerfile-production index 607ff38..ee4273e 100644 --- a/tests/integration/Dockerfile-production +++ b/tests/integration/Dockerfile-production @@ -11,11 +11,11 @@ COPY vendor/ vendor/ FROM php:8.5-alpine # recommended: install optional extensions ext-ev and ext-sockets -RUN apk --no-cache add ${PHPIZE_DEPS} libev linux-headers \ +RUN apk --no-cache add --virtual .phpize-deps autoconf gcc libc-dev linux-headers make \ && pecl install ev \ && docker-php-ext-enable ev \ && docker-php-ext-install sockets \ - && apk del ${PHPIZE_DEPS} linux-headers \ + && apk del --no-network .phpize-deps \ && echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" WORKDIR /app/ From dbd41e3bd0ea676b6158fba1466585deb8cbc7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 27 Oct 2026 00:22:40 +0100 Subject: [PATCH 2/3] Improve Docker build to compile PHP extensions in parallel stages --- docs/best-practices/deployment.md | 27 +++++++++++++++++-------- tests/integration/Dockerfile-production | 25 ++++++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/docs/best-practices/deployment.md b/docs/best-practices/deployment.md index baf3bad..b50062d 100644 --- a/docs/best-practices/deployment.md +++ b/docs/best-practices/deployment.md @@ -707,22 +707,33 @@ be achieved by using a `Dockerfile` with the following contents: ```docker title="Dockerfile" # syntax=docker/dockerfile:1 + FROM php:8.5-alpine AS php-version + FROM composer:2 AS build WORKDIR /app/ COPY composer.json composer.lock ./ RUN composer install --no-dev --ignore-platform-reqs --optimize-autoloader - FROM php:8.5-alpine + # base build stage with build tools to compile extensions in parallel + FROM php-version AS phpize + RUN apk --no-cache add --virtual .phpize-deps autoconf gcc libc-dev linux-headers make - # recommended: install optional extensions ext-ev and ext-sockets - RUN apk --no-cache add --virtual .phpize-deps autoconf gcc libc-dev linux-headers make \ - && pecl install ev \ - && docker-php-ext-enable ev \ - && docker-php-ext-install sockets \ - && apk del --no-network .phpize-deps \ - && echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" + FROM phpize AS ext-ev + RUN MAKEFLAGS="-j$(nproc)" pecl install ev && docker-php-ext-enable ev + FROM phpize AS ext-sockets + RUN docker-php-ext-install -j$(nproc) sockets + + # recommended: install optional extensions ext-ev and ext-sockets + FROM php-version AS os + COPY --from=ext-ev /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/ + COPY --from=ext-ev /usr/local/etc/php/conf.d/docker-php-ext-ev.ini /usr/local/etc/php/conf.d/ + COPY --from=ext-sockets /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/ + COPY --from=ext-sockets /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini /usr/local/etc/php/conf.d/ + RUN echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" + + FROM os WORKDIR /app/ COPY public/ public/ # COPY src/ src/ diff --git a/tests/integration/Dockerfile-production b/tests/integration/Dockerfile-production index ee4273e..a8acf2f 100644 --- a/tests/integration/Dockerfile-production +++ b/tests/integration/Dockerfile-production @@ -1,4 +1,6 @@ # syntax=docker/dockerfile:1 +FROM php:8.5-alpine AS php-version + FROM composer:2 AS build WORKDIR /app/ @@ -8,16 +10,25 @@ COPY composer.json composer.lock ./ # dev environment already has dependencies installed: COPY vendor/ vendor/ -FROM php:8.5-alpine +# base build stage with build tools to compile extensions in parallel +FROM php-version AS phpize +RUN apk --no-cache add --virtual .phpize-deps autoconf gcc libc-dev linux-headers make + +FROM phpize AS ext-ev +RUN MAKEFLAGS="-j$(nproc)" pecl install ev && docker-php-ext-enable ev + +FROM phpize AS ext-sockets +RUN docker-php-ext-install -j$(nproc) sockets # recommended: install optional extensions ext-ev and ext-sockets -RUN apk --no-cache add --virtual .phpize-deps autoconf gcc libc-dev linux-headers make \ - && pecl install ev \ - && docker-php-ext-enable ev \ - && docker-php-ext-install sockets \ - && apk del --no-network .phpize-deps \ - && echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" +FROM php-version AS os +COPY --from=ext-ev /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/ +COPY --from=ext-ev /usr/local/etc/php/conf.d/docker-php-ext-ev.ini /usr/local/etc/php/conf.d/ +COPY --from=ext-sockets /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/ +COPY --from=ext-sockets /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini /usr/local/etc/php/conf.d/ +RUN echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" +FROM os WORKDIR /app/ COPY public/ public/ # COPY src/ src/ From 566961ef7480e7ce47a443c16af9f596c9a35ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 27 Oct 2026 00:22:57 +0100 Subject: [PATCH 3/3] Improve Dockerfile structure to avoid unneeded instructions --- docs/best-practices/deployment.md | 13 ++++++------- tests/integration/Dockerfile-basics | 1 - tests/integration/Dockerfile-production | 12 ++++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/best-practices/deployment.md b/docs/best-practices/deployment.md index b50062d..9543a17 100644 --- a/docs/best-practices/deployment.md +++ b/docs/best-practices/deployment.md @@ -690,7 +690,6 @@ be achieved by using a `Dockerfile` with the following contents: === "Dockerfile basics for development" ```docker title="Dockerfile" - # syntax=docker/dockerfile:1 FROM php:8.5-cli WORKDIR /app/ @@ -706,12 +705,11 @@ be achieved by using a `Dockerfile` with the following contents: === "Dockerfile for minimal production image" ```docker title="Dockerfile" - # syntax=docker/dockerfile:1 + # base PHP version for the build and final project FROM php:8.5-alpine AS php-version - FROM composer:2 AS build - - WORKDIR /app/ + # base composer stage to install dependencies in parallel + FROM composer:2 AS vendor COPY composer.json composer.lock ./ RUN composer install --no-dev --ignore-platform-reqs --optimize-autoloader @@ -725,7 +723,7 @@ be achieved by using a `Dockerfile` with the following contents: FROM phpize AS ext-sockets RUN docker-php-ext-install -j$(nproc) sockets - # recommended: install optional extensions ext-ev and ext-sockets + # base os stage with recommended extensions ext-ev and ext-sockets FROM php-version AS os COPY --from=ext-ev /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/ COPY --from=ext-ev /usr/local/etc/php/conf.d/docker-php-ext-ev.ini /usr/local/etc/php/conf.d/ @@ -733,11 +731,12 @@ be achieved by using a `Dockerfile` with the following contents: COPY --from=ext-sockets /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini /usr/local/etc/php/conf.d/ RUN echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" + # final project stage FROM os WORKDIR /app/ COPY public/ public/ # COPY src/ src/ - COPY --from=build /app/vendor/ vendor/ + COPY --from=vendor /app/vendor/ vendor/ ENV X_LISTEN=0.0.0.0:8080 EXPOSE 8080 diff --git a/tests/integration/Dockerfile-basics b/tests/integration/Dockerfile-basics index 670d87b..4bbac99 100644 --- a/tests/integration/Dockerfile-basics +++ b/tests/integration/Dockerfile-basics @@ -1,4 +1,3 @@ -# syntax=docker/dockerfile:1 FROM php:8.5-cli WORKDIR /app/ diff --git a/tests/integration/Dockerfile-production b/tests/integration/Dockerfile-production index a8acf2f..0b18757 100644 --- a/tests/integration/Dockerfile-production +++ b/tests/integration/Dockerfile-production @@ -1,9 +1,8 @@ -# syntax=docker/dockerfile:1 +# base PHP version for the build and final project FROM php:8.5-alpine AS php-version -FROM composer:2 AS build - -WORKDIR /app/ +# base composer stage to install dependencies in parallel +FROM composer:2 AS vendor COPY composer.json composer.lock ./ # production environment should install optimized dependencies: # RUN composer install --no-dev --ignore-platform-reqs --optimize-autoloader @@ -20,7 +19,7 @@ RUN MAKEFLAGS="-j$(nproc)" pecl install ev && docker-php-ext-enable ev FROM phpize AS ext-sockets RUN docker-php-ext-install -j$(nproc) sockets -# recommended: install optional extensions ext-ev and ext-sockets +# base os stage with recommended extensions ext-ev and ext-sockets FROM php-version AS os COPY --from=ext-ev /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/ COPY --from=ext-ev /usr/local/etc/php/conf.d/docker-php-ext-ev.ini /usr/local/etc/php/conf.d/ @@ -28,11 +27,12 @@ COPY --from=ext-sockets /usr/local/lib/php/extensions/ /usr/local/lib/php/extens COPY --from=ext-sockets /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini /usr/local/etc/php/conf.d/ RUN echo "memory_limit = -1" >> "$PHP_INI_DIR/conf.d/acme.ini" +# final project stage FROM os WORKDIR /app/ COPY public/ public/ # COPY src/ src/ -COPY --from=build /app/vendor/ vendor/ +COPY --from=vendor /app/vendor/ vendor/ ENV X_LISTEN=0.0.0.0:8080 EXPOSE 8080