跳至主要内容

关于服务容器

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

关于服务容器

服务容器是 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 主机。更多信息,请参见“关于服务容器”。

创建服务容器

您可以使用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将 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 容器仓库进行身份验证的示例

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 }}

进一步阅读