サービス コンテナー
Azure DevOps Services
パイプラインで 1 つ以上のサービスのサポートが必要な場合は、ジョブごとにサービスの作成、接続、クリーンアップが必要になる場合があります。 たとえば、パイプラインでは、新しく作成されたデータベースと、パイプライン内の各ジョブのメモリ キャッシュへのアクセスを必要とする統合テストを実行できます。
コンテナーは、パイプラインが依存するサービスを簡単かつ移植可能な方法で実行できます。 サービス コンテナーを使用すると、コンテナー化されたサービスのライフサイクルを自動的に作成、ネットワーク化、管理できます。 各サービス コンテナーには、それを必要とする job のみがアクセスできます。 サービス コンテナーはあらゆる種類のジョブで動作しますが、 コンテナー ジョブで最もよく使用されます。
要件
サービス コンテナーでは、
CMD
またはENTRYPOINT
を定義する必要があります。 パイプラインは、指定されたコンテナーに対して引数なしでdocker run
実行されます。Azure Pipelines では、Linux コンテナーまたは Windows コンテナーを実行できます。 Linux コンテナー用のホストされた Ubuntu コンテナー プールまたは Windows コンテナー用のホストされた Windows プールを使用できます。 ホストされている macOS プールは、コンテナーの実行をサポートしていません。
Note
サービス コンテナーは、クラシック パイプラインではサポートされていません。
単一コンテナー ジョブ
次の YAML パイプライン定義の例は、1 つのコンテナー ジョブを示しています。
resources:
containers:
- container: my_container
image: buildpack-deps:focal
- container: nginx
image: nginx
pool:
vmImage: 'ubuntu-latest'
container: my_container
services:
nginx: nginx
steps:
- script: |
curl nginx
displayName: Show that nginx is running
上記のパイプラインは、Docker Hub からnginx
コンテナーとbuildpack-deps
コンテナーをフェッチしコンテナーを開始します。 コンテナーはネットワークでつながっているため、services
名で互いに接続できます。
このジョブ コンテナー内から、 nginx
ホスト名は、Docker ネットワークを使用して適切なサービスに解決されます。 ネットワーク上のすべてのコンテナーは、自動的にすべてのポートを互いに公開します。
単一の非コンテナー ジョブ
次の例のように、ジョブ コンテナーなしでサービス コンテナーを使用することもできます。
resources:
containers:
- container: nginx
image: nginx
ports:
- 8080:80
env:
NGINX_PORT: 80
- container: redis
image: redis
ports:
- 6379
pool:
vmImage: 'ubuntu-latest'
services:
nginx: nginx
redis: redis
steps:
- script: |
curl localhost:8080
echo $AGENT_SERVICES_REDIS_PORTS_6379
上記のパイプラインは、最新の nginx
コンテナーを開始します。 ジョブはコンテナーで実行されていないため、名前の自動解決は行われません。 代わりに、 localhost
を使用してサービスにアクセスできます。 この例では、 8080:80
ポートを明示的に提供します。
また、実行時にランダムなポートを動的に割り当てる方法もあります。 その後、変数を使用してこれらの動的ポートにアクセスできます。 これらの変数は、agent.services.<serviceName>.ports.<port>
の形式になります。 Bash スクリプトでは、プロセス環境を使用して変数にアクセスできます。
前の例では、 redis
には、ホストでランダムに使用可能なポートが割り当てられます。 agent.services.redis.ports.6379
変数にはポート番号が含まれています。
複数のジョブ
サービス コンテナーは、同じサービスの複数のバージョンに対して同じステップを実行する場合にも役立ちます。 次の例では、同じステップが複数のバージョンの PostgreSQL に対して実行されます。
resources:
containers:
- container: my_container
image: ubuntu:22.04
- container: pg15
image: postgres:15
- container: pg14
image: postgres:14
pool:
vmImage: 'ubuntu-latest'
strategy:
matrix:
postgres15:
postgresService: pg15
postgres14:
postgresService: pg14
container: my_container
services:
postgres: $[ variables['postgresService'] ]
steps:
- script: printenv
Port
コンテナー リソースまたはインライン コンテナーを呼び出すときに、次の例のように、コンテナーで公開する ports
の配列を指定できます。
resources:
containers:
- container: my_service
image: my_service:latest
ports:
- 8080:80
- 5432
services:
redis:
image: redis
ports:
- 6379/tcp
ジョブがコンテナーで実行されている場合、 ports
を指定する必要はありません。同じ Docker ネットワーク上のコンテナーでは、既定ですべてのポートが自動的に相互に公開されるためです。
ジョブがホストで実行されている場合、サービスにアクセスするには ports
が必要です。 ポートは、フォーム <hostPort>:<containerPort>
を受け取るか、末尾に省略可能な/<protocol>
を使用して<containerPort>
します。 たとえば、6379/tcp
は、ホスト コンピューター上のランダムなポートにバインドされたポート 6379
経由でtcp
を公開します。
ホスト マシン上のランダム ポートにバインドされたポートの場合、パイプラインは、ジョブがポートにアクセスできるように、 agent.services.<serviceName>.ports.<port>
形式の変数を作成します。 たとえば、agent.services.redis.ports.6379
はホスト コンピューター上のランダムに割り当てられたポートに解決されます。
ボリューム
ボリュームは、サービス間でデータを共有したり、ジョブの複数の実行間でデータを保持したりする場合に便利です。 ボリューム マウントは、フォーム <source>:<destinationPath>
のvolumes
の配列として指定します。ここで、<source>
はホスト コンピューター上の名前付きボリュームまたは絶対パスを指定でき、<destinationPath>
はコンテナー内の絶対パスです。 ボリュームには、Docker ボリューム、匿名 Docker ボリューム、またはホスト上のバインド マウントという名前を付けることができます。
services:
my_service:
image: myservice:latest
volumes:
- mydockervolume:/data/dir
- /data/dir
- /src/dir:/dst/dir
Note
Microsoft でホストされているプールを使用する場合、各ジョブが完了した後にホスト マシンがクリーンアップされるため、ジョブ間でボリュームは保持されません。
スタートアップ オプション
サービス コンテナーは、コンテナー ジョブと同じコンテナー リソースを共有します。 つまり、同じ スタートアップ オプションを使用できます。
正常性チェック
いずれかのサービス コンテナーで HEALTHCHECK が指定されている場合、エージェントは必要に応じて、コンテナーが正常になるまで待機してからジョブを実行できます。
サービスを含む複数のコンテナーの例
次の例では、PostgreSQL と MySQL データベース コンテナーに接続された Django Python Web コンテナーがあります。
- PostgreSQL データベースはプライマリ データベースであり、そのコンテナーには
db
という名前が付けられています。 db
コンテナーはボリューム/data/db:/var/lib/postgresql/data
を使用し、env
を介してコンテナーに渡される 3 つのデータベース変数があります。mysql
コンテナーはポート3306:3306
を使用し、env
経由で渡されるデータベース変数もあります。web
コンテナーはポート8000
で開いています。
この手順では、 pip
依存関係をインストールしてから、Django テストを実行します。
作業例を設定するには、2 つのデータベースを使用して Django サイトを設定する必要があります。 この例では、 manage.py ファイルがルート ディレクトリにあり、Django プロジェクトもそのディレクトリ内にあることを前提としています。 そうでない場合は、/__w/1/s/manage.py test
で/__w/1/s/
パスを更新する必要があります。
resources:
containers:
- container: db
image: postgres
volumes:
- '/data/db:/var/lib/postgresql/data'
env:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
- container: mysql
image: 'mysql:5.7'
ports:
- '3306:3306'
env:
MYSQL_DATABASE: users
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
MYSQL_ROOT_PASSWORD: mysql
- container: web
image: python
volumes:
- '/code'
ports:
- '8000:8000'
pool:
vmImage: 'ubuntu-latest'
container: web
services:
db: db
mysql: mysql
steps:
- script: |
pip install django
pip install psycopg2
pip install mysqlclient
displayName: set up django
- script: |
python /__w/1/s/manage.py test