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"
デフォルトでは、docker-compose run
はサービスのポートを公開しません。 --service-ports
オプションを渡してdocker-compose.ymlで定義されているポートを公開するか、-p
オプションを使用してすべてのポートを公開できます。
docker-compose run のドキュメントを参照してください
--service-ports
(up
コマンドでは機能せず、何らかの方法でstop
とrun
をもう一度試してみてください)また、この動作は変更されず、ポートが公開されます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
C:\Users\pooya>curl Host:2048
Hello World!
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
を使用して簡単にカールできます
**この方法は、新しいドッカーバージョンでは機能しません**
根本的な問題はdocker bridgeメソッドにあるようです。 dockerはiptables
を使用してnat INCOMING正しいコンテナのポートへの接続
$ Sudo iptables -L|grep 2048
ACCEPT tcp -- anywhere 10.0.0.12 tcp dpt:2048
ご覧のとおり、dport
sの10.0.0.12:2048
への着信接続のみ
奇妙な!しかし、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