从操作中通过 github 操作中的主机名访问容器

whi*_*cko 10 docker docker-network github-actions

我在 github 操作中启动了一个 docker 容器,并尝试从操作中访问它。但该操作无法解析主机名。如何将我的容器添加到与操作相同的 docker 网络并让操作通过其主机名访问它?

steps:
  - name: Run Fuseki
    run: docker run -p 3030:3030 --name fuseki -d stain/jena-fuseki /jena-fuseki/fuseki-server --file=/staging/aksw.org.nt /aksw
  - name: curl
    uses: wei/curl@master
    with:
      args: https://fuseki:3030/aksw
Run Code Online (Sandbox Code Playgroud)

完整的文件可以在 GitHub 上找到。

ITC*_*hap 10

当我在 shell 步骤中混合使用服务、docker 操作和普通的旧 docker 命令时,我的工作流程中也遇到了同样的问题。目前,我只看到两种可能的解决方法:

  1. 在主机网络上运行所有内容。服务可以在主机上发布其端口。使用ports字段。例如:
   services:
      redis:
        image: redis
        ports:
          - 6379:6379
Run Code Online (Sandbox Code Playgroud)

在其他步骤和操作中,您可以将该--network "host"选项传递给 docker。要访问任何容器只需调用localhost:port. 这将在您的步骤的外壳和容器内工作。这是最简单的解决方案。不幸的是,服务之间可能会发生冲突,而且我真的不知道在 github 托管运行器上执行此操作是否会产生任何严重的安全隐患。

  1. 您可以使用运行程序在创建的网络中启动容器--network ${{ job.container.network }}。通过传递,--cidfile $CID_FILE您可以将容器的 id 存储在文件中$CID_FILE。从那里您可以使用 docker inform 并输出容器 IP 地址。通过这样做,即使容器的名称无法解析,您仍然可以使用 IP 地址从一个容器连接到另一个容器。以下是如何通过一个简单的操作来实现它:
    name: Docker start container
    description: Start a detached container
    
    inputs:
      image:
        description: The image to use
        required: true
      name:
        description: The container name
        required: true
      options:
        description: Additional options to pass to docker run
        required: false
        default: ''
      command:
        description: The command to run
        required: false
        default: ''
    
    outputs:
      cid:
        description: Container ID
        value: ${{ steps.info.outputs.cid }}
      address:
        description: Container ID
        value: ${{ steps.info.outputs.address }}
    
    runs:
      using: composite
      steps:
        - name: Pull
          shell: bash
          run: docker pull ${{ inputs.image }}
    
        - name: Run
          env:
            CID_FILE: ${{ inputs.name }}.cid
          shell: bash
          run: >
            docker run -d
            --name ${{ inputs.name }}
            --network host
            --cidfile $CID_FILE
            ${{ inputs.options }}
            ${{ inputs.image }}
            ${{ inputs.command }}

        - name: Info
          id: info
          shell: bash
          run: |
            export CID=$(cat $CID_FILE)
            export ADDR=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CID)
            echo "::set-output name=cid::$CID"
            echo "::set-output name=address::$ADDR"
Run Code Online (Sandbox Code Playgroud)

这可能更安全,但除了增加复杂性之外,它还有一个主要缺点:作业启动时不知道容器地址。这意味着您无法使用作业范围的环境变量将任何这些 IP 地址传递到其他容器。


whi*_*cko 2

我的解决方案是定义一个自定义 docker 网络并且不使用操作,而是将后续服务作为 docker 容器运行。这不是很干净,但只要 GitHub 不允许我指定操作的自定义网络或记录如何使我的自定义容器可用于操作 DNS,就可以工作。

steps:
  - name: Create Docker Network
    run: docker network create data
  - name: Run Fuseki
    run: docker run -v ${{ github.workspace }}/.aksw-model:/staging --network data --name fuseki -d stain/jena-fuseki /jena-fuseki/fuseki-server --file=/staging/aksw.org.nt /aksw
  - name: curl
    run: docker run --rm --network data curlimages/curl:latest http://fuseki:3030/aksw
Run Code Online (Sandbox Code Playgroud)

实际完整的文件可在 GitHub 上找到。