{"meta":{"title":"Docker サービス コンテナーとの通信","intro":"Docker サービス コンテナーを使って、データベース、Web サービス、メモリ キャッシュ、その他のツールをワークフローに接続する方法について説明します。","product":"GitHub Actions","breadcrumbs":[{"href":"/ja/actions","title":"GitHub Actions"},{"href":"/ja/actions/tutorials","title":"チュートリアル"},{"href":"/ja/actions/tutorials/use-containerized-services","title":"コンテナー化されたサービスを使用する"},{"href":"/ja/actions/tutorials/use-containerized-services/use-docker-service-containers","title":"Docker サービス コンテナーを使用する"}],"documentType":"article"},"body":"# Docker サービス コンテナーとの通信\n\nDocker サービス コンテナーを使って、データベース、Web サービス、メモリ キャッシュ、その他のツールをワークフローに接続する方法について説明します。\n\n## Docker サービス コンテナーとの通信\n\nサービスコンテナは、ワークフロー中でアプリケーションをテストもしくは運用するのに必要になるかもしれないサービスをホストするための、シンプルでポータブルな方法を提供するDockerコンテナです。 たとえば、ワークフローでデータベースやメモリキャッシュへのアクセスを必要とする結合テストを実行する必要があるかもしれません。\n\nサービスコンテナは、ワークフロー中のそれぞれのジョブに対して設定できます。\nGitHub は、ワークフローで構成されたサービスごとに新しい Docker コンテナーを作成し、ジョブの完了時にサービス コンテナーを破棄します。 ジョブ内のステップは、同じジョブに含まれるすべてのサービスコンテナと通信できます。 ただし、複合アクション内でサービスコンテナーを作成して使用することはできません。\n\n> \\[!NOTE]\n> ワークフローで Docker コンテナー アクション、ジョブ コンテナー、またはサービス コンテナーが使われる場合は、Linux ランナーを使う必要があります。\n>\n> * GitHubホストランナーを使うなら、Ubuntuランナーを使わなければなりません。\n> * セルフホストランナーを使っているなら、ランナーとしてLinuxマシンを使い、Dockerをインストールしておかなければなりません。\n\nワークフロー中のジョブは、直接ランナーマシン上で実行するようにも、Dockerコンテナ中で実行するようにも設定できます。 ジョブと、ジョブのサービスコンテナとの通信は、ジョブがランナーマシン上で直接実行されているか、コンテナ内で実行されているかによって異なります。\n\n### コンテナ内でのジョブの実行\n\nコンテナーでジョブを実行すると、 GitHub は、Docker のユーザー定義ブリッジ ネットワークを使用してサービス コンテナーをジョブに接続します。 詳しくは、Docker ドキュメントの「[ブリッジ ネットワーク ドライバー](https://docs.docker.com/engine/network/drivers/bridge/)」を参照してください。\n\nコンテナ内でジョブとサービスを実行すれば、ネットワークアクセスはシンプルになります。 サービスコンテナへは、ワークフロー中で設定したラベルを使ってアクセスできます。 サービスコンテナのホスト名は、自動的にラベル名にマップされます。 たとえば、`redis` というラベルでサービスコンテナを作成したなら、そのサービスコンテナのホスト名は `redis` になります。\n\nサービスコンテナでポートを設定する必要はありません。 デフォルトで、すべてのコンテナは同じDockerネットワークの一部となってお互いにすべてのポートを公開し合い、Dockerネットワークの外部へはポートは公開されません。\n\n### ランナーマシン上でのジョブの実行\n\nランナーマシン上でジョブを直接実行する場合、`localhost:<port>` か `127.0.0.1:<port>` を使ってサービスコンテナにアクセスできます。\nGitHub は、サービス コンテナーから Docker ホストへの通信を有効にするようにコンテナー ネットワークを構成します。\n\nジョブがランナーマシン上で直接実行されている場合、Dockerコンテナ内で実行されているサービスは、ランナー上で実行しているジョブに対してデフォルトではポートを公開しません。 サービスコンテナ上のポートは、Dockerホストに対してマップする必要があります。 詳しくは、「[Docker サービス コンテナーとの通信](/ja/actions/tutorials/use-containerized-services/use-docker-service-containers#mapping-docker-host-and-service-container-ports)」をご覧ください。\n\n## サービスコンテナの作成\n\n`services` キーワードを使って、ワークフロー内のジョブの一部であるサービスコンテナを作成できます。 詳細については、「[`jobs.<job_id>.services`](/ja/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservices)」を参照してください。\n\nこの例では、`redis` という名前のジョブで `container-job` という名前のサービスが作成されます。 この例の Docker ホストは `node:16-bullseye` コンテナです。\n\n```yaml copy\nname: Redis container example\non: push\n\njobs:\n  # Label of the container job\n  container-job:\n    # Containers must run in Linux based operating systems\n    runs-on: ubuntu-latest\n    # Docker Hub image that `container-job` executes in\n    container: node:16-bullseye\n\n    # Service containers to run with `container-job`\n    services:\n      # Label used to access the service container\n      redis:\n        # Docker Hub image\n        image: redis\n```\n\n## Dockerホストとサービスコンテナのポートのマッピング\n\nジョブがDockerコンテナ内で実行されるなら、ポートをホストあるいはサービスコンテナにマップする必要はありません。 ジョブがランナーマシン上で直接実行されるなら、必要なサービスコンテナのポートはホストランナーマシンのポートにマップしなければなりません。\n\nサービスコンテナのポートは、`ports` キーワードを使って Docker ホストにマップできます。 詳細については、「[`jobs.<job_id>.services`](/ja/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservices)」を参照してください。\n\n| `ports` の値    | 説明                                                   |\n| ------------- | ---------------------------------------------------- |\n| `8080:80`     | コンテナのTCPのポート80をDockerホストのポート8080にマップします。             |\n| `8080:80/udp` | コンテナのUDPポート80をDockerホストのポート8080にマップします。              |\n| `8080/udp`    | Docker ホストでランダムに選択したポートをコンテナーの UDP ポート 8080 にマップします。 |\n\n`ports` キーワードを使用してポートをマップする場合、GitHubは `--publish` コマンドを使用してコンテナーのポートを Docker ホストに発行します。 詳しくは、Docker ドキュメントの [Docker コンテナー ネットワーク](https://docs.docker.com/config/containers/container-networking/)に関するページを参照してください。\n\nコンテナー ポートを指定したが Docker ホスト ポートを指定しなかった場合、コンテナー ポートは空きポートにランダムに割り当てられます。\nGitHub は、サービス コンテナー コンテキストで割り当てられたコンテナー ポートを設定します。 たとえば `redis` サービスコンテナに対し、Docker ホストのポート 5432 を設定したなら、対応するコンテナのポートには `job.services.redis.ports[5432]` コンテキストを使ってアクセスできます。 詳しくは、「[コンテキスト リファレンス](/ja/actions/reference/workflows-and-actions/contexts#job-context)」をご覧ください。\n\n### Redisのポートのマッピングの例\n\n以下の例は、サービスコンテナ `redis` のポート 6379 を、Docker ホストのポート 6379 にマップします。\n\n```yaml copy\nname: Redis Service Example\non: push\n\njobs:\n  # Label of the container job\n  runner-job:\n    # You must use a Linux environment when using service containers or container jobs\n    runs-on: ubuntu-latest\n\n    # Service containers to run with `runner-job`\n    services:\n      # Label used to access the service container\n      redis:\n        # Docker Hub image\n        image: redis\n        #\n        ports:\n          # Opens tcp port 6379 on the host and service container\n          - 6379:6379\n```\n\n## イメージレジストリによる認証\n\nイメージ レジストリで認証する必要がある場合は、サービス コンテナーの資格情報を指定できます。 これにより、プライベート レジストリのイメージを使用したり、[DockerHub のレート制限を引き上げたりすることができます](https://www.docker.com/increase-rate-limits/)。\n\nDocker Hub と GitHubContainer registryを使用した認証の例を次に示します。\n\n```yaml copy\njobs:\n  build:\n    services:\n      redis:\n        # Docker Hub image\n        image: redis\n        ports:\n          - 6379:6379\n        credentials:\n          username: ${{ secrets.dockerhub_username }}\n          password: ${{ secrets.dockerhub_password }}\n      db:\n        # Private registry image\n        image: ghcr.io/octocat/testdb:latest\n        credentials:\n          username: ${{ github.repository_owner }}\n          password: ${{ secrets.ghcr_password }}\n```\n\n## サービス コンテナーのエントリポイントとコマンドのカスタマイズ\n\n既定では、サービス コンテナーは、Docker イメージで定義されたエントリポイントとコマンドを使用して実行されます。 これらのキーは、 `entrypoint` キーと `command` キーを使用してオーバーライドできます。 これは、カスタム ラッパー イメージを作成せずに、サービス (データベースなど) にフラグを渡すか、イメージエントリポイントを完全にスワップする必要がある場合に便利です。\n\n`command` キーは、イメージの既定のコマンド (`CMD`) をオーバーライドします。 ほとんどのシナリオでは、 `command`のみが必要です。イメージには既に適切なエントリ ポイントがあり、フラグを渡すだけで済みます。\n\n```yaml copy\nservices:\n  mysql:\n    image: mysql:8\n    command: --sql_mode=STRICT_TRANS_TABLES --max_allowed_packet=512M\n    env:\n      MYSQL_ROOT_PASSWORD: test\n    ports:\n      - 3306:3306\n```\n\n`entrypoint` キーは、イメージの`ENTRYPOINT`をオーバーライドします。 それを `command` と組み合わせて、カスタム エントリポイントに引数を渡すことができます。\n\n```yaml copy\nservices:\n  etcd:\n    image: quay.io/coreos/etcd:v3.5.17\n    entrypoint: etcd\n    command: >-\n      --listen-client-urls http://0.0.0.0:2379\n      --advertise-client-urls http://0.0.0.0:2379\n    ports:\n      - 2379:2379\n```\n\n名前付けと動作は Docker Compose と一致します。 詳細については、[`jobs.<job_id>.services.<service_id>.command`](/ja/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservicesservice_idcommand) および [`jobs.<job_id>.services.<service_id>.entrypoint`](/ja/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservicesservice_identrypoint) を参照してください。\n\n## 参考資料\n\n* [Redisサービスコンテナの作成](/ja/actions/tutorials/use-containerized-services/create-redis-service-containers)\n* [PostgreSQLサービスコンテナの作成](/ja/actions/tutorials/use-containerized-services/create-postgresql-service-containers)"}