Skip to main content

サービスコンテナについて

サービスコンテナを使って、データベース、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コンテナ内で実行されているサービスは、ランナー上で実行しているジョブに対してデフォルトではポートを公開しません。 サービスコンテナ上のポートは、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/udpDocker ホストでランダムに選択したポートをコンテナーの 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 }}

参考資料