Skip to main content

Docker サービス コンテナーとの通信

Docker サービス コンテナーを使って、データベース、Web サービス、メモリ キャッシュ、その他のツールをワークフローに接続する方法について説明します。

Docker サービス コンテナーとの通信

サービスコンテナは、ワークフロー中でアプリケーションをテストもしくは運用するのに必要になるかもしれないサービスをホストするための、シンプルでポータブルな方法を提供する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ホストに対してマップする必要があります。 詳しくは、「Docker サービス コンテナーとの通信」をご覧ください。

サービスコンテナの作成

          `services` キーワードを使って、ワークフロー内のジョブの一部であるサービスコンテナを作成できます。 詳細については、「[`jobs.<job_id>.services`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idservices)」を参照してください。

この例では、redis という名前のジョブで container-job という名前のサービスが作成されます。 この例の 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 コンテナー ネットワーク](https://docs.docker.com/config/containers/container-networking/)に関するページを参照してください。

コンテナー ポートを指定したが 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 }}

参考資料

  •         [AUTOTITLE](/actions/using-containerized-services/creating-redis-service-containers)
    
  •         [AUTOTITLE](/actions/using-containerized-services/creating-postgresql-service-containers)