Skip to main content

关于服务容器

您可以使用服务容器将数据库、网络服务、内存缓存及其他工具连接到您的工作流程。

关于服务容器

服务容器是 Docker 容器,以简便、可携带的方式托管您可能需要在工作流程中测试或操作应用程序的服务。 例如,您的工作流程可能必须运行需要访问数据库和内存缓存的集成测试。

您可以为工作流程中的每个作业配置服务容器。 GitHub 为工作流中配置的每个服务创建一个新的 Docker 容器,并在作业完成后销毁该服务容器。 作业中的步骤可与属于同一作业的所有服务容器通信。 但是,你不能在组合操作中创建和使用服务容器。

注意:如果工作流使用 Docker 容器操作、作业容器或服务容器,则必须使用 Linux 运行器:

  • 如果您要使用 GitHub 托管的运行器,则必须使用 Ubuntu 运行器。
  • 如果您要使用自托管运行器,则必须使用 Linux 机器作为运行器,并且必须安装 Docker。

与服务容器通信

您可以在工作流程中配置作业直接在运行器机器或 Docker 容器上运行。 作业与其服务容器之间的通信根据作业是直接在运行器上运行还是在容器中运行而有所不同。

在容器中运行作业

在容器中运行作业时,GitHub 使用 Docker 的用户定义桥接网络将服务容器连接到作业。 有关详细信息,请参阅 Docker 文档中的“桥网络驱动程序”。

在容器中运行作业和服务可简化网络访问。 您可以使用工作流程中配置的标签访问服务容器。 服务容器的主机名自动映射到标签名称。 例如,如果创建带有标签 redis 的服务容器,则该服务容器的主机名为 redis

您无需为服务容器配置任何端口。 默认情况下,属于同一 Docker 网络的所有容器会相互显示所有端口,但在 Docker 网络外部不会显示任何端口。

在运行器机器上运行作业

直接在运行程序计算机上运行作业时,你可以使用 localhost:<port>127.0.0.1:<port> 访问服务容器。 GitHub 配置容器网络以启用从服务容器到 Docker 主机的通信。

当作业直接在运行器机器上运行时, Docker 容器中运行的服务默认情况下不会向运行器上的作业显示其端口。 您需要将服务容器上的端口映射到 Docker 主机。 有关详细信息,请参阅“关于服务容器”。

创建服务容器

可以使用 services 关键字创建作为工作流作业的一部分的服务容器。 有关详细信息,请参阅 jobs.<job_id>.services

此示例在名为 container-job 的作业中创建名为 redis 的服务。 此示例中的 Docker 主机是 node:16-bullseye 容器。

YAML
name: Redis container example
on: push

jobs:
  # Label of the container job
  container-job:
    # Containers must run in Linux based operating systems
    runs-on: ubuntu-latest
    # Docker Hub image that `container-job` executes in
    container: node:16-bullseye

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis

映射 Docker 主机和服务容器端口

如果作业在 Docker 容器中运行,则不需要映射主机或服务容器上的端口。 如果作业直接在运行器机器上运行,则需要将任何必需的服务容器端口映射到主机运行器机器上的端口。

可以使用 ports 关键字将服务容器端口映射到 Docker 主机。 有关详细信息,请参阅 jobs.<job_id>.services

ports 的值说明
8080:80将容器中的 TCP 端口 80 映射到 Docker 主机上的端口 8080。
8080:80/udp将容器中的 UDP 端口 80 映射到 Docker 主机上的端口 8080。
8080/udp将容器中随机选择的 UDP 端口映射到 Docker 主机上的 UDP 端口 8080。

使用 ports 关键字映射端口时,GitHub 使用 --publish 命令将容器的端口发布到 Docker 主机。 有关详细信息,请参阅 Docker 文档中的“Docker 容器网络”。

指定 Docker 主机端口但不指定容器端口时,容器端口将随机分配给空闲端口。 GitHub 在服务容器上下文中设置分配的容器端口。 例如,对于 redis 服务容器,如果配置了 Docker 主机端口 5432,则可以使用 job.services.redis.ports[5432] 上下文访问对应的容器端口。 有关详细信息,请参阅“访问有关工作流运行的上下文信息”。

映射 Redis 端口的示例

此示例将服务容器 redis 端口 6379 映射到 Docker 主机端口 6379。

YAML
name: Redis Service Example
on: push

jobs:
  # Label of the container job
  runner-job:
    # You must use a Linux environment when using service containers or container jobs
    runs-on: ubuntu-latest

    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis
        #
        ports:
          # Opens tcp port 6379 on the host and service container
          - 6379:6379

使用映像注册表进行身份验证

如果需要使用映像注册表进行身份验证,则可以指定服务容器的凭据。 这允许使用专用注册表中的映像或提高 DockerHub 速率限制

下面是使用 Docker Hub 和 GitHub Container registry 进行身份验证的示例:

YAML
jobs:
  build:
    services:
      redis:
        # Docker Hub image
        image: redis
        ports:
          - 6379:6379
        credentials:
          username: ${{ secrets.dockerhub_username }}
          password: ${{ secrets.dockerhub_password }}
      db:
        # Private registry image
        image:  ghcr.io/octocat/testdb:latest
        credentials:
          username: ${{ github.repository_owner }}
          password: ${{ secrets.ghcr_password }}

延伸阅读