From 9a22a9339c46b549140a30ab5824e8557ae5fea3 Mon Sep 17 00:00:00 2001 From: Norbert Orzechowicz Date: Fri, 12 Dec 2025 13:37:14 +0100 Subject: [PATCH 1/2] fix: improve building docker performance - Add .dockerignore to reduce build context - Extract PHP extension compilation to separate Dockerfile.base for reuse - Simplify main Dockerfile to use pre-built base image from registry - Add new docker-base.yml workflow to build base image weekly for PHP 8.3/8.4/8.5 - Remove GHA cache from baseline workflow (no longer needed with pre-built base) - Update documentation with two-layer Docker build instructions --- .dockerignore | 3 ++ .github/workflows/baseline.yml | 4 +- .github/workflows/docker-base.yml | 55 +++++++++++++++++++++++ .nix/pkgs/php-snappy/package.nix | 2 +- Dockerfile | 52 +++------------------ Dockerfile.base | 37 +++++++++++++++ documentation/contributing/environment.md | 22 ++++++++- 7 files changed, 125 insertions(+), 50 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/docker-base.yml create mode 100644 Dockerfile.base diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..6248e60bc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +# Exclude everything except what Docker needs +* +!build/flow.phar diff --git a/.github/workflows/baseline.yml b/.github/workflows/baseline.yml index 9dba64e34..6f60929ff 100644 --- a/.github/workflows/baseline.yml +++ b/.github/workflows/baseline.yml @@ -71,11 +71,11 @@ jobs: file: ./Dockerfile push: true platforms: linux/amd64,linux/arm64 + build-args: | + FLOW_PHP_VERSION=${{ matrix.php-version }} tags: | ghcr.io/flow-php/flow:latest target: flow - cache-from: type=gha - cache-to: type=gha,mode=max - name: "Prepare artifact name" if: ${{ github.event_name == 'push' }} diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml new file mode 100644 index 000000000..94e8a6b56 --- /dev/null +++ b/.github/workflows/docker-base.yml @@ -0,0 +1,55 @@ +name: Build Docker Base Image + +on: + workflow_dispatch: + schedule: + # Run weekly on Sunday at 2 AM UTC + - cron: '0 2 * * 0' + push: + branches: [ 1.x ] + paths: + - 'Dockerfile.base' + +jobs: + build-base-image: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-version: + - "8.3" + - "8.4" + - "8.5" + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push Base Image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile.base + push: true + platforms: linux/amd64,linux/arm64 + build-args: | + FLOW_PHP_VERSION=${{ matrix.php-version }} + tags: | + ghcr.io/flow-php/flow-base:${{ matrix.php-version }}-alpine + ghcr.io/flow-php/flow-base:latest + cache-from: type=registry,ref=ghcr.io/flow-php/flow-base:${{ matrix.php-version }}-alpine + cache-to: type=inline diff --git a/.nix/pkgs/php-snappy/package.nix b/.nix/pkgs/php-snappy/package.nix index d4c7ec573..b159fdbcd 100644 --- a/.nix/pkgs/php-snappy/package.nix +++ b/.nix/pkgs/php-snappy/package.nix @@ -8,7 +8,7 @@ php.buildPecl { owner = "kjdev"; repo = "php-ext-snappy"; tag = "0.2.3"; - hash = "sha256-PAKdIcpJKH6d74EulYQepP4XbQvccrj1nEuir47vro4="; + hash = "sha256-W3TJ/bJz1LEPXq8m8YWAYX/2IZoJEpvqzasBiN61hK0="; fetchSubmodules = true; }; diff --git a/Dockerfile b/Dockerfile index fd54263eb..ebf0aa658 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,54 +1,16 @@ -# Stage 1: Build stage -ARG FLOW_PHP_VERSION=8.3.28 -ARG FLOW_BASE_IMAGE_TAG_SUFFIX=cli-alpine3.22 -ARG FLOW_BASE_IMAGE_TAG=${FLOW_PHP_VERSION}-${FLOW_BASE_IMAGE_TAG_SUFFIX} -ARG FLOW_BASE_IMAGE=php:${FLOW_BASE_IMAGE_TAG} +# Flow PHP Docker Image +# Uses pre-built base image with all PHP extensions +# Base image is built by .github/workflows/docker-base.yml +ARG FLOW_PHP_VERSION=8.5 +ARG FLOW_BASE_IMAGE=ghcr.io/flow-php/flow-base:${FLOW_PHP_VERSION}-alpine -FROM ${FLOW_BASE_IMAGE} AS builder - -# Install dependencies and PHP extensions -RUN apk update && apk add --no-cache \ - $PHPIZE_DEPS \ - gmp-dev \ - git \ - mariadb-dev \ - postgresql-dev \ - sqlite-dev \ - libpq \ - curl \ - build-base \ - autoconf \ - automake \ - libtool \ - protobuf-dev \ - protobuf-c-dev \ - && docker-php-ext-install bcmath gmp pdo_mysql pdo_pgsql pdo_sqlite \ - && curl -L https://github.com/php/pie/releases/latest/download/pie.phar -o /usr/local/bin/pie \ - && chmod +x /usr/local/bin/pie \ - && php /usr/local/bin/pie install kjdev/brotli \ - && php /usr/local/bin/pie install kjdev/lz4 \ - && php /usr/local/bin/pie install kjdev/snappy \ - && php /usr/local/bin/pie install kjdev/zstd \ - && php /usr/local/bin/pie install flow-php/pg-query-ext:1.x-dev - -# Stage 2: Final Image FROM ${FLOW_BASE_IMAGE} AS flow -# Copy the built extensions from the builder stage -COPY --from=builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions -COPY --from=builder /usr/local/etc/php/conf.d /usr/local/etc/php/conf.d - -# Copy necessary libraries for the extensions -COPY --from=builder /usr/lib/libgmp.so.10 /usr/lib/ -COPY --from=builder /usr/lib/libstdc++.so.6 /usr/lib/ -COPY --from=builder /usr/lib/libgcc_s.so.1 /usr/lib/ -COPY --from=builder /usr/lib/libpq.so.5 /usr/lib/ - -# Copy your PHP application +# Copy the pre-built PHAR file COPY build/flow.phar /flow-php/flow.phar RUN chmod +x /flow-php/flow.phar # Set the work directory, entrypoint, and volume WORKDIR /flow-php ENTRYPOINT ["php", "/flow-php/flow.phar"] -VOLUME ["/flow-php"] \ No newline at end of file +VOLUME ["/flow-php"] diff --git a/Dockerfile.base b/Dockerfile.base new file mode 100644 index 000000000..7549d85f7 --- /dev/null +++ b/Dockerfile.base @@ -0,0 +1,37 @@ +# Base image with all PHP extensions pre-compiled for Flow PHP +# This image is built weekly and cached in the registry +# Used by Dockerfile to avoid recompiling extensions on every build +ARG FLOW_PHP_VERSION=8.3 +ARG FLOW_BASE_IMAGE_TAG_SUFFIX=cli-alpine3.22 + +FROM php:${FLOW_PHP_VERSION}-${FLOW_BASE_IMAGE_TAG_SUFFIX} + +# Pin PIE version for reproducible builds +ARG PIE_VERSION=1.3.1 + +# Install dependencies and PHP extensions in a single layer +RUN apk update && apk add --no-cache \ + $PHPIZE_DEPS \ + gmp-dev \ + git \ + mariadb-dev \ + postgresql-dev \ + sqlite-dev \ + libpq \ + curl \ + build-base \ + autoconf \ + automake \ + libtool \ + protobuf-dev \ + protobuf-c-dev \ + && docker-php-ext-install bcmath gmp pdo_mysql pdo_pgsql pdo_sqlite \ + && curl -L "https://github.com/php/pie/releases/download/${PIE_VERSION}/pie.phar" -o /usr/local/bin/pie \ + && chmod +x /usr/local/bin/pie \ + && php /usr/local/bin/pie install kjdev/brotli \ + && php /usr/local/bin/pie install kjdev/lz4 \ + && php /usr/local/bin/pie install kjdev/snappy \ + && php /usr/local/bin/pie install kjdev/zstd \ + && php /usr/local/bin/pie install flow-php/pg-query-ext:1.x-dev \ + && apk del $PHPIZE_DEPS build-base autoconf automake libtool git \ + && rm -rf /var/cache/apk/* /tmp/* diff --git a/documentation/contributing/environment.md b/documentation/contributing/environment.md index 403d80f6b..0d31a91f3 100644 --- a/documentation/contributing/environment.md +++ b/documentation/contributing/environment.md @@ -92,13 +92,31 @@ composer build:phar ## Building Docker Image -In order to build docker image and load it to local registry please use: +The Docker setup uses a two-layer approach for faster builds: + +1. **Base image** (`Dockerfile.base`) - Contains PHP and all extensions, built weekly in CI +2. **Main image** (`Dockerfile`) - Copies the PHAR into the base image + +### Using Pre-built Base Image (Recommended) + +Build the main image using the pre-built base from the registry: ```shell +composer build:phar +docker buildx build -t flow-php/flow:latest . --progress=plain --load +``` + +### Building Base Image Locally + +If you need to build the base image locally (e.g., testing extension changes): + +```shell +docker buildx build -f Dockerfile.base -t ghcr.io/flow-php/flow-base:8.3-alpine . --progress=plain --load +composer build:phar docker buildx build -t flow-php/flow:latest . --progress=plain --load ``` -Usage: +### Usage ```shell docker run -v $(pwd):/flow-workspace -it flow-php/flow:latest --version From c49731697067f98e773f577fa0a402810f8fb6c0 Mon Sep 17 00:00:00 2001 From: Norbert Orzechowicz Date: Fri, 12 Dec 2025 13:38:16 +0100 Subject: [PATCH 2/2] fix: composer build:docker action --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 60c16cb8a..1ab57038c 100644 --- a/composer.json +++ b/composer.json @@ -452,7 +452,7 @@ "@build:phar" ], "build:docker": [ - "docker buildx build -t flow-php/flow:latest . --progress=plain --load" + "docker build -f Dockerfile.base -t ghcr.io/flow-php/flow-base:8.5-alpine ." ], "build:docs": [ "bin/docs.php dsl:dump web/landing/resources/dsl.json",