web-dev-qa-db-ja.com

Docker-compose portsとexposeの違いは何ですか

docker-compose.ymlportsexposeオプションの違いは何ですか

251
bibstha

docker-composeの参照によれば

ポート は次のように定義されます。

ports を公開します。両方のポートを指定するか(Host:CONTAINER)、またはコンテナポートだけを指定します(ランダムなHostポートが選択されます)。

  • Docker-compose.ymlで言及されているportsはdocker-composeによって開始されたさまざまなサービスの間で共有されるでしょう。
  • ポートはホストマシンからランダムなポートまたは特定のポートに公開されます。

私の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
348
bibstha

ports

  1. コンテナをアクティブにして、dockerの外側の世界(同じホストマシンまたは別のマシンにすることができます)およびまたdockerの内側にあるアクセス可能なワールドから指定されたポートを待機します。
  2. 複数のポートを指定することができます(それが ports not portである理由です)

enter image description here

公開

  1. 港湾労働者の内側の世界と港湾労働者の外側のアクセスできない世界からのみ特定のポートをリッスンするようにコンテナをアクティブにします。
  2. 指定できるポートは1つだけです

enter image description here

26
Mehraj Malik

ポート このセクションは、ホストサーバーとDockerコンテナーの間のマッピングを定義するために使用されます。

ports:
   - 10005:80

これは、コンテナ内で実行されているアプリケーションがポート80で公開されていることを意味します。ただし、外部システム/エンティティはそれにアクセスできないため、ホストサーバーポートにマッピングする必要があります。

注:ホストエンティティポート10005を開き、外部エンティティがアプリケーションにアクセスできるようにファイアウォールルールを変更する必要があります。

彼らは使用することができます

http:// {ホストIP}:10005

このようなもの

_ expose _ これは、dockerコンテナ内でアプリケーションが実行されているポートを定義するためだけに使用されます。

Dockerfileでも定義できます。一般的に、dockerfileの中でEXPOSEを定義するのは良いことで広く使われている方法です。

8
sorabzone

ポート

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を使用して他のコンテナーに接続できます。

4
BMitch

私は前の答えに全く賛成です。私はちょうどexposeとportsの違いがdockerのセキュリティの概念の一部であることに言及したいです。これはdockerの networking と密接に関係しています。例えば:

Webフロントエンドとデータベースバックエンドを持つアプリケーションを想像してください。外部の世界はWebフロントエンド(おそらくポート80)にアクセスする必要がありますが、データベースのホストとポートにアクセスする必要があるのはバックエンド自体だけです。ユーザー定義ブリッジを使用する場合は、Webポートのみを開く必要があり、Webフロントエンドはユーザー定義ブリッジを介してアクセスできるため、データベースアプリケーションを開く必要はありません。

これは、dockerでネットワークアーキテクチャを設定するときの一般的なユースケースです。したがって、たとえばデフォルトのブリッジネットワークでは、外部の世界からポートにアクセスすることはできません。そのため、 "ports"でイングレスポイントを開くことができます。 「公開」を使用して、ネットワーク内の通信を定義します。デフォルトのポートを公開したい場合は、docker-composeファイルで "expose"を定義する必要はありません。

1
medTech