From f11a5051c66a2c86e0a66de2afc6f679a07c56a1 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 7 Mar 2026 21:18:21 +0000 Subject: [PATCH] fix(ci): lowercase GHCR owner tags and harden frontend runtime image --- .github/workflows/backend-beta.yml | 15 ++++++++++++--- .github/workflows/backend-latest.yml | 15 ++++++++++++--- .github/workflows/backend-release.yml | 15 ++++++++++++--- .github/workflows/cdn-beta.yml | 7 +++++-- .github/workflows/cdn-latest.yml | 7 +++++-- .github/workflows/cdn-release.yml | 7 +++++-- .github/workflows/frontend-beta.yml | 15 ++++++++++++--- .github/workflows/frontend-latest.yml | 15 ++++++++++++--- .github/workflows/frontend-release.yml | 17 +++++++++++++---- frontend/Dockerfile | 24 +++++++++++++++++++++++- 10 files changed, 111 insertions(+), 26 deletions(-) diff --git a/.github/workflows/backend-beta.yml b/.github/workflows/backend-beta.yml index d17d6cea..85b3c622 100644 --- a/.github/workflows/backend-beta.yml +++ b/.github/workflows/backend-beta.yml @@ -34,6 +34,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Set lower case owner name + id: repo_owner + run: | + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" + env: + OWNER: "${{ github.repository_owner }}" + - name: Build and push beta Docker image with BuildKit cache uses: docker/build-push-action@v5 with: @@ -41,12 +50,12 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: | - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:beta + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:beta cache-from: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache type=local,src=/tmp/.buildx-cache cache-to: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max type=local,dest=/tmp/.buildx-cache,mode=max env: DOCKER_BUILDKIT: 1 diff --git a/.github/workflows/backend-latest.yml b/.github/workflows/backend-latest.yml index df1bd907..7e029d24 100644 --- a/.github/workflows/backend-latest.yml +++ b/.github/workflows/backend-latest.yml @@ -36,6 +36,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Set lower case owner name + id: repo_owner + run: | + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" + env: + OWNER: "${{ github.repository_owner }}" + - name: Build and push latest Docker image with BuildKit cache uses: docker/build-push-action@v5 with: @@ -43,12 +52,12 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: | - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:latest cache-from: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache type=local,src=/tmp/.buildx-cache cache-to: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max type=local,dest=/tmp/.buildx-cache,mode=max env: DOCKER_BUILDKIT: 1 diff --git a/.github/workflows/backend-release.yml b/.github/workflows/backend-release.yml index e5791bb9..e0621d2c 100644 --- a/.github/workflows/backend-release.yml +++ b/.github/workflows/backend-release.yml @@ -31,6 +31,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Set lower case owner name + id: repo_owner + run: | + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" + env: + OWNER: "${{ github.repository_owner }}" + - name: Build and push release Docker image with BuildKit cache uses: docker/build-push-action@v5 with: @@ -38,12 +47,12 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: | - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }} + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }} cache-from: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache type=local,src=/tmp/.buildx-cache cache-to: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max type=local,dest=/tmp/.buildx-cache,mode=max env: DOCKER_BUILDKIT: 1 diff --git a/.github/workflows/cdn-beta.yml b/.github/workflows/cdn-beta.yml index e1fa7ab8..147b0398 100644 --- a/.github/workflows/cdn-beta.yml +++ b/.github/workflows/cdn-beta.yml @@ -34,9 +34,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: set lower case owner name + - name: Set lower case owner name + id: repo_owner run: | - echo "REPO_OWNER=${OWNER,,}" >>${GITHUB_ENV} + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" env: OWNER: "${{ github.repository_owner }}" diff --git a/.github/workflows/cdn-latest.yml b/.github/workflows/cdn-latest.yml index 2fd01a30..f0048045 100644 --- a/.github/workflows/cdn-latest.yml +++ b/.github/workflows/cdn-latest.yml @@ -34,9 +34,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: set lower case owner name + - name: Set lower case owner name + id: repo_owner run: | - echo "REPO_OWNER=${OWNER,,}" >>${GITHUB_ENV} + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" env: OWNER: "${{ github.repository_owner }}" diff --git a/.github/workflows/cdn-release.yml b/.github/workflows/cdn-release.yml index 1c0925dc..e1058527 100644 --- a/.github/workflows/cdn-release.yml +++ b/.github/workflows/cdn-release.yml @@ -31,9 +31,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: set lower case owner name + - name: Set lower case owner name + id: repo_owner run: | - echo "REPO_OWNER=${OWNER,,}" >>${GITHUB_ENV} + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" env: OWNER: "${{ github.repository_owner }}" diff --git a/.github/workflows/frontend-beta.yml b/.github/workflows/frontend-beta.yml index 8125867e..cfb4d0db 100644 --- a/.github/workflows/frontend-beta.yml +++ b/.github/workflows/frontend-beta.yml @@ -34,6 +34,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Set lower case owner name + id: repo_owner + run: | + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" + env: + OWNER: "${{ github.repository_owner }}" + - name: Build and push beta Docker image with BuildKit cache uses: docker/build-push-action@v5 with: @@ -41,12 +50,12 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: | - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:beta + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:beta cache-from: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache type=local,src=/tmp/.buildx-cache cache-to: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max type=local,dest=/tmp/.buildx-cache,mode=max env: DOCKER_BUILDKIT: 1 diff --git a/.github/workflows/frontend-latest.yml b/.github/workflows/frontend-latest.yml index 85d7e5b4..cf4eddfa 100644 --- a/.github/workflows/frontend-latest.yml +++ b/.github/workflows/frontend-latest.yml @@ -36,6 +36,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Set lower case owner name + id: repo_owner + run: | + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" + env: + OWNER: "${{ github.repository_owner }}" + - name: Build and push latest Docker image with BuildKit cache uses: docker/build-push-action@v5 with: @@ -43,12 +52,12 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: | - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:latest cache-from: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache type=local,src=/tmp/.buildx-cache cache-to: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max type=local,dest=/tmp/.buildx-cache,mode=max env: DOCKER_BUILDKIT: 1 diff --git a/.github/workflows/frontend-release.yml b/.github/workflows/frontend-release.yml index a1d35804..268464f5 100644 --- a/.github/workflows/frontend-release.yml +++ b/.github/workflows/frontend-release.yml @@ -31,6 +31,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Set lower case owner name + id: repo_owner + run: | + LOWER_OWNER="${OWNER,,}" + echo "REPO_OWNER=${LOWER_OWNER}" >>"$GITHUB_ENV" + echo "repo_owner=${LOWER_OWNER}" >>"$GITHUB_OUTPUT" + env: + OWNER: "${{ github.repository_owner }}" + - name: Build and push release Docker image with BuildKit cache uses: docker/build-push-action@v5 with: @@ -38,13 +47,13 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: | - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }} - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }} + ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:latest cache-from: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache type=local,src=/tmp/.buildx-cache cache-to: | - type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + type=registry,ref=ghcr.io/${{ steps.repo_owner.outputs.repo_owner }}/${{ env.IMAGE_NAME }}:buildcache,mode=max type=local,dest=/tmp/.buildx-cache,mode=max env: DOCKER_BUILDKIT: 1 diff --git a/frontend/Dockerfile b/frontend/Dockerfile index e327e135..e5912ad1 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,5 +1,5 @@ # Use this image as the platform to build the app -FROM node:22-alpine AS external-website +FROM node:22-alpine AS builder # Metadata labels for the AdventureLog image LABEL maintainer="Sean Morley" \ @@ -42,6 +42,28 @@ RUN pnpm run build # Make startup script executable RUN chmod +x ./startup.sh +# Keep only production dependencies for runtime image +RUN CI=true pnpm prune --prod + +# Runtime image contains only built app + runtime deps +FROM node:22-alpine AS runtime + +WORKDIR /app + +# Upgrade zlib and remove npm toolchain from runtime image +RUN apk upgrade --no-cache zlib \ + && rm -f /usr/local/bin/npm /usr/local/bin/npx \ + && rm -rf /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack + +# Copy build artifacts and production runtime dependencies +COPY --from=builder /app/build ./build +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/package.json ./package.json +COPY --from=builder /app/startup.sh ./startup.sh + +# Ensure startup script is executable +RUN chmod +x ./startup.sh + # Change to non-root user for security USER node:node