GitHub 操作:是否可以从 Docker 容器中调用运行器主机?

GitHub Actions: Is it possible to call the runner host from a Docker container?

在下面的 GitHub Actions 工作流程中,我执行了一个 Gradle 构建,该构建针对 Micronaut 应用程序运行集成测试。此应用程序依赖于

jobs:
  build-test:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: [ '15' ]

    services:
      tempoapp-db:
        image: mariadb:10.4.15
        ports:
          - 3306:3306
        env:
          MYSQL_ROOT_PASSWORD: foo
          MYSQL_DATABASE: xoxo
          MYSQL_USER: bar
          MYSQL_PASSWORD: foobar

      security:
        image: security/image:0.1.15
        env:
          JAVA_TOOL_OPTIONS: "-Dcallback.url=http://<what to place here?>:8090"
        credentials:
          username: ${{ secrets.PACKAGES_USER }}
          password: ${{ secrets.PACKAGES_TOKEN }}
        ports:
          - 6000:8080

    steps:
      - name: Check out repository
        uses: actions/checkout@v2

      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: ${{ matrix.java }}

      - name: Build and test the application
        run: ./gradlew -s check publishToMavenLocal dockerPrepare

在集成测试阶段,security/image:0.1.15 Docker 容器需要访问 Docker 主机上的 Micronaut 应用程序 运行。在我的 Docker 桌面环境中,我通常使用主机名 host.docker.internal 从容器访问主机。这似乎不适用于 GitHub 操作,因为我收到以下错误

io.micronaut.http.client.exceptions.HttpClientException: Connect Error: host.docker.internal: Name does not resolve
    at io.micronaut.http.client.netty.DefaultHttpClient.lambda$null(DefaultHttpClient.java:1119)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616)

有没有办法获取主机的 IP 地址或主机名?

security:
  image: security/image:0.1.15
  env:
    JAVA_TOOL_OPTIONS: "-Dcallback.url=http://<what to place here?>:8090"

我已经设法解决了我的问题。这个答案给了我正确方向的提示 ()

AFAIK, in the case of Docker for Linux (standard distribution), the IP address of the host will always be 172.17.0.1 (on the main network of docker, see comments to learn more).

为了验证这一点,我添加了一个额外的工作流程步骤来启动 Alpine Linux 容器并打印 Docker 主机 ip(感谢 @Nek

  1. 运行 阿尔卑斯 Docker
  2. 更新依赖项(安静地)
  3. 安装 iproute2 包(安静地)
  4. (很好地)显示主机的 ip
  5. 删除 docker(感谢 --rm arg)
- name: Find Docker Host IP
  uses: addnab/docker-run-action@v1
  with:
    image: alpine:latest
    run: apk update > /dev/null && apk add iproute2 > /dev/null && ip -4 route show default | cut -d' ' -f3

正如您在下面的屏幕截图中看到的,IP 是 172.17.0.1

所以我将 IP 添加到我的 security 容器的 JAVA_TOOL_OPTIONS env 变量中,一切正常。

jobs:
  build-test:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: [ '15' ]

    services:
      tempoapp-db:
        image: mariadb:10.4.15
        ports:
          - 3306:3306
        env:
          MYSQL_ROOT_PASSWORD: foo
          MYSQL_DATABASE: xoxo
          MYSQL_USER: bar
          MYSQL_PASSWORD: foobar

      security:
        image: security/image:0.1.15
        env:
          JAVA_TOOL_OPTIONS: "-Dcallback.url=http://172.17.0.1:8090"
        credentials:
          username: ${{ secrets.PACKAGES_USER }}
          password: ${{ secrets.PACKAGES_TOKEN }}
        ports:
          - 6000:8080

    steps:
      - name: Check out repository
        uses: actions/checkout@v2

      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: ${{ matrix.java }}

      - name: Build and test the application
        run: ./gradlew -s check publishToMavenLocal dockerPrepare