Docker Compose を使用する
Docker Compose は、連携して動作する複数のコンテナーをオーケストレーションする方法を提供します。たとえば、リクエストを処理するサービスとフロントエンド Web サイト、または Redis キャッシュなどのサポート機能を使用するサービスなどです。アプリ開発にマイクロサービス モデルを使用している場合、Docker Compose を使用して、アプリのコードを、Web リクエストを使用して通信するいくつかの独立して実行されるサービスに分割できます。この記事では、Node.js、Python、.NET のいずれであるかにかかわらず、アプリで Docker Compose を有効にする方法と、これらのシナリオで Visual Studio Code のデバッグを構成する方法について説明します。
また、単一コンテナーのシナリオでは、Docker Compose を使用すると、単一の Dockerfile ではできないツールに依存しない構成が可能になります。コンテナーのボリューム マウント、ポート マッピング、環境変数などの構成設定は、docker-compose YML ファイルで宣言できます。
Container Tools 拡張機能を使用して VS Code で Docker Compose を使用するには、Docker Compose の基本をすでに理解している必要があります。
プロジェクトに Docker Compose のサポートを追加する
すでに 1 つ以上の Dockerfile を持っている場合、コマンド パレット (⇧⌘P (Windows、Linux Ctrl+Shift+P)) を開き、Containers: Add Docker Compose Files to Workspace コマンドを使用することで、Docker Compose ファイルを追加できます。プロンプトに従ってください。
コマンド パレット (⇧⌘P (Windows、Linux Ctrl+Shift+P)) を開き、Containers: Add Docker Files to Workspace コマンドを使用することで、Dockerfile を追加すると同時に Docker Compose ファイルをワークスペースに追加できます。Docker Compose ファイルを追加するかどうか尋ねられます。既存の Dockerfile を保持したい場合は、Dockerfile を上書きするかどうかのプロンプトでいいえを選択してください。
Container Tools 拡張機能は、docker-compose.yml
ファイルをワークスペースに追加します。このファイルには、運用環境で想定どおりにコンテナーを起動するための構成が含まれています。場合によっては、docker-compose.debug.yml
も生成されます。このファイルは、デバッガーを有効にするための簡略化された起動モードを提供します。
VS Code Container Tools 拡張機能は、すぐに使用できるファイルを生成しますが、シナリオに合わせて最適化するためにカスタマイズすることもできます。その後、Containers: Compose Up コマンド (docker-compose.yml
ファイルを右クリックするか、コマンド パレットでコマンドを検索) を使用して、すべてを一度に開始できます。VS Code のコマンド プロンプトまたはターミナル ウィンドウから docker-compose up
コマンドを使用してコンテナーを開始することもできます。Docker Compose の動作を構成する方法と利用可能なコマンドライン オプションについては、Docker Compose ドキュメントを参照してください。
docker-compose ファイルを使用すると、.json 構成ファイルではなく、docker-compose ファイルでポート マッピングを指定できるようになりました。例については、Docker Compose ドキュメントを参照してください。
ヒント: Docker Compose を使用する場合は、ホスト ポートを指定しないでください。代わりに、Docker にランダムに利用可能なポートを選択させ、ポートの競合の問題を自動的に回避してください。
プロジェクトに新しいコンテナーを追加する
別のアプリまたはサービスを追加したい場合は、再度 Containers: Add Docker Compose Files to Workspace を実行し、既存の docker-compose ファイルを上書きすることを選択できますが、そのファイル内のカスタマイズはすべて失われます。Compose ファイルへの変更を保持したい場合は、docker-compose.yml
ファイルを手動で変更して新しいサービスを追加できます。通常、既存のサービス セクションをコピーして貼り付け、新しいエントリを作成し、新しいサービスに適した名前に変更できます。
新しいアプリの Dockerfile
を生成するには、Containers: Add Docker Files to Workspace コマンドを再度実行できます。各アプリまたはサービスは独自の Dockerfile を持っていますが、ワークスペースごとに通常、docker-compose.yml
ファイルと docker-compose.debug.yml
ファイルが 1 つずつ存在します。
Python プロジェクトでは、Dockerfile
、.dockerignore
、docker-compose*.yml
のすべてのファイルがワークスペースのルート フォルダーにあります。別のアプリまたはサービスを追加する場合は、Dockerfile をアプリのフォルダーに移動します。
Node.js プロジェクトでは、Dockerfile
と .dockerignore
ファイルは、そのサービスの package.json
の隣に配置されます。
.NET の場合、Docker Compose ファイルを作成する際に既に複数のプロジェクトを処理するためのフォルダー構造が設定されており、.dockerignore
および docker-compose*.yml
はワークスペースのルート (例: プロジェクトが src/project1
にある場合、ファイルは src
にある) に配置されます。そのため、別のサービスを追加する場合は、たとえば project2
というフォルダーに別のプロジェクトを作成し、前述のように docker-compose ファイルを再作成または変更します。
デバッグ
まず、VS Code でコンテナー内のデバッグの基本を理解するために、ターゲット プラットフォームのデバッグ ドキュメントを参照してください。
Docker Compose でデバッグしたい場合は、前のセクションで説明した 2 つの Docker Compose ファイルのいずれかを使用して、Containers: Compose Up コマンドを実行し、適切な Attach 起動構成を使用してアタッチします。通常の起動構成を直接使用して起動しても、Docker Compose は使用されません。
Attach 起動構成を作成します。これは launch.json
のセクションです。プロセスはほとんど手動ですが、場合によっては、Container Tools 拡張機能が、テンプレートとして使用しカスタマイズできる事前構成済みの起動構成を追加することで役立つことがあります。各プラットフォーム (Node.js、Python、.NET) のプロセスは、以下のセクションで説明されています。
Node.js
-
デバッグ タブで、構成 ドロップダウンを選択し、新しい構成 を選択し、
Containers: Attach
構成テンプレート Containers: Attach to Node を選択します。 -
docker-compose.debug.yml
でデバッグ ポートを構成します。これはファイル作成時に設定されるため、変更する必要がない場合があります。以下の例では、ホストとコンテナーの両方でデバッグにポート 9229 が使用されています。version: '3.4' services: node-hello: image: node-hello build: . environment: NODE_ENV: development ports: - 3000 - 9229:9229 command: node --inspect=0.0.0.0:9229 ./bin/www
-
複数のアプリがある場合は、各アプリに一意のポートが割り当てられるように、一部のアプリのポートを変更する必要があります。
launch.json
で適切なデバッグ ポートを指定し、ファイルを保存できます。これを省略すると、ポートは自動的に選択されます。以下は、Node.js の起動構成 - Attach を示す例です。
"configurations": [ { "type": "node", "request": "attach", "name": "Containers: Attach to Node", "remoteRoot": "/usr/src/app", "port": 9229 // Optional; otherwise inferred from the docker-compose.debug.yml. }, // ... ]
-
Attach 構成の編集が完了したら、
launch.json
を保存し、新しい起動構成をアクティブな構成として選択します。デバッグ タブの構成 ドロップダウンで、新しい構成を見つけてください。 -
docker-compose.debug.yml
ファイルを右クリックし、Compose Up を選択します。 -
HTML を返す HTTP エンドポイントを公開するサービスにアタッチしても、Web ブラウザーは自動的に開きません。ブラウザーでアプリを開くには、サイドバーでコンテナーを選択し、右クリックしてブラウザーで開くを選択します。複数のポートが構成されている場合は、ポートを選択するよう求められます。
-
通常の方法でデバッガーを起動します。デバッグ タブから、緑色の矢印 (開始 ボタン) を選択するか、F5 を使用します。
Python
Docker Compose を使用して Python をデバッグするには、次の手順に従います。
-
デバッグ タブで、構成 ドロップダウンを選択し、新しい構成 を選択し、Python Debugger を選択し、
Remote Attach
構成テンプレートを選択します。 -
デバッグに使用するホスト マシン (例: localhost) とポートを選択するように促されます。Python の既定のデバッグ ポートは 5678 です。複数のアプリがある場合は、各アプリに一意のポートが割り当てられるように、いずれかのポートを変更する必要があります。
launch.json
で適切なデバッグ ポートを指定し、ファイルを保存できます。これを省略すると、ポートは自動的に選択されます。"configurations": [ { "name": "Python Debugger: Remote Attach", "type": "debugpy", "request": "attach", "port": 5678, "host": "localhost", "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/app" } ] }
-
Attach 構成の編集が完了したら、
launch.json
を保存します。デバッグ タブに移動し、Python Debugger: Remote Attach をアクティブな構成として選択します。 -
有効な Dockerfile をすでに持っている場合は、Containers: Add Docker Compose Files to Workspace コマンドを実行することをお勧めします。これにより、
docker-compose.yml
ファイルと、コンテナー内で Python デバッガーをボリューム マップして起動するdocker-compose.debug.yml
も作成されます。Dockerfile がまだない場合は、Containers: Add Docker Files to Workspace を実行し、Docker Compose ファイルを含めるためにはいを選択することをお勧めします。注: 既定では、Containers: Add Docker Files to Workspace を使用する際、Django および Flask オプションを選択すると、Gunicorn 用に構成された Dockerfile が生成されます。続行する前に、正しく構成されていることを確認するために、コンテナー内の Python クイックスタート の指示に従ってください。
-
docker-compose.debug.yml
ファイル (以下の例を参照) を右クリックし、Compose Up を選択します。version: '3.4' services: pythonsamplevscodedjangotutorial: image: pythonsamplevscodedjangotutorial build: context: . dockerfile: ./Dockerfile command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 manage.py runserver 0.0.0.0:8000 --nothreading --noreload"] ports: - 8000:8000 - 5678:5678
-
コンテナーがビルドされて実行されたら、Python Debugger: Remote Attach 起動構成が選択された状態で F5 を押してデバッガーをアタッチします。
注: 特定のファイルに Python デバッガーをインポートしたい場合は、詳細を debugpy README で確認できます。
-
HTTP エンドポイントを公開し、HTML を返すサービスにアタッチしても、Web ブラウザーが自動的に開かない場合があります。ブラウザーでアプリを開くには、コンテナー エクスプローラーでコンテナーを右クリックし、ブラウザーで開くを選択します。複数のポートが構成されている場合は、ポートを選択するよう求められます。
これで、コンテナーで実行中のアプリをデバッグしています。
.NET
-
デバッグ タブで、構成 ドロップダウンを選択し、新しい構成 を選択し、
Container Attach
構成テンプレート Containers: .NET Attach (Preview) を選択します。 -
VS Code は、既定のパスを使用して
vsdbg
をホスト マシンからターゲット コンテナーにコピーしようとします。Attach 構成で、既存のvsdbg
インスタンスへのパスを指定することもできます。"netCore": { "debuggerPath": "/remote_debugger/vsdbg" }
-
Attach 構成の編集が完了したら、
launch.json
を保存し、新しい起動構成をアクティブな構成として選択します。デバッグ タブの構成 ドロップダウンで、新しい構成を見つけてください。 -
docker-compose.debug.yml
ファイルを右クリックし、Compose Up を選択します。 -
HTML を返す HTTP エンドポイントを公開するサービスにアタッチしても、Web ブラウザーは自動的に開きません。ブラウザーでアプリを開くには、サイドバーでコンテナーを選択し、右クリックしてブラウザーで開くを選択します。複数のポートが構成されている場合は、ポートを選択するよう求められます。
-
通常の方法でデバッガーを起動します。デバッグ タブから、緑色の矢印 (開始 ボタン) を選択するか、F5 を使用します。
-
コンテナーで実行中の .NET アプリにアタッチしようとすると、アプリのコンテナーを選択するよう求めるプロンプトが表示されます。
この手順をスキップするには、launch.json の Attach 構成でコンテナー名を指定します。
"containerName": "Your ContainerName"
次に、デバッガー (
vsdbg
) をコンテナーにコピーするかどうか尋ねられます。はいを選択してください。
すべてが正しく構成されていれば、デバッガーは .NET アプリにアタッチされているはずです。
ボリューム マウント
既定では、Container Tools 拡張機能はデバッグ コンポーネントのボリューム マウントを行いません。必要なコンポーネントはランタイムに組み込まれているため、.NET や Node.js では必要ありません。アプリにボリューム マウントが必要な場合は、docker-compose*.yml
ファイルの volumes
タグを使用して指定します。
volumes:
- /host-folder-path:/container-folder-path
複数の Compose ファイルを使用する Docker Compose
ワークスペースには、開発、テスト、運用など、さまざまな環境を処理するための複数の docker-compose ファイルを含めることができます。構成の内容は複数のファイルに分割できます。たとえば、すべての環境に共通する情報を定義するベースの Compose ファイルと、環境固有の情報を定義する個別のオーバーライド ファイルなどです。これらのファイルが docker-compose
コマンドへの入力として渡されると、これらのファイルが単一の構成に結合されます。既定では、Containers: Compose Up コマンドは単一のファイルを Compose コマンドへの入力として渡しますが、コマンドのカスタマイズを使用して複数のファイルを渡すように compose up
コマンドをカスタマイズできます。または、カスタム タスクを使用して、目的のパラメーターで docker-compose
コマンドを呼び出すこともできます。
注: ワークスペースに
docker-compose.yml
とdocker-compose.override.yml
があり、他の Compose ファイルがない場合、docker-compose
コマンドは入力ファイルなしで呼び出され、これらのファイルが暗黙的に使用されます。この場合、カスタマイズは不要です。
コマンドのカスタマイズ
コマンドのカスタマイズ は、要件に基づいて compose up
コマンドをカスタマイズするさまざまな方法を提供します。以下は、compose up
コマンドのコマンド カスタマイズのいくつかのサンプルです。
ベース ファイルとオーバーライド ファイル
ワークスペースにベースの Compose ファイル (docker-compose.yml
) と各環境のオーバーライド ファイル (docker-compose.dev.yml
、docker-compose.test.yml
、docker-compose.prod.yml
) があり、常にベース ファイルとオーバーライド ファイルで docker compose up
を実行すると仮定します。この場合、compose up
コマンドは以下の例のようにカスタマイズできます。compose up
コマンドが呼び出されると、${configurationFile}
は選択されたファイルに置き換えられます。
"docker.commands.composeUp": [
{
"label": "override",
"template": "docker-compose -f docker-compose.yml ${configurationFile} up -d --build",
}
]
テンプレート マッチング
各環境に異なる入力ファイル セットがあると仮定します。正規表現マッチングを持つ複数のテンプレートを定義でき、選択されたファイル名は、この match
プロパティと照合され、対応するテンプレートが使用されます。
"containers.commands.composeUp": [
{
"label": "dev-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.debug.yml -f docker-compose.dev.yml up -d --build",
"match": "dev"
},
{
"label": "test-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.debug.yml -f docker-compose.test.yml up -d --build",
"match": "test"
},
{
"label": "prod-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.release.yml -f docker-compose.prod.yml up -d --build",
"match": "prod"
}
]
コマンド呼び出し時にテンプレートを選択する
コマンド テンプレートから match
プロパティを省略すると、compose up
コマンドが呼び出されるたびに、どのテンプレートを使用するか尋ねられます。例えば、
"containers.commands.composeUp": [
{
"label": "dev",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.dev.yml ${configurationFile} up -d --build"
},
{
"label": "test",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.test.yml ${configurationFile} up -d --build"
},
{
"label": "prod",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.prod.yml ${configurationFile} up -d --build"
},
],
カスタム タスク
コマンドのカスタマイズを使用する代わりに、次のようなタスクを定義して docker-compose
コマンドを呼び出すこともできます。このオプションの詳細については、カスタム タスク を参照してください。
{
"type": "shell",
"label": "compose-up-dev",
"command": "docker-compose -f docker-compose.yml -f docker-compose.Common.yml -f docker-compose.dev.yml up -d --build",
"presentation": {
"reveal": "always",
"panel": "new"
}
}