Redis 서비스 컨테이너 만들기

Redis 서비스 컨테이너 만들기

서비스 컨테이너를 사용해서 워크플로우에 Redis 클라이언트를 만들 수 있어요. 이 가이드는 컨테이너에서 실행되거나 러너 머신에서 직접 실행되는 job을 위한 Redis 서비스를 만드는 예시를 보여줍니다.

출처: 문서

본문

Introduction

이 가이드는 Docker Hub redis 이미지를 사용해서 서비스 컨테이너를 구성하는 워크플로우 예시를 보여줍니다. 워크플로우는 Redis 클라이언트를 만들고 데이터로 채우는 스크립트를 실행해요. 워크플로우가 Redis 클라이언트를 만들고 채우는지 테스트하기 위해, 스크립트는 클라이언트의 데이터를 콘솔에 출력해요.

[!NOTE] 워크플로우가 Docker 컨테이너 액션, job 컨테이너 또는 서비스 컨테이너를 사용한다면 Linux 러너를 사용해야 해요.

  • GitHub에서 호스팅하는 러너를 사용한다면 Ubuntu 러너를 사용해야 해요.
  • 자체 호스팅 러너를 사용한다면 러너로 Linux 머신을 사용해야 하고 Docker가 설치되어 있어야 해요.

Prerequisites

서비스 컨테이너가 GitHub Actions에서 어떻게 동작하는지, 그리고 러너에서 job을 직접 실행할 때와 컨테이너에서 실행할 때의 네트워킹 차이점을 알고 있으면 좋아요. 자세한 내용은 Communicating with Docker service containers 문서를 참고하세요.

YAML, GitHub Actions 문법, Redis에 대한 기본적인 이해가 있으면 더 도움이 될 수 있어요. 자세한 내용은 다음을 참고하세요.

Running jobs in containers

job을 컨테이너에서 실행하도록 구성하면 job과 서비스 컨테이너 간의 네트워킹 구성이 단순해져요. 같은 사용자 정의 브리지 네트워크의 Docker 컨테이너는 서로에게 모든 포트를 노출하므로, 서비스 컨테이너 포트를 Docker 호스트에 매핑할 필요가 없어요. 워크플로우에서 구성한 레이블을 사용해서 job 컨테이너에서 서비스 컨테이너에 접근할 수 있어요.

이 워크플로우 파일을 저장소의 .github/workflows 디렉터리에 복사하고 필요에 따라 수정할 수 있어요.

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@v6

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.com/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

Configuring the container job

이 워크플로우는 node:20-bookworm-slim 컨테이너에서 실행되는 job을 구성하고, 컨테이너의 Docker 호스트로 ubuntu-latest GitHub에서 호스팅하는 러너를 사용해요. node:20-bookworm-slim 컨테이너에 대한 자세한 내용은 Docker Hub의 node image를 참고하세요.

이 워크플로우는 redis 레이블로 서비스 컨테이너를 구성해요. 모든 서비스는 컨테이너에서 실행되어야 하므로 각 서비스에 컨테이너 image를 지정해야 해요. 이 예시는 redis 컨테이너 이미지를 사용하고, 서비스가 실행 중인지 확인하기 위한 헬스 체크 옵션을 포함해요. 이미지 이름에 태그를 추가해서 버전을 지정할 수 있어요. 예를 들어 redis:6처럼요. 자세한 내용은 Docker Hub의 redis image를 참고하세요.

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

Configuring the steps for the container job

워크플로우는 다음 단계를 수행해요.

  1. 러너에서 저장소를 체크아웃합니다.
  2. 의존성을 설치합니다.
  3. 클라이언트를 만드는 스크립트를 실행합니다.
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v6

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.com/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_HOSTREDIS_PORT 환경 변수를 찾아요. 워크플로우는 "Connect to Redis" 단계의 일부로 이 두 환경 변수를 설정해서 client.js 스크립트가 사용할 수 있게 해요. 스크립트에 대한 자세한 내용은 Testing the Redis service container 문서를 참고하세요.

Redis 서비스의 호스트 이름은 워크플로우에서 구성한 레이블로, 이 경우 redis예요. 같은 사용자 정의 브리지 네트워크의 Docker 컨테이너는 기본적으로 모든 포트를 열기 때문에 기본 Redis 포트 6379에서 서비스 컨테이너에 접근할 수 있어요.

Running jobs directly on the runner machine

러너 머신에서 job을 직접 실행할 때는 서비스 컨테이너의 포트를 Docker 호스트의 포트에 매핑해야 해요. Docker 호스트에서 localhost와 Docker 호스트 포트 번호를 사용해서 서비스 컨테이너에 접근할 수 있어요.

이 워크플로우 파일을 저장소의 .github/workflows 디렉터리에 복사하고 필요에 따라 수정할 수 있어요.

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@v6

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.com/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

Configuring the runner job

예시는 Docker 호스트로 ubuntu-latest GitHub에서 호스팅하는 러너를 사용해요.

이 워크플로우는 redis 레이블로 서비스 컨테이너를 구성해요. 모든 서비스는 컨테이너에서 실행되어야 하므로 각 서비스에 컨테이너 image를 지정해야 해요. 이 예시는 redis 컨테이너 이미지를 사용하고, 서비스가 실행 중인지 확인하기 위한 헬스 체크 옵션을 포함해요. 이미지 이름에 태그를 추가해서 버전을 지정할 수 있어요. 예를 들어 redis:6처럼요. 자세한 내용은 Docker Hub의 redis image를 참고하세요.

이 워크플로우는 Redis 서비스 컨테이너의 포트 6379를 Docker 호스트에 매핑해요. ports 키워드에 대한 자세한 내용은 Communicating with Docker service containers 문서를 참고하세요.

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

Configuring the steps for the runner job

워크플로우는 다음 단계를 수행해요.

  1. 러너에서 저장소를 체크아웃합니다.
  2. 의존성을 설치합니다.
  3. 클라이언트를 만드는 스크립트를 실행합니다.
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v6

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.com/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_HOSTREDIS_PORT 환경 변수를 찾아요. 워크플로우는 "Connect to Redis" 단계의 일부로 이 두 환경 변수를 설정해서 client.js 스크립트가 사용할 수 있게 해요. 스크립트에 대한 자세한 내용은 Testing the Redis service container 문서를 참고하세요.

호스트 이름은 localhost 또는 127.0.0.1이에요.

Testing the Redis service container

Redis 클라이언트를 만들고 일부 자리 표시자 데이터로 채우는 다음 스크립트로 워크플로우를 테스트할 수 있어요. 그런 다음 스크립트는 Redis 클라이언트에 저장된 값을 터미널에 출력해요. 스크립트는 원하는 어떤 언어든 사용할 수 있지만, 이 예시는 Node.js와 redis npm 모듈을 사용해요. 자세한 내용은 npm redis module을 참고하세요.

워크플로우에 필요한 Redis 작업을 포함하도록 client.js를 수정할 수 있어요. 이 예시에서 스크립트는 Redis 클라이언트 인스턴스를 만들고, 자리 표시자 데이터를 추가한 다음 데이터를 검색해요.

다음 코드로 저장소에 client.js라는 새 파일을 추가하세요.

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
  }
})();

스크립트는 hostport 매개변수를 받는 createClient 메서드를 사용해서 새 Redis 클라이언트를 만들어요. 스크립트는 REDIS_HOSTREDIS_PORT 환경 변수를 사용해서 클라이언트의 IP 주소와 포트를 설정해요. hostport가 정의되지 않으면 기본 호스트는 localhost이고 기본 포트는 6379예요.

스크립트는 sethset 메서드를 사용해서 데이터베이스에 일부 키, 필드, 값을 채워요. Redis 클라이언트에 데이터가 있는지 확인하기 위해 스크립트는 데이터베이스의 내용을 콘솔 로그에 출력해요.

이 워크플로우를 실행하면 "Connect to Redis" 단계에서 다음 출력이 보여야 해요. 이는 Redis 클라이언트를 만들고 데이터를 추가했음을 확인해 줘요.

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

더 알아보기 (Learn more)