簡體   English   中英

使用 docker/build-push-action 在 GitHub Actions 中本地構建 docker 鏡像

[英]Build docker image locally in GitHub Actions using docker/build-push-action

我的項目中有幾個 Dockerfile。 一種是用於構建basic圖像,其中包含一些業務級別的抽象。 其他人正在構建服務,基於basic形象。

所以在我的服務的 Dockerfiles 中,我有類似的東西

FROM my-project/base
# Adding some custom logic around basic stuff

我使用 GitHub Actions 作為我的 CI/CD 工具。 起初我有一個步驟將 docker 安裝到我的工人中,然后運行如下:

- name: Build base image
  working-directory: business
  run: docker build -t my-project/base .

- name: Build and push service
  working-directory: service
  run: |
    docker build -t my-ecr-repo/service .
    docker push my-ecr-repo/service

但是后來我找到了 docker/build-push-action 並決定在我的管道中使用它:

- name: Build business-layer container
  uses: docker/build-push-action@v2
  with:
    load: true
    tags: my-project/base
    context: business
    file: business/Dockerfile

- name: Build service
  uses: docker/build-push-action@v2
  with:
    push: true
    tags: my-ecr-repo/service
    context: service
    file: service/Dockerfile

至於現在,第二步嘗試下載docker.io /my-project/base,顯然做不到,因為我從來沒有推送過base image:

ERROR: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

問題是:構建鏡像的正確方法什么,因此可以通過以下構建步驟在本地訪問它?

PS:我不想將我的裸體basic圖像推到任何地方。

我相信您需要在基本圖像和最終圖像中設置load: true 這改變了使用本地 docker 引擎處理圖像的行為。 我相信如果你這樣做,你需要運行一個單獨的推送,例如:

- name: Build business-layer container
  uses: docker/build-push-action@v2
  with:
    load: true
    tags: my-project/base
    context: business
    file: business/Dockerfile

- name: Build service
  uses: docker/build-push-action@v2
  with:
    load: true
    tags: my-ecr-repo/service
    context: service
    file: service/Dockerfile

- name: push service
  run: |
    docker push my-ecr-repo/service

另一種選擇是使用本地注冊表。 這具有支持多平台構建的優勢。 但是你會想要從load切換到使用你的基本圖像push ,我會將基本圖像作為構建參數傳遞,以使其更容易用於 Github 操作之外的用例,例如:

jobs:
  local-registry:
    runs-on: ubuntu-latest
    services:
      registry:
        image: registry:2
        ports:
          - 5000:5000
    steps:
      - name: Login to DockerHub
        uses: docker/login-action@v1 
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      # qemu should only be needed for multi-platform images
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
        with:
          driver-opts: network=host
      - name: Build business-layer container
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: localhost:5000/my-project/base
          context: business
          file: business/Dockerfile
      - name: Build service
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: my-ecr-repo/service
          context: service
          file: service/Dockerfile
          build-args: |
            BASE_IMAGE=localhost:5000/my-project/base

然后您的 Dockerfile 將允許將基本映像指定為構建參數:

ARG BASE_IMAGE=my-project/base
FROM ${BASE_IMAGE}
# ...

GitHub的動作docker/setup-buildx-action@v1默認為駕駛員docker-container如記錄
這意味着構建將默認在容器中運行,因此圖像在操作之外將不可用。
解決方案是將驅動程序設置為docker

     ...

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
        with:
          driver: docker # defaults to "docker-containerized"

      - name: Build business-layer container
        uses: docker/build-push-action@v2
        with:
          # using "load: true" forces the docker driver
          # not necessary here, because we set it before
          #load: true
          tags: my-project/base:latest
          context: business
          file: business/Dockerfile

      - name: Build service
        uses: docker/build-push-action@v2
        with:
          # using "push: true" will lead to error:
          # Error: buildx call failed with: auto-push is currently not implemented for docker driver
          # so you will have to follow the solution outlined here:
          # https://github.com/docker/build-push-action/issues/100#issuecomment-715352826
          # and push the image manually following the build
          #push: true
          tags: my-ecr-repo/service:latest
          context: service
          file: service/Dockerfile

      # list all images, you will see my-ecr-repo/service and my-project/base
      - name: Look up images
        run: docker image ls

      # push the image manually, see above comment
      - name: Push image
        run: docker push my-ecr-repo/service:latest

     ...

在構建期間使用本地映像沒有涉及特殊步驟。 Docker 總是在進入注冊表之前檢查您在本地擁有的內容。 如果您在一個會話中完成了兩個步驟並且沒有在某處打錯字 - 它就可以正常工作。

現在,如果沒有,則只剩下兩個可能的問題來源:要么是您構建這些圖像的環境,要么是您使用的操作。 嘗試在ubuntu-latest上運行,看看是否有任何更改以消除第一個。

我還可以為您提供兩種解決方案,但您可能不會同時喜歡它們:

1. 使用臨時本地注冊表。 我在您使用的操作的自述頁面上找到了本指南,並為您的代碼稍微更改了它:

jobs:
  local-registry:
    runs-on: ubuntu-latest
    services:
      registry:
        image: registry:2
        ports:
          - 5000:5000
    steps:
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v2
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
        with:
          driver-opts: network=host
      -
        name: Build business-layer container
        uses: docker/build-push-action@v2
        with:
          load: true
          tags: localhost:5000/my-project/base
          context: business
          file: business/Dockerfile
      - 
        name: Build service
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: my-ecr-repo/service
          context: service
          file: service/Dockerfile

當然,您必須更新service/Dockerfile以指向localhost:5000/my-project/base而不僅僅是my-project/base

2. 使用簡單的 shell 而不是 build-push-action。 如果您的舊代碼有效而該操作無效,那么問題可能出在操作中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM