
実際のトラブルでは、Docker Engineの有無よりも、コンテナの起動状態、環境変数、ネットワーク、ボリューム、ホストとの依存関係が問題になる。Laravelの開発環境でも、PHPコンテナは起動しているが、データベース名が異なる。WordPressでは、コンテナは動作しているが、永続ボリュームが正しく接続されていない。この種の不具合は珍しくない。
Dockerは、アプリケーションと実行に必要な設定をコンテナとしてカプセル化する技術である。ホストOSのカーネルを共有するため、仮想マシンより起動が速く、リソース消費も少ない。ただし、Dockerを使えばインフラの知識が不要になるわけではない。ネットワーク、ファイルシステム、権限、プロセス管理の理解は残る。
仮想マシンとコンテナは、似ているようで構造が違う
Dockerを理解するには、まず仮想マシンとの違いを整理する必要がある。
仮想マシンは、ホストOS上でハイパーバイザーを動かし、その上にゲストOSを起動する。アプリケーションはゲストOSのカーネル、ライブラリ、プロセス管理機構を利用する。独立性は高い。一方で、ゲストOS全体を起動するため、起動時間とディスク使用量が大きくなる。
コンテナは、ホストOSのカーネルを共有する。コンテナごとにプロセス、ファイルシステム、ネットワークなどを分離するが、ゲストOS全体は持たない。この違いが、起動速度とリソース効率に直結する。
| 比較項目 | 仮想マシン | Dockerコンテナ |
|---|---|---|
| 仮想化の単位 | ゲストOSを含む仮想マシン | アプリケーションと依存関係 |
| カーネル | ゲストOSごとに持つ | ホストOSと共有する |
| 起動時間 | 数分かかる場合がある | 数秒で起動する |
| イメージサイズ | 数ギガバイトから数百ギガバイト | 数メガバイトから数百メガバイト |
| リソース消費 | 比較的大きい | 比較的小さい |
| 障害の影響範囲 | OS単位で分離しやすい | 共有カーネルの影響を受ける |
| 主な用途 | OSレベルの分離、従来型サーバー | 開発環境、アプリ実行、継続的デリバリー |
ここで注意すべき点は、コンテナが「小さな仮想マシン」ではないことである。コンテナは仮想マシンより軽量だが、完全に同じ分離モデルではない。
Dockerでは、コンテナ内のプロセスがホストOSのカーネル機能を利用する。したがって、特権モードの利用、ホストディレクトリのマウント、ソケットの共有などは、分離境界を弱める可能性がある。利便性だけを見て設定すると、運用上のリスクが増える。
Dockerの利点は、環境を完全に隠すことではない。依存関係を宣言し、同じ実行条件を再現しやすくすることである。
起動が速いことと、処理が速いことは別である
Dockerコンテナの起動が数秒で完了するからといって、アプリケーションの処理速度が常に向上するわけではない。
コンテナの起動時間は、主にイメージの展開、ファイルシステムの準備、ネットワーク設定、プロセスの起動に左右される。Laravelのリクエスト処理速度は、PHPの設定、フレームワークのキャッシュ、データベースへの接続、外部サービスへの通信などに左右される。
この二つを混同すると、Docker導入後に期待した性能が得られない。
インフラ構築で見るべき指標は、少なくとも分けて考える必要がある。
- 起動時間:コンテナを作成してプロセスが動き始めるまでの時間
- 応答時間:HTTPリクエストを受けてレスポンスを返すまでの時間
- スループット:一定時間内に処理できるリクエスト数
- メモリ使用量:コンテナと関連プロセスが消費するメモリ
- イメージサイズ:転送、保存、展開に必要な容量
- 復旧時間:障害発生後にサービスを再開するまでの時間
Dockerは、特に起動時間、環境再現性、デプロイ単位の明確化で効果を発揮する。逆に、アプリケーション内部の計算量やSQLのボトルネックを自動的に解消する技術ではない。
Docker環境の導入では、最初にバージョンと実行状態を分けて確認する
Docker環境を構築した直後に、いきなりアプリケーションを起動するのは効率が悪い。
最初に確認すべきなのは、Dockerのコマンドが存在するかではない。Docker EngineとComposeが実際に利用可能な状態かである。
Dockerのバージョンは、docker --version で確認できる。Composeのバージョンは、docker compose version で確認する。両方のコマンドがバージョン情報を返せば、少なくともクライアント側のコマンドは認識されている。
ただし、クライアントがインストールされていても、Docker Engineが停止している場合がある。この場合、コマンド自体は存在するが、コンテナの起動やイメージの取得で失敗する。
確認の順序は次のように分けるとよい。
1. docker --version でDockerのバージョンを確認する。
バージョン情報が返らない場合は、インストールまたは実行パスに問題がある。
2. docker compose version でComposeのバージョンを確認する。
Composeを使うプロジェクトでは、このコマンドが実行できる必要がある。
3. Docker Engineが起動している状態であるか確認する。
クライアントとEngineは別の役割を持つ。コマンドが存在しても、接続先のEngineが応答しなければコンテナは動かない。
4. docker ps で現在起動しているコンテナを確認する。
一覧が空でも異常とは限らない。重要なのは、期待するコンテナが表示されるかである。
5. docker compose ps でComposeプロジェクト単位の状態を確認する。
LaravelやWordPressのように複数コンテナを使う環境では、こちらのほうが依存関係を追いやすい。
docker ps は、起動中のコンテナだけを表示する。停止したコンテナも含めて確認する場合は、docker ps -a を使う。起動に失敗したコンテナは、すでに停止しているため、docker ps だけでは見落とす。
これは初歩的に見えるが、実際の切り分けでは重要である。起動していないコンテナと、起動しているが通信できないコンテナでは、調べるべき場所が異なる。
Composeはコンテナの依存関係を管理する
個人開発のLaravel環境では、PHP、ウェブサーバー、データベース、キャッシュサーバーを分ける構成が一般的である。WordPressでも、アプリケーション本体とデータベースを別コンテナにする。
この構成では、単一コンテナの状態だけを見ても全体像が分からない。
Composeは、複数のサービスをひとつのプロジェクトとして扱うための仕組みである。サービス名、ネットワーク、ボリューム、環境変数などを設定ファイルにまとめられる。開発者ごとに手順を変えずに済む点が大きい。
一方で、Composeファイルに依存関係を詰め込みすぎると、設定の変更が別のサービスへ波及する。たとえば、データベースのサービス名を変更すると、Laravel側の接続先設定も変える必要がある。コンテナ名、サービス名、ホスト名、環境変数の関係を曖昧にしてはいけない。
Compose環境では、次の項目を分離して管理するのが安定する。
- イメージを作るための設定
- サービスを起動するための設定
- 開発者ごとに異なる環境変数
- データを永続化するボリューム
- サービス間通信に使うネットワーク
- 本番環境だけで必要になる秘密情報
特に環境変数は、コンテナ内に注入された値と、ホスト側の設定ファイルに書かれた値が一致するとは限らない。実行時の状態を確認するには、設定ファイルを読むだけでは不十分である。
docker inspect で、実行中コンテナの実際の設定を見る
コンテナの設定を調査する場合、最初に使うべきコマンドは docker inspect <コンテナ名またはID> である。
docker inspect は、コンテナに注入された環境変数、ネットワーク設定、バインドマウント、ボリューム、起動コマンドなどを含む詳細な情報を返す。ComposeファイルやDockerfileを読むだけでは分からない、実行後の状態を確認できる。
インフラの障害では、「設定ファイルには正しく書かれている」という説明が役に立たない場合がある。必要なのは、現在のコンテナに何が設定されているかである。
たとえば、Laravelがデータベースに接続できない場合、次のような差分が考えられる。
- データベースのホスト名が、Composeのサービス名と一致していない
- データベース名が異なる
- ユーザー名またはパスワードが異なる
- コンテナ内には古い環境変数が残っている
- データベースコンテナが起動していない
- 同じネットワークに接続されていない
- ポート番号を、コンテナ間通信とホストからの接続で混同している
このうち、環境変数やネットワーク設定は docker inspect で確認できる。
ホスト側のポートと、コンテナ間のポートは役割が違う
Dockerで頻繁に発生する誤解が、ポート番号の扱いである。
ホストからコンテナへアクセスする場合、ポート公開の設定が関係する。ブラウザからLaravelやWordPressへアクセスする場合は、ホスト側のポート番号を使う。
一方、コンテナから別のコンテナへ接続する場合、通常は同一ネットワーク内のサービス名とコンテナ側の待受ポートを使う。ホスト側に公開したポート番号を、そのままコンテナ間通信に使うとは限らない。
たとえば、ウェブアプリケーションのコンテナがデータベースへ接続する場合、接続先は「ホストの特定ポート」ではなく、Compose上で定義されたデータベースサービス名になる構成が多い。
この違いを確認せずに、接続先だけを変更し続けると、設定の試行錯誤が増える。調査対象を次の三つに分けるべきである。
| 接続元 | 接続先 | 主に確認する項目 |
|---|---|---|
| ホストOS | ウェブコンテナ | 公開ポート、待受アドレス、ファイアウォール |
| アプリケーションコンテナ | データベースコンテナ | サービス名、内部ポート、同一ネットワーク |
| コンテナ | 外部サービス | DNS、経路、認証情報、外部側の許可設定 |
docker inspect の結果では、ネットワーク名、IPアドレス、接続されたネットワーク、ポート設定などを確認できる。ただし、コンテナのIPアドレスをアプリケーション設定に直接書く方法は、通常は安定しない。コンテナの再作成で変わる可能性があるためである。
依存関係は、固定IPではなくサービス名で表現するほうが保守しやすい。
環境変数は「存在」と「値」を別々に見る
環境変数の調査でも、単純に値が存在するかだけを見てはいけない。
Laravelでは、アプリケーションキー、データベース接続情報、キャッシュの接続先などが実行環境に影響する。WordPressでは、データベースのホスト、ユーザー、パスワード、データベース名が初期設定に使われる。
ここで問題になるのが、設定値の反映タイミングである。Composeファイルや環境変数ファイルを変更しても、既存のコンテナへ期待どおり反映されない場合がある。コンテナを再作成せず、プロセスだけを再起動している場合は特に注意が必要である。
調査では、次の順序が効率的である。
1. 設定ファイル上の値を確認する。
2. 実行中コンテナの環境変数を docker inspect で確認する。
3. アプリケーションが読み込んだ設定キャッシュを確認する。
4. データベースや外部サービス側の実際の認証情報と照合する。
5. 値を変更した場合は、コンテナの再作成が必要か判断する。
環境変数に秘密情報を含める場合は、docker inspect の結果をそのまま共有しないほうがよい。ログ、チケット、チャットへ貼り付ける際に、パスワードやトークンが露出する可能性がある。
実行環境がコンテナ内か確認する /.dockerenv
現在動作しているプロセスがDockerコンテナ内にあるかを確認する簡便な方法として、ルート直下の /.dockerenv を確認する手法がある。
このファイルが存在する場合、Dockerコンテナ内で実行されている可能性が高い。シェルやアプリケーションの診断処理から、実行環境を推測する材料になる。
ただし、/.dockerenv の存在だけで、あらゆるコンテナ実装や実行環境を断定するのは適切ではない。これはDocker環境で使われる簡便な判定方法であり、仮想マシン、別のコンテナランタイム、特殊な実行環境まで含めた標準的な判定仕様ではない。
本番アプリケーションの重要な分岐条件を、単一のファイルの有無だけに依存させる設計は避けるべきである。
判定処理をアプリケーションに入れる場合の注意
開発環境と本番環境で処理を分けたい場合、まず環境変数やデプロイ設定を利用できないか検討する。
たとえば、ログ出力の詳細度、デバッグモード、外部サービスの接続先などは、明示的な環境変数で管理するほうが意図を読み取りやすい。/.dockerenv の存在を見て本番・開発を判定すると、Docker上の本番環境とDocker上の開発環境を区別できない。
判定方法には、それぞれ役割がある。
- Dockerコンテナ内か確認する:
/.dockerenvの存在を確認する - 開発環境か確認する:アプリケーション用の環境変数を確認する
- 本番環境か確認する:デプロイ時に明示された実行環境を確認する
- サービスの種類を確認する:Composeのサービス名や起動設定を確認する
- 実行基盤を確認する:コンテナランタイムやオーケストレーション環境の情報を確認する
この切り分けをしておくと、「コンテナ内であること」と「本番であること」を混同しなくて済む。
Dockerfileとイメージの設計が、環境差を左右する
Dockerインフラの再現性は、コンテナを起動する設定だけで決まらない。イメージの作り方も関係する。
Dockerfileにインストール手順を直接記述すると、同じイメージを再構築しやすくなる。Laravelであれば、PHPの拡張、依存パッケージ、実行ユーザー、作業ディレクトリなどが対象になる。WordPressであれば、ウェブサーバー、PHP、データベース接続、永続化対象の整理が必要になる。
ここで、開発用の設定と本番用の設定を一つのイメージに詰め込むと、不要な依存関係が増える。イメージサイズが増え、脆弱性の調査対象も広がる。
マルチステージビルドは、この問題を抑える手段の一つである。ビルドに必要なツールと、実行時に必要なファイルを分離できる。たとえば、依存パッケージの生成に必要な環境と、アプリケーションを実行する環境を分ける構成である。
ただし、マルチステージビルドを採用すれば必ず改善するわけではない。ビルド成果物の受け渡しが不明確になると、実行時に必要なファイルが欠落する。キャッシュの利用によって、変更がイメージへ反映されていないように見えることもある。
確認すべき点は、イメージが小さいかどうかだけではない。
- 実行時に不要なビルドツールを含んでいないか
- 必要なPHP拡張やシステムライブラリが含まれているか
- 実行ユーザーが過剰な権限を持っていないか
- 設定ファイルと秘密情報がイメージへ埋め込まれていないか
- キャッシュによる古い依存関係が残っていないか
- ログをコンテナの標準出力へ出せるか
- コンテナを再作成してもデータが失われないか
イメージサイズは、転送時間や保存容量に影響する。しかし、サイズだけを追求してデバッグ用の情報や運用上必要な機能を削ると、障害調査のコストが増える。最適化の対象は、容量ではなく依存関係である。
小さいイメージが目的ではない。実行に不要な依存関係を持たないイメージが目的である。
ボリュームは、コンテナの再作成とデータ消失を分離する
コンテナは、停止や削除を前提に扱う。コンテナの中へ直接保存したデータは、コンテナの再作成で失われる可能性がある。
データベースのデータ、WordPressのアップロードファイル、Laravelで生成したユーザー関連ファイルなどは、コンテナのライフサイクルから分離する必要がある。Dockerでは、ボリュームやバインドマウントを利用して、ホスト側またはDocker管理領域へデータを保持する。
ここでも、開発環境と本番環境で要件が異なる。
開発環境では、ソースコードをホストからバインドマウントすると編集結果をすぐに反映できる。エディタやデバッグツールとの相性もよい。一方で、ホストとコンテナのファイルシステム差、権限差、ファイル監視の挙動がボトルネックになる場合がある。
本番環境では、ソースコードをイメージへ含めてデプロイする構成のほうが、実行状態を固定しやすい。ホスト側のファイルを自由に変更できる構成は、再現性を下げる。
| 保存方法 | 開発環境での扱いやすさ | 本番環境での再現性 | 主な注意点 |
|---|---|---|---|
| コンテナ内部 | 高い | 低い | 再作成でデータを失う可能性 |
| バインドマウント | 高い | 構成次第 | 権限とホスト依存が発生 |
| Dockerボリューム | 高い | 比較的高い | バックアップ方法が必要 |
| 外部ストレージ | 構築が必要 | 高い | 通信障害と費用を考慮 |
データベースをコンテナで動かす場合、コンテナを削除してもデータボリュームが残る構成にする必要がある。ただし、ボリュームが残ることと、バックアップがあることは別である。
ボリュームは障害からデータを守る仕組みではない。同一ホストのディスク障害、誤削除、ファイル破損には対応できない。バックアップと復元手順は、Dockerの外側も含めて設計する必要がある。
コンテナ運用では、ログと終了状態を最初に見る
アプリケーションへアクセスできない場合、ブラウザのエラー画面だけを見ても原因は分からない。
最初に見るべき情報は、コンテナの終了状態とログである。Compose環境であれば、サービス単位でログを確認する。コンテナが停止しているなら、停止理由と終了コードを調べる。起動しているなら、ウェブサーバー、PHP、データベースのどこで処理が止まっているかを分ける。
ログ調査では、次のような状態を区別する。
- プロセスが起動直後に終了している
- 設定ファイルの読み込みで失敗している
- ポートがすでに使用されている
- データベースへの接続待ちになっている
- 権限不足でファイルを読み書きできない
- DNSまたはネットワークの名前解決に失敗している
- アプリケーションは動いているが、ウェブサーバーから到達できない
「コンテナが起動している」という事実だけでは不十分である。コンテナ内のメインプロセスが生きていても、アプリケーションが正常にリクエストを処理できるとは限らない。
Dockerコンテナは、通常、メインプロセスの状態がコンテナの状態になる。プロセス管理を複雑にし、複数のサービスを一つのコンテナへ詰め込むと、終了状態の意味が曖昧になる。
個人開発では、ウェブサーバー、アプリケーション、データベースをサービス単位で分ける構成が、調査しやすさの点で有利である。障害の境界が明確になるためである。
セキュリティは、特権とマウントを確認しないと判断できない
Dockerの導入でセキュリティが自動的に改善するわけではない。
コンテナはホストOSのカーネルを共有する。特権モードの利用、ホストの重要なディレクトリのマウント、Dockerソケットの共有などは、設計意図を明確にする必要がある。
特に、ホスト側のDockerソケットをコンテナへ渡す構成は強い権限を持ちやすい。継続的インテグレーションやデプロイ自動化で利用されることがあるが、利便性だけで導入してはいけない。
セキュリティ上の確認対象は、次のように整理できる。
- コンテナが特権モードで起動していないか
- 実行ユーザーが不要な管理者権限を持っていないか
- ホストのディレクトリを過剰にマウントしていないか
- Dockerソケットを無制限に共有していないか
- 秘密情報をイメージへ書き込んでいないか
- 不要なポートをホストへ公開していないか
- 使用しているベースイメージと依存パッケージを更新できる状態か
- ログや監視によって異常を検知できるか
公開ポートを増やすと、接続経路も増える。開発環境で便利な管理用ポートを、そのまま本番環境へ残すのは避けるべきである。
また、環境変数に秘密情報を設定している場合も、ログや診断出力から漏れる可能性がある。docker inspect は便利だが、出力には環境変数が含まれる。調査結果を保存する場所まで含めて管理する必要がある。
開発環境と本番環境は、同じイメージでも同じ構成ではない
Dockerの代表的な利点は、開発環境から本番環境まで同じイメージを利用しやすいことである。環境差による不具合を減らせる。
ただし、「同じイメージ」と「同じ設定」は異なる。
開発環境では、ソースコードの編集、デバッグ、詳細ログ、データベースの初期化などが必要になる。本番環境では、最小限の権限、安定した設定、監視、バックアップ、障害復旧が優先される。
同じイメージを使いながら、Composeの上書き設定や環境変数で実行条件を変える構成は合理的である。一方で、開発用の設定を本番へ混ぜない管理が必要になる。
| 項目 | 開発環境 | 本番環境 |
|---|---|---|
| ソースコード | バインドマウントが便利 | イメージへ含めて固定しやすい |
| ログ | 詳細な出力 | 監視しやすい形式と保存先 |
| デバッグ | 有効化する場合がある | 原則として無効化 |
| データ | 初期化しやすさを重視 | 永続化とバックアップを重視 |
| 権限 | 作業効率とのバランス | 最小権限を優先 |
| 設定変更 | すぐ反映できる構成 | デプロイ単位で管理 |
| 障害対応 | 再作成で復旧 | 原因調査と復旧手順を分離 |
Laravelの開発環境では、依存パッケージのインストールやキャッシュクリアを頻繁に行う。WordPressでは、プラグインやアップロードファイルの扱いが問題になる。これらを本番運用の設計へそのまま持ち込むと、再現性と安全性の両方が下がる。
Dockerインフラ構築の確認手順を一つに固定する
トラブルが発生するたびに、思いついたコマンドを実行する方法は効率が悪い。確認対象を固定し、外側から内側へ進めるほうがよい。
1. Docker自体が利用可能か確認する
docker --version と docker compose version を実行する。ここで失敗する場合、アプリケーション設定を調査しても意味がない。
Dockerクライアント、Compose、Docker Engineを別の構成要素として扱う。バージョン表示の成功は、すべての動作を保証しない。
2. コンテナの存在と状態を確認する
docker ps で起動中のコンテナを確認する。表示されない場合は、docker ps -a で停止済みのコンテナを含めて確認する。
Composeプロジェクトなら、docker compose ps でサービス単位の状態を確認する。ウェブ、アプリケーション、データベースのどこが停止しているかを分ける。
3. ログで終了理由を確認する
停止したコンテナは、ログと終了状態を確認する。起動直後に終了している場合、設定ファイル、権限、依存ライブラリ、ポート競合が候補になる。
ログが何も出ない場合は、ログが標準出力へ流れているか、メインプロセスが正しく設定されているかを確認する。
4. 実行時設定を確認する
docker inspect <コンテナ名またはID> で、環境変数、ネットワーク、マウント、ポート、起動コマンドを確認する。
設定ファイルの記述と実行中コンテナの状態を比較する。ここで差分があれば、再作成やキャッシュの扱いを確認する。
5. コンテナ内外の通信経路を分ける
ホストからウェブコンテナへ接続できないのか、アプリケーションコンテナからデータベースへ接続できないのかを分ける。
同じ「接続できない」でも、ポート公開、サービス名、ネットワーク、認証情報のどれを調べるかは異なる。
6. データの保存先を確認する
コンテナの再作成でデータが消える構成になっていないか確認する。データベースやアップロードファイルを扱う場合、ボリュームの接続先とバックアップ手順を確認する。
7. コンテナ内であることが必要なら /.dockerenv を確認する
実行環境の簡易判定として、/.dockerenv の存在を確認する。ただし、本番・開発の判定には専用の環境変数やデプロイ設定を使う。
この順序には意味がある。Docker Engineが停止している状態でネットワークを調査しても、正確な結論は出ない。コンテナが存在しない状態で環境変数を確認しても、対象がない。外側の障害を解消してから、内側の依存関係へ進むべきである。
Dockerを採用する基準は、起動速度だけではない
Dockerは、個人開発の環境構築を単純化する。しかし、設定ファイルが増え、ネットワークとボリュームの抽象化が入るため、仕組みを理解せずに使うと別の複雑さが発生する。
採用の効果が大きいのは、次のような状況である。
- Laravel、WordPress、データベースなど複数の実行環境を分離したい
- 開発者ごとのPHPや拡張機能の差を減らしたい
- 本番環境へ近い構成をローカルで再現したい
- CI/CDパイプラインで同じ実行環境を使いたい
- サービス単位で起動、停止、更新、監視を管理したい
- サーバー移行時の依存関係を明確にしたい
反対に、単一の小規模スクリプトを一台のホストで動かすだけなら、Dockerの導入が必ずしも最短経路になるとは限らない。Dockerfile、Compose、ボリューム、ログ、ネットワークを管理するコストが発生するためである。
Dockerは目的ではない。環境差を減らし、依存関係を管理し、デプロイ単位を明確にするための手段である。
まとめ
Docker・インフラ構築を確認するとき、最初に見るべきなのは「Dockerが入っているか」だけではない。クライアント、Engine、Compose、コンテナ、ネットワーク、環境変数、ボリュームを順番に分けて調査する必要がある。
要点は次のとおりである。
- DockerはゲストOSを持たないコンテナ型仮想化であり、VMより起動が速く、リソース消費が少ない
docker --versionとdocker compose versionで基本的な導入状態を確認できるdocker psとdocker compose psで、起動中サービスと停止済みコンテナを分けて見るdocker inspectで、環境変数、ネットワーク、ポート、マウントなど実行時設定を確認できる/.dockerenvは、プロセスがDockerコンテナ内にあるかを推測する簡便な手段である- コンテナ間通信では、ホスト公開ポートと内部ポートを混同しない
- データベースやアップロードファイルは、コンテナのライフサイクルから分離する
- Docker導入後も、権限、共有カーネル、秘密情報、ログ、バックアップの設計は必要である
- イメージの最適化では、サイズより不要な依存関係の削減を優先する
Dockerの改善効果は、起動時間の短縮だけでは測れない。環境差の削減、再構築の再現性、障害箇所の分離、デプロイ手順の固定化が主な成果である。
一方で、Dockerはネットワークやファイルシステムを消す技術ではない。むしろ、設定として明示し、管理対象にする技術である。そこを理解すれば、LaravelやWordPressのローカル環境だけでなく、CI/CDやクラウド上のコンテナ運用まで、同じ考え方で設計できる。
Related reading: Docker導入の分岐点:個人開発でコンテナ化が必要になる基準 and Docker Composeの内部ネットワークでコンテナ間通信ができる仕組み.