如何在 Github Action 中构建、运行和调用 Docker 容器

8
我需要从当前代码库的源代码构建Docker镜像,运行一个容器,然后执行一些API调用。如何使用GitHub Action完成这个任务?
name: Docs Generator
on:
  pull_request:
    types: [opened]

jobs:
  pr-labeler:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
          uses: actions/checkout@v2
          with:
            ref: ${{ github.event.pull_request.head.ref }}
            repository: ${{ github.event.pull_request.head.repo.full_name }}
          
      - name: Get the version
        id: vars
        run: echo ::set-output name=tag::$(echo ${GITHUB_REF:10})
        
      - name: Build the tagged Docker image
        run: docker build . --file Dockerfile --tag service:${{steps.vars.outputs.tag}}
        
      - name: Run docker image
        docker run -v ${{ inputs.path }}:/src service:${{steps.vars.outputs.tag}}

      - name: Call API
        run: |
          curl +x http://localhost:8080/test
       
       .....

2个回答

5
我们可以采用以下方法来实现。
优点:
  • 不需要推送中间的 Docker 构建
  • 我们可以一步构建 docker,并在另一步中使用它,而无需将其推送到任何注册表中
  • 我们需要 docker/build-push-action 来构建 docker 和 addnab/docker-run-action 来运行 docker。
以下示例展示了一个单元测试流程。但是概念对于您的流程仍然相同。
...
jobs:
  unittest:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3    
      - uses: docker/setup-buildx-action@v2
      - uses: docker/build-push-action@v4
        with:
          context: .
          file: "Dockerfile.test"
          tags: localpytest:latest
          load: true
          cache-from: type=gha
          cache-to: type=gha,mode=max
          push: false
      - name: Run Pytest
        uses: addnab/docker-run-action@v3
        with:
          image: localpytest:latest
          run: pytest    

  • 对于addnab/docker-run-action,请注意load参数。默认值为false。必须将其设置为true才能在另一个步骤中使用一个步骤中的镜像。
  • 对于addnab/docker-run-action,请将push参数设置为false。因此,我们不会将其推送到任何Docker注册表中。
  • Github还提供了Docker层缓存。这有助于提高后续构建的速度。

3
为此,您可以结合使用https://github.com/marketplace/actions/build-and-push-docker-imageshttps://github.com/addnab/docker-run-action。第一个构建并发布容器,第二个则将该容器用于运行命令。
下面是示例。我自己不使用这种设置,但我已经测试过了。请用您的用户名和容器名称替换username/container
name: Docker Image CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
    compile:
        name: Build and run the container
        runs-on: ubuntu-latest
        steps:
          - name: Set up QEMU
            uses: docker/setup-qemu-action@v1
          - name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v1
          - name: Login to DockerHub
            uses: docker/login-action@v1
            with:
              username: ${{ secrets.DOCKERHUB_USERNAME }}
              password: ${{ secrets.DOCKERHUB_TOKEN }}
          - name: Build and push
            uses: docker/build-push-action@v2
            with:
              push: true
              tags: username/container
          - name: Check out the repo
            uses: actions/checkout@v2
          - name: Run the build process with Docker
            uses: addnab/docker-run-action@v3
            with:
                image: username/container:latest
                options: -v ${{ github.workspace }}:/data
                run: |
                    echo "Hello World"


请注意,构建容器是一个相当耗时的任务,可能会很快消耗您的Github Action限制。您可以考虑单独构建/发布容器,或在此处添加更好的缓存(即仅在Dockerfile更改时重建它)。
请注意,您需要设置DOCKERHUB_USERNAME和DOCKERHUB_TOKEN密钥。
不要使用echo "Hello World",而应使用您想要运行的命令。对于这个设置,repo数据将在/data目录中。

如果您的 docker run 步骤(例如:echo "Hello World")失败了,该步骤仍将被视为成功继续执行,是否有一种方法可以捕获容器中出现的错误? - csaba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接