From 2d6e34c5551353b50a562e005c10652beb8ae47c Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 2 Mar 2026 16:16:20 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(ci)=20reuse=20amd64=20to=20b?= =?UTF-8?q?uild=20arm64=20image=20when=20possible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building twice the image take lof of time. In soma cases, building the arm64 image using the artifacts build in the amd64 and thant can be reused should speed up the build of the arm64 image. --- .github/workflows/docker-hub.yml | 111 +++++--------------- .github/workflows/docker-publish.yml | 13 ++- src/frontend/Dockerfile | 16 ++- src/frontend/apps/impress/conf/default.conf | 2 +- 4 files changed, 48 insertions(+), 94 deletions(-) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index 4f9757f1..7ca81c66 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -28,100 +28,37 @@ jobs: with: image_name: lasuite/impress-backend context: . + file: Dockerfile target: backend-production should_push: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'preview') }} docker_user: 1001:127 build-and-push-frontend: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set up QEMU - if: env.SHOULD_PUSH == 'true' - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - if: env.SHOULD_PUSH == 'true' - uses: docker/setup-buildx-action@v3 - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: lasuite/impress-frontend - - name: Login to DockerHub - if: env.SHOULD_PUSH == 'true' - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_USER }} - password: ${{ secrets.DOCKER_HUB_PASSWORD }} - # - name: Run trivy scan - # uses: numerique-gouv/action-trivy-cache@main - # with: - # docker-build-args: "-f src/frontend/Dockerfile --target frontend-production" - # docker-image-name: "docker.io/lasuite/impress-frontend:${{ github.sha }}" - # trivyignores: ./.github/.trivyignore - - name: Build and push - if: env.SHOULD_PUSH == 'true' - uses: docker/build-push-action@v6 - with: - context: . - file: ./src/frontend/Dockerfile - target: frontend-production - platforms: linux/amd64,linux/arm64 - build-args: | - DOCKER_USER=${{ env.DOCKER_USER }} - PUBLISH_AS_MIT=false - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - name: Cleanup Docker after build - if: always() - run: | - docker system prune -af - docker volume prune -f + uses: ./.github/workflows/docker-publish.yml + permissions: + contents: read + secrets: inherit + with: + image_name: lasuite/impress-frontend + context: . + file: src/frontend/Dockerfile + target: frontend-production + arm64_reuse_amd64_build_arg: "FRONTEND_IMAGE" + should_push: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'preview') }} + docker_user: 1001:127 build-and-push-y-provider: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set up QEMU - if: env.SHOULD_PUSH == 'true' - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - if: env.SHOULD_PUSH == 'true' - uses: docker/setup-buildx-action@v3 - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: lasuite/impress-y-provider - - name: Login to DockerHub - if: env.SHOULD_PUSH == 'true' - run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_HUB_USER }}" --password-stdin - # - name: Run trivy scan - # uses: numerique-gouv/action-trivy-cache@main - # with: - # docker-build-args: "-f src/frontend/servers/y-provider/Dockerfile --target y-provider" - # docker-image-name: "docker.io/lasuite/impress-y-provider:${{ github.sha }}" - # trivyignores: ./.github/.trivyignore - - name: Build and push - if: env.SHOULD_PUSH == 'true' - uses: docker/build-push-action@v6 - with: - context: . - file: ./src/frontend/servers/y-provider/Dockerfile - target: y-provider - platforms: linux/amd64,linux/arm64 - build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - name: Cleanup Docker after build - if: always() - run: | - docker system prune -af - docker volume prune -f + uses: ./.github/workflows/docker-publish.yml + permissions: + contents: read + secrets: inherit + with: + image_name: lasuite/impress-y-provider + context: . + file: src/frontend/servers/y-provider/Dockerfile + target: y-provider + should_push: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'preview') }} + docker_user: 1001:127 notify-argocd: needs: diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 56b493fc..6a500711 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -12,6 +12,10 @@ description: Build and push a container image based on the input arguments provi type: string required: true description: The path to the context to start `docker build` into. + file: + type: string + required: true + description: The path to the Dockerfile target: type: string required: false @@ -72,20 +76,23 @@ jobs: echo "amd64_first=$FIRST_AMD64_TAG" } >> "$GITHUB_OUTPUT" # - name: Run trivy scan - # if: vars.TRIVY_SCAN_ENABLED + # if: ${{ vars.TRIVY_SCAN_ENABLED }} == 'true' # uses: numerique-gouv/action-trivy-cache@main # with: - # docker-build-args: "--target backend-production -f Dockerfile" + # docker-build-args: "--target ${{ inputs.target }} -f ${{ inputs.file }}" # docker-image-name: "docker.io/${{ inputs.image_name }}:${{ github.sha }}" # trivyignores: ./.github/.trivyignore - name: Build and push (amd64) + if: ${{ inputs.should_push }}||${{ vars.TRIVY_SCAN_ENABLED }} != 'true' uses: docker/build-push-action@v6 with: context: ${{ inputs.context }} + file: ${{ inputs.file }} target: ${{ inputs.target }} platforms: linux/amd64 build-args: | DOCKER_USER=${{ inputs.docker_user }} + PUBLISH_AS_MIT=false push: ${{ inputs.should_push }} provenance: false tags: ${{ steps.platform-tags.outputs.amd64 }} @@ -95,10 +102,12 @@ jobs: uses: docker/build-push-action@v6 with: context: ${{ inputs.context }} + file: ${{ inputs.file }} target: ${{ inputs.target }} platforms: linux/arm64 build-args: | DOCKER_USER=${{ inputs.docker_user }} + PUBLISH_AS_MIT=false ${{ inputs.arm64_reuse_amd64_build_arg && format('{0}={1}', inputs.arm64_reuse_amd64_build_arg, steps.platform-tags.outputs.amd64_first) || '' }} push: ${{ inputs.should_push }} provenance: false diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile index 3562d098..c0dfa54b 100644 --- a/src/frontend/Dockerfile +++ b/src/frontend/Dockerfile @@ -1,3 +1,5 @@ +ARG FRONTEND_IMAGE=frontend-build-output + FROM node:24-alpine AS frontend-deps # Upgrade system packages to install security updates @@ -32,7 +34,7 @@ EXPOSE 3000 CMD [ "yarn", "dev"] -# Tilt will rebuild impress target so, we dissociate impress and impress-builder +# Tilt will rebuild impress target so, we dissociate impress and impress-builder # to avoid rebuilding the app at every changes. FROM impress AS impress-builder @@ -49,6 +51,14 @@ ENV NEXT_PUBLIC_PUBLISH_AS_MIT=${PUBLISH_AS_MIT} RUN yarn build +# Normalize output path to /app (matches the runtime-prod layout) +FROM scratch AS frontend-build-output +COPY --from=impress-builder /home/frontend/apps/impress/out /app + +# When FRONTEND_IMAGE is set to an external image, BuildKit skips +# frontend-deps,impress-builder, and frontend-build-output entirely +FROM ${FRONTEND_IMAGE} AS frontend-source + # ---- Front-end image ---- FROM nginxinc/nginx-unprivileged:alpine3.22 AS frontend-production @@ -62,9 +72,7 @@ RUN apk update && \ ARG DOCKER_USER USER ${DOCKER_USER} -COPY --from=impress-builder \ - /home/frontend/apps/impress/out \ - /usr/share/nginx/html +COPY --from=frontend-source /app /app COPY ./src/frontend/apps/impress/conf/default.conf /etc/nginx/conf.d COPY ./docker/files/usr/local/bin/entrypoint /usr/local/bin/entrypoint diff --git a/src/frontend/apps/impress/conf/default.conf b/src/frontend/apps/impress/conf/default.conf index fecd0070..ac978124 100644 --- a/src/frontend/apps/impress/conf/default.conf +++ b/src/frontend/apps/impress/conf/default.conf @@ -3,7 +3,7 @@ server { listen 3000; server_name localhost; - root /usr/share/nginx/html; + root /app; location / { try_files $uri index.html $uri/index.html =404;