web-dev-qa-db-ja.com

Docker Composeで実行する場合のポート公開

docker-compose runでできるのと同じように、docker runでポートパブリッシングを動作させる方法を考え出すことはできません。

Docker Compose(およびdocker-compose.ymlのポートマッピング)を使用すると、curlから「接続に失敗しました」というエラーが発生します。

$ docker-compose run flask
 * Running on http://0.0.0.0:2048/ (Press CTRL+C to quit)

$ curl http://localhost:2048/
curl: (7) Failed connect to localhost:2048; Connection refused

ただし、ポートを手動でdocker runに渡す場合は問題ありません。

$ docker run -p 2048:2048 --name flask -t flask_image
 * Running on http://0.0.0.0:2048/ (Press CTRL+C to quit)

$ curl http://localhost:2048
Hello World!

私は何が欠けていますか?


Dockerfile

FROM centos:7

# Install EPEL repo.
RUN rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm

# Install Python and Pip.
RUN yum -y update && yum -y install \
    python \
    python-pip

# Flask is necessary to run the app.
RUN pip install flask

EXPOSE 2048

ADD hello_world_flask_app.py /src/hello_world_flask_app.py
CMD ["python", "/src/hello_world_flask_app.py"]

hello_world_flask_app.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(Host='0.0.0.0', port=2048)

docker-compose.yml

version: '2'
services:
  flask:
    build: .
    ports:
      - "2048:2048"
23
JimmidyJoo

デフォルトでは、docker-compose runはサービスのポートを公開しません。 --service-portsオプションを渡してdocker-compose.ymlで定義されているポートを公開するか、-pオプションを使用してすべてのポートを公開できます。

docker-compose run のドキュメントを参照してください

23
thaJeztah

編集

--service-portsupコマンドでは機能せず、何らかの方法でstoprunをもう一度試してみてください)また、この動作は変更されず、ポートが公開されますcurlできず、127.0.0.1からの言及された理由で到達できない


これは、docker-compose 2構文を使用しているためです。

デフォルトでは、各構成プロジェクトコンテナ間に内部ネットワーク(または場合によってはオーバーレイネットワーク)を作成します。

docker inspect <container_name>を使用して、コンテナネットワークのステータスを取得できます。

また、netstatを使用すると、tcp6インターフェイスでのみリッスンするように見えるdockerからの奇妙な動作が発生します。

$ Sudo netstat -lt|grep 2048

  tcp6       0      0 [::]:2048           [::]:*         LISTEN      501/docker

可能な解決策 :

1-外部ホストからカール!できます :)

C:\Users\pooya>curl Host:2048
Hello World!

2- portsセクションでLocalhost IP(127.0.0.1)を指定します。

$ cat docker-compose.yml
version: '2'
services:
  flask:
      build: .
      ports:
        - "127.0.0.1:2048:2048"

curl localhost:2048を使用して簡単にカールできます

3-ネットワークドライバー(network_mode)をbridgeに変更

**この方法は、新しいドッカーバージョンでは機能しません**

4- 127.0.0.1の代わりにホストのIPからカール


それで問題は何でしたか?

根本的な問題はdocker bridgeメソッドにあるようです。 dockerはiptablesを使用してnat INCOMING正しいコンテナのポートへの接続

$ Sudo iptables -L|grep 2048
ACCEPT     tcp  --  anywhere             10.0.0.12            tcp dpt:2048

ご覧のとおり、dportsの10.0.0.12:2048への着信接続のみ


待って、docker-composeを使用しないのはどうですか?

奇妙な!しかし、0.0.0.0を正しくリッスンするには、すべてがうまくいきます:)

$ docker run -it -d  -p 2048:2048 test
$ netstat -ltn|grep 2048
tcp        0      0 0.0.0.0:2048   0.0.0.0:*               LISTEN
10
Pooya