diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index e49cd5e4c..1dbf985ad 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -13,20 +13,69 @@ env: IMAGE_NAME: ${{ github.repository }} jobs: - build-and-push: - name: Build and Push ${{ matrix.os }} + build-php-base: + name: Build PHP base image on ${{ matrix.os }} runs-on: ${{ matrix.os }} permissions: contents: read packages: write - strategy: fail-fast: false matrix: - os: [ubuntu-24.04, ubuntu-24.04-arm] + include: + - os: ubuntu-24.04 + arch: amd64 + platform: linux/amd64 + - os: ubuntu-24.04-arm + arch: arm64 + platform: linux/arm64 + steps: + - name: Code checkout + uses: actions/checkout@v4 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Build the base PHP image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile.base + push: false + load: true + platforms: ${{ matrix.platform }} + tags: base-php:${{ matrix.arch }} + cache-from: type=gha,scope=base-php${{ matrix.arch }} + cache-to: type=gha,scope=base-php${{ matrix.arch }} + + - name: Export image to file + run: docker save -o base-php-${{ matrix.arch }}.tar base-php:${{ matrix.arch }} + + - name: Push the docker build to the artifacts + uses: actions/upload-artifact@v4 + with: + name: base-php-${{ matrix.arch }}.tar + path: base-php-${{ matrix.arch }}.tar + retention-days: 7 + + + build-and-push: + name: Build and Push ubuntu-24.04 + runs-on: ubuntu-24.04 + needs: build-php-base + permissions: + contents: read + packages: write + strategy: + fail-fast: false + # Start a temp local registry because workflow can not pull from localy loaded images + services: + registry: + image: registry:2 + ports: + - 5000:5000 # Always run against a tag, even if the commit into the tag has [docker skip] within the commit message. if: "!contains(github.ref, 'main') || (!contains(github.event.head_commit.message, 'skip docker') && !contains(github.event.head_commit.message, 'docker skip'))" - steps: - name: Code checkout uses: actions/checkout@v4 @@ -43,8 +92,14 @@ jobs: type=ref,event=tag type=ref,event=branch + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + # We Need to start it in host mode else it can't acces the local registry on port 5000 - name: Setup Docker buildx uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -59,6 +114,26 @@ jobs: echo "version_tag=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_OUTPUT echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + # Download the base PHP image AMD64 + - uses: actions/download-artifact@v4 + with: + name: base-php-amd64.tar + + # Download the base PHP image ARM64 + - uses: actions/download-artifact@v4 + with: + name: base-php-arm64.tar + + - name: Load base images into local registry + run: | + docker load -i base-php-amd64.tar + docker load -i base-php-arm64.tar + docker tag base-php:amd64 localhost:5000/base-php:amd64 + docker tag base-php:arm64 localhost:5000/base-php:arm64 + docker push localhost:5000/base-php:amd64 + docker push localhost:5000/base-php:arm64 + rm base-php-arm64.tar base-php-amd64.tar + - name: Build and Push (tag) uses: docker/build-push-action@v6 if: "github.event_name == 'release' && github.event.action == 'published'" @@ -66,14 +141,14 @@ jobs: context: . file: ./Dockerfile push: true - platforms: ${{ matrix.os == 'ubuntu-24.04' && 'linux/amd64' || 'linux/arm64' }} + platforms: 'linux/amd64,linux/arm64' build-args: | VERSION=${{ steps.build_info.outputs.version_tag }} labels: ${{ steps.docker_meta.outputs.labels }} tags: ${{ steps.docker_meta.outputs.tags }} cache-from: type=gha,scope=tagged${{ matrix.os }} cache-to: type=gha,scope=tagged${{ matrix.os }},mode=max - + - name: Build and Push (main) uses: docker/build-push-action@v6 if: "github.event_name == 'push' && contains(github.ref, 'main')" @@ -81,7 +156,7 @@ jobs: context: . file: ./Dockerfile push: ${{ github.event_name != 'pull_request' }} - platforms: ${{ matrix.os == 'ubuntu-24.04' && 'linux/amd64' || 'linux/arm64' }} + platforms: 'linux/amd64,linux/arm64' build-args: | VERSION=dev-${{ steps.build_info.outputs.short_sha }} labels: ${{ steps.docker_meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index b12576776..b06a65c09 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,21 @@ -# syntax=docker.io/docker/dockerfile:1.7-labs +# syntax=docker.io/docker/dockerfile:1.13-labs # Pelican Production Dockerfile -# ================================ -# Stage 1: Build PHP Base Image -# ================================ -FROM --platform=$TARGETOS/$TARGETARCH php:8.3-fpm-alpine AS base -ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ +# For those who want to build this Dockerfile themselves, uncomment lines 6-12 and replace "localhost:5000/base-php:$TARGETARCH" on lines 17 and 67 with "base". -RUN install-php-extensions bcmath gd intl zip opcache pcntl posix pdo_mysql +# FROM --platform=$TARGETOS/$TARGETARCH php:8.3-fpm-alpine as base -RUN rm /usr/local/bin/install-php-extensions +# ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +# RUN install-php-extensions bcmath gd intl zip opcache pcntl posix pdo_mysql + +# RUN rm /usr/local/bin/install-php-extensions # ================================ -# Stage 2-1: Composer Install +# Stage 1-1: Composer Install # ================================ -FROM --platform=$TARGETOS/$TARGETARCH base AS composer +FROM --platform=$TARGETOS/$TARGETARCH localhost:5000/base-php:$TARGETARCH AS composer WORKDIR /build @@ -27,7 +27,7 @@ COPY composer.json composer.lock ./ RUN composer install --no-dev --no-interaction --no-autoloader --no-scripts # ================================ -# Stage 2-2: Yarn Install +# Stage 1-2: Yarn Install # ================================ FROM --platform=$TARGETOS/$TARGETARCH node:20-alpine AS yarn @@ -40,7 +40,7 @@ RUN yarn config set network-timeout 300000 \ && yarn install --frozen-lockfile # ================================ -# Stage 3-1: Composer Optimize +# Stage 2-1: Composer Optimize # ================================ FROM --platform=$TARGETOS/$TARGETARCH composer AS composerbuild @@ -50,7 +50,7 @@ COPY --exclude=Caddyfile --exclude=docker/ . ./ RUN composer dump-autoload --optimize # ================================ -# Stage 3-2: Build Frontend Assets +# Stage 2-2: Build Frontend Assets # ================================ FROM --platform=$TARGETOS/$TARGETARCH yarn AS yarnbuild @@ -63,9 +63,9 @@ COPY --from=composer /build . RUN yarn run build # ================================ -# Stage 4: Build Final Application Image +# Stage 5: Build Final Application Image # ================================ -FROM --platform=$TARGETOS/$TARGETARCH base AS final +FROM --platform=$TARGETOS/$TARGETARCH localhost:5000/base-php:$TARGETARCH AS final WORKDIR /var/www/html diff --git a/Dockerfile.base b/Dockerfile.base new file mode 100644 index 000000000..082a54c63 --- /dev/null +++ b/Dockerfile.base @@ -0,0 +1,10 @@ +# ================================ +# Stage 0: Build PHP Base Image +# ================================ +FROM --platform=$TARGETOS/$TARGETARCH php:8.3-fpm-alpine + +ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +RUN install-php-extensions bcmath gd intl zip opcache pcntl posix pdo_mysql + +RUN rm /usr/local/bin/install-php-extensions \ No newline at end of file