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;