跳到主要内容

创建 Redis 服务容器

您可以使用服务容器在工作流中创建 Redis 客户端。本指南展示了为在容器中或直接在 Runner 机器上运行的作业创建 Redis 服务的示例。

简介

本指南向您展示了使用 Docker Hub `redis` 镜像配置服务容器的工作流示例。工作流运行一个脚本以创建 Redis 客户端并使用数据填充客户端。为了测试工作流是否创建并填充了 Redis 客户端,脚本会将客户端的数据打印到控制台。

注意

如果您的工作流使用 Docker 容器 Actions、作业容器或服务容器,则必须使用 Linux Runner。

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

先决条件

您应该熟悉服务容器如何在 GitHub Actions 中工作以及直接在 Runner 上运行作业还是在容器中运行作业的网络差异。有关更多信息,请参阅“关于服务容器”。

您可能还会发现对 YAML(GitHub Actions 的语法)和 Redis 有基本的了解很有帮助。有关更多信息,请参阅

在容器中运行作业

将作业配置为在容器中运行可以简化作业和服务容器之间的网络配置。同一用户定义的桥接网络上的 Docker 容器会相互公开所有端口,因此您无需将任何服务容器端口映射到 Docker 主机。您可以使用在工作流中配置的标签从作业容器访问服务容器。

您可以将此工作流文件复制到存储库的 `.github/workflows` 目录,并根据需要进行修改。

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:20-bookworm-slim

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      # Downloads a copy of the code in your repository before running CI tests
      - name: Check out repository code
        uses: actions/checkout@v4

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.net.cn/cli/ci.html
      - name: Install dependencies
        run: npm ci

      - name: Connect to Redis
        # Runs a script that creates a Redis client, populates
        # the client with data, and retrieves data
        run: node client.js
        # Environment variable used by the `client.js` script to create a new Redis client.
        env:
          # The hostname used to communicate with the Redis service container
          REDIS_HOST: redis
          # The default Redis port
          REDIS_PORT: 6379

配置容器作业

此工作流配置了一个在 `node:20-bookworm-slim` 容器中运行的作业,并使用 `ubuntu-latest` GitHub 托管的 Runner 作为容器的 Docker 主机。有关 `node:20-bookworm-slim` 容器的更多信息,请参阅 Docker Hub 上的 node 镜像

此工作流使用标签 `redis` 配置了一个服务容器。所有服务都必须在容器中运行,因此每个服务都需要指定容器 `image`。此示例使用 `redis` 容器镜像,并包含健康检查选项以确保服务正在运行。将标签附加到镜像名称以指定版本,例如 `redis:6`。有关更多信息,请参阅 Docker Hub 上的 redis 镜像

YAML
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:20-bookworm-slim

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

配置容器作业的步骤

此工作流执行以下步骤:

  1. 在 Runner 上检出存储库
  2. 安装依赖项
  3. 运行脚本以创建客户端
YAML
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v4

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.net.cn/cli/ci.html
  - name: Install dependencies
    run: npm ci

  - name: Connect to Redis
    # Runs a script that creates a Redis client, populates
    # the client with data, and retrieves data
    run: node client.js
    # Environment variable used by the `client.js` script to create a new Redis client.
    env:
      # The hostname used to communicate with the Redis service container
      REDIS_HOST: redis
      # The default Redis port
      REDIS_PORT: 6379

client.js 脚本查找 `REDIS_HOST` 和 `REDIS_PORT` 环境变量来创建客户端。工作流程在“连接到 Redis”步骤中设置这两个环境变量,以便 client.js 脚本可以使用它们。有关该脚本的更多信息,请参见“测试 Redis 服务容器”。

Redis 服务的主机名是您在工作流程中配置的标签,在本例中为 `redis`。由于同一用户定义的桥接网络上的 Docker 容器默认情况下会打开所有端口,因此您可以通过默认的 Redis 端口 6379 访问服务容器。

直接在运行器机器上运行作业

当您直接在运行器机器上运行作业时,需要将服务容器上的端口映射到 Docker 主机上的端口。您可以使用 `localhost` 和 Docker 主机端口号从 Docker 主机访问服务容器。

您可以将此工作流文件复制到存储库的 `.github/workflows` 目录,并根据需要进行修改。

YAML
name: Redis runner example
on: push

jobs:
  # Label of the runner 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
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          # Maps port 6379 on service container to the host
          - 6379:6379

    steps:
      # Downloads a copy of the code in your repository before running CI tests
      - name: Check out repository code
        uses: actions/checkout@v4

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.net.cn/cli/ci.html
      - name: Install dependencies
        run: npm ci

      - name: Connect to Redis
        # Runs a script that creates a Redis client, populates
        # the client with data, and retrieves data
        run: node client.js
        # Environment variable used by the `client.js` script to create
        # a new Redis client.
        env:
          # The hostname used to communicate with the Redis service container
          REDIS_HOST: localhost
          # The default Redis port
          REDIS_PORT: 6379

配置运行器作业

此示例使用 `ubuntu-latest` GitHub 托管的运行器作为 Docker 主机。

此工作流使用标签 `redis` 配置了一个服务容器。所有服务都必须在容器中运行,因此每个服务都需要指定容器 `image`。此示例使用 `redis` 容器镜像,并包含健康检查选项以确保服务正在运行。将标签附加到镜像名称以指定版本,例如 `redis:6`。有关更多信息,请参阅 Docker Hub 上的 redis 镜像

工作流程将 Redis 服务容器上的 6379 端口映射到 Docker 主机。有关 `ports` 关键字的更多信息,请参见“关于服务容器”。

YAML
jobs:
  # Label of the runner 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
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          # Maps port 6379 on service container to the host
          - 6379:6379

配置运行器作业的步骤

此工作流执行以下步骤:

  1. 在 Runner 上检出存储库
  2. 安装依赖项
  3. 运行脚本以创建客户端
YAML
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v4

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.net.cn/cli/ci.html
  - name: Install dependencies
    run: npm ci

  - name: Connect to Redis
    # Runs a script that creates a Redis client, populates
    # the client with data, and retrieves data
    run: node client.js
    # Environment variable used by the `client.js` script to create
    # a new Redis client.
    env:
      # The hostname used to communicate with the Redis service container
      REDIS_HOST: localhost
      # The default Redis port
      REDIS_PORT: 6379

client.js 脚本查找 `REDIS_HOST` 和 `REDIS_PORT` 环境变量来创建客户端。工作流程在“连接到 Redis”步骤中设置这两个环境变量,以便 client.js 脚本可以使用它们。有关该脚本的更多信息,请参见“测试 Redis 服务容器”。

主机名是 `localhost` 或 `127.0.0.1`。

测试 Redis 服务容器

您可以使用以下脚本来测试您的工作流程,该脚本创建一个 Redis 客户端并使用一些占位符数据填充客户端。然后,脚本将存储在 Redis 客户端中的值打印到终端。您的脚本可以使用任何您喜欢的语言,但此示例使用 Node.js 和 `redis` npm 模块。更多信息,请参见 npm redis 模块

您可以修改 client.js 以包含工作流程所需的任何 Redis 操作。在此示例中,脚本创建 Redis 客户端实例,添加占位符数据,然后检索数据。

向您的存储库添加一个名为 client.js 的新文件,其中包含以下代码。

JavaScript
const redis = require("redis");

// Creates a new Redis client
// If REDIS_HOST is not set, the default host is localhost
// If REDIS_PORT is not set, the default port is 6379
const redisClient = redis.createClient({
  url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`
});

redisClient.on("error", (err) => console.log("Error", err));

(async () => {
  await redisClient.connect();

  // Sets the key "octocat" to a value of "Mona the octocat"
  const setKeyReply = await redisClient.set("octocat", "Mona the Octocat");
  console.log("Reply: " + setKeyReply);
  // Sets a key to "species", field to "octocat", and "value" to "Cat and Octopus"
  const SetFieldOctocatReply = await redisClient.hSet("species", "octocat", "Cat and Octopus");
  console.log("Reply: " + SetFieldOctocatReply);
  // Sets a key to "species", field to "dinotocat", and "value" to "Dinosaur and Octopus"
  const SetFieldDinotocatReply = await redisClient.hSet("species", "dinotocat", "Dinosaur and Octopus");
  console.log("Reply: " + SetFieldDinotocatReply);
  // Sets a key to "species", field to "robotocat", and "value" to "Cat and Robot"
  const SetFieldRobotocatReply = await redisClient.hSet("species", "robotocat", "Cat and Robot");
  console.log("Reply: " + SetFieldRobotocatReply);

  try {
    // Gets all fields in "species" key
    const replies = await redisClient.hKeys("species");
    console.log(replies.length + " replies:");
    replies.forEach((reply, i) => {
        console.log("    " + i + ": " + reply);
    });
    await redisClient.quit();
  }
  catch (err) {
    // statements to handle any exceptions
  }
})();

该脚本使用 `createClient` 方法创建一个新的 Redis 客户端,该方法接受 `host` 和 `port` 参数。该脚本使用 `REDIS_HOST` 和 `REDIS_PORT` 环境变量来设置客户端的 IP 地址和端口。如果未定义 `host` 和 `port`,则默认主机为 `localhost`,默认端口为 6379。

该脚本使用 `set` 和 `hset` 方法使用一些键、字段和值填充数据库。为了确认 Redis 客户端包含数据,脚本将数据库的内容打印到控制台日志。

运行此工作流程时,您应该在“连接到 Redis”步骤中看到以下输出,确认您已创建 Redis 客户端并添加了数据。

Reply: OK
Reply: 1
Reply: 1
Reply: 1
3 replies:
    0: octocat
    1: dinotocat
    2: robotocat