docker-compose.yml
のports
とexpose
オプションの違いは何ですか
ports を公開します。両方のポートを指定するか(Host:CONTAINER)、またはコンテナポートだけを指定します(ランダムなHostポートが選択されます)。
私のdocker-compose.yml
は次のようになります。
mysql:
image: mysql:5.7
ports:
- "3306"
docker-compose ps
を実行すると、次のようになります。
Name Command State Ports
-------------------------------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:32769->3306/tcp
ホストマシンに公開せずにポートを公開します - それらはリンクされたサービスにしかアクセスできないでしょう。指定できるのは内部ポートだけです。
ポートはホストマシンには公開されず、他のサービスにのみ公開されます。
mysql:
image: mysql:5.7
expose:
- "3306"
docker-compose ps
を実行すると、次のようになります。
Name Command State Ports
---------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp
ポート このセクションは、ホストサーバーとDockerコンテナーの間のマッピングを定義するために使用されます。
ports:
- 10005:80
これは、コンテナ内で実行されているアプリケーションがポート80で公開されていることを意味します。ただし、外部システム/エンティティはそれにアクセスできないため、ホストサーバーポートにマッピングする必要があります。
注:ホストエンティティポート10005を開き、外部エンティティがアプリケーションにアクセスできるようにファイアウォールルールを変更する必要があります。
彼らは使用することができます
http:// {ホストIP}:10005
このようなもの
_ expose _ これは、dockerコンテナ内でアプリケーションが実行されているポートを定義するためだけに使用されます。
Dockerfileでも定義できます。一般的に、dockerfileの中でEXPOSEを定義するのは良いことで広く使われている方法です。
ports
セクションは、ホスト上のポートを公開します。 Dockerは、ホストネットワークからコンテナーへの特定のポートの転送をセットアップします。デフォルトでは、これは最初のポートでリッスンし、2番目のポイントでリッスンする必要があるコンテナに転送するユーザー空間プロキシプロセス(docker-proxy
)で実装されます。コンテナが宛先ポートでリッスンしていない場合、ホストでリッスンしているものが表示されますが、そのホストポートに接続しようとすると、失敗した転送からコンテナへの接続が拒否されます。
このプロキシはコンテナのネットワーク名前空間内で実行されておらず、コンテナ内で127.0.0.1に到達できないため、コンテナはすべてのネットワークインターフェイスでリッスンしている必要があります。そのためのIPv4方法は、0.0.0.0
でリッスンするようにアプリケーションを構成することです。
また、公開されたポートは反対方向には機能しないことに注意してください。ポートを公開して、コンテナからホスト上のサービスに接続することはできません。代わりに、既に使用中のホストポートをリッスンしようとするdockerエラーが見つかります。
公開はドキュメントです。イメージにメタデータを設定し、実行時にコンテナにもメタデータを設定します。通常、これはEXPOSE
命令を使用してDockerfileで構成し、イメージを実行しているユーザーのドキュメントとして機能し、デフォルトでアプリケーションがリッスンするポートを知ることができます。構成ファイルを使用して構成されている場合、このメタデータはコンテナでのみ設定されます。イメージまたはコンテナでdocker inspect
を実行すると、公開されたポートを確認できます。
公開されたポートに依存するいくつかのツールがあります。 Dockerでは、-P
フラグは、公開されているすべてのポートをホスト上の一時ポートに公開します。コンテナポートを明示的に設定しない場合、アプリケーションにトラフィックを送信するときにデフォルトで公開ポートを使用するさまざまなリバースプロキシもあります。
これらの外部ツールを除き、公開はコンテナ間のネットワークにまったく影響しません。 1つのコンテナに別のコンテナからアクセスするには、共通のdockerネットワークが必要であり、コンテナポートに接続するだけです。そのネットワークがユーザーが作成したものである場合(たとえば、bridge
という名前のデフォルトのブリッジネットワークではない場合)、DNSを使用して他のコンテナーに接続できます。
私は前の答えに全く賛成です。私はちょうどexposeとportsの違いがdockerのセキュリティの概念の一部であることに言及したいです。これはdockerの networking と密接に関係しています。例えば:
Webフロントエンドとデータベースバックエンドを持つアプリケーションを想像してください。外部の世界はWebフロントエンド(おそらくポート80)にアクセスする必要がありますが、データベースのホストとポートにアクセスする必要があるのはバックエンド自体だけです。ユーザー定義ブリッジを使用する場合は、Webポートのみを開く必要があり、Webフロントエンドはユーザー定義ブリッジを介してアクセスできるため、データベースアプリケーションを開く必要はありません。
これは、dockerでネットワークアーキテクチャを設定するときの一般的なユースケースです。したがって、たとえばデフォルトのブリッジネットワークでは、外部の世界からポートにアクセスすることはできません。そのため、 "ports"でイングレスポイントを開くことができます。 「公開」を使用して、ネットワーク内の通信を定義します。デフォルトのポートを公開したい場合は、docker-composeファイルで "expose"を定義する必要はありません。