关于服务容器
服务容器是 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
容器。
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
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。
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
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 进行身份验证的示例:
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 }}
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 }}