Turborepo构建时推送所有镜像,如何仅推送最终Runner镜像?
问题:Docker多阶段构建推送所有中间镜像,仅需推送最终Runner镜像
背景
我拥有一个使用Turborepo的npm monorepo,希望通过GitHub Actions将其构建为生产环境镜像。
问题
使用docker/build-push-action GitHub Action时,所有3个中间镜像都被推送到了我的制品仓库,仅有最终的Runner镜像标签正确。
预期结果
仅将最终的Runner镜像推送到制品仓库
我的Dockerfile
FROM node:alpine AS builder RUN apk add --no-cache libc6-compat RUN apk update # Set working directory WORKDIR /app RUN npm install turbo --global COPY . . RUN turbo prune --scope=admin --docker # Add lockfile and package.json's of isolated subworkspace FROM node:alpine AS installer RUN apk add --no-cache libc6-compat RUN apk update WORKDIR /app # First install the dependencies (as they change less often) COPY .gitignore .gitignore COPY --from=builder /app/out/json/ . COPY --from=builder /app/out/package-lock.json ./package-lock.json RUN npm ci # Build the project ARG MONOLITH_DOMAIN ENV MONOLITH_DOMAIN=$MONOLITH_DOMAIN COPY --from=builder /app/out/full/ . COPY turbo.json turbo.json RUN npx turbo run build --filter=admin FROM node:alpine AS runner WORKDIR /app # Don't run production as root RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs USER nextjs COPY --from=installer /app/apps/admin/next.config.js . COPY --from=installer /app/apps/admin/package.json . # Automatically leverage output traces to reduce image size COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/.next/standalone ./ COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/.next/static ./apps/admin/.next/static COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/public ./apps/admin/public CMD node apps/admin/server.js
此Dockerfile遵循Turborepo官方推荐的多阶段构建方式。
我的GitHub Action
name: Build and Push Docker Image on: workflow_call: inputs: environment: required: true type: string tag: required: true type: string monolith_domain: required: true type: string secrets: GOOGLE_CLOUD_SERVICE_ACCOUNT_JSON_TOKEN: required: true jobs: build-and-push: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - id: auth name: Authenticate to Google Cloud uses: google-github-actions/auth@v1 with: token_format: access_token credentials_json: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_JSON_TOKEN }} - uses: 'docker/login-action@v2' with: registry: europe-west1-docker.pkg.dev username: oauth2accesstoken password: ${{ steps.auth.outputs.access_token }} - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . file: ./apps/admin/Dockerfile push: true tags: europe-west1-docker.pkg.dev/xxxx/frontend/admin-frontend:${{ inputs.tag }} build-args: | MONOLITH_DOMAIN=${{ inputs.monolith_domain }}
解决方案
问题根源是Docker Buildx在push: true时默认会推送所有构建阶段的镜像(包括中间的builder、installer阶段)。只需在docker/build-push-action中指定target: runner,即可只构建并推送最终的runner阶段镜像。
修改后的GitHub Action构建步骤如下:
- name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . file: ./apps/admin/Dockerfile push: true target: runner # 指定仅构建推送runner阶段 tags: europe-west1-docker.pkg.dev/xxxx/frontend/admin-frontend:${{ inputs.tag }} build-args: | MONOLITH_DOMAIN=${{ inputs.monolith_domain }}
原理说明
多阶段构建中,每个FROM指令定义一个构建阶段。默认情况下,build-push-action会将所有阶段的镜像推送到仓库(即使没有显式标签)。通过target参数指定最终阶段后,Action会只执行到该阶段,并仅推送这个阶段的镜像,中间阶段不会被推送。
内容的提问来源于stack exchange,提问作者Rickard Liljeberg
相关产品推荐
相关产品推荐

