使用Docker Compose运行时的端口发布

我似乎无法find一种方法让端口发布与docker-compose run ,就像使用docker run

使用Docker Compose(并因此在docker-compose.yml的端口映射)从curl给出“Failed to connect”错误:

 $ 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) 

泊坞窗,compose.yml

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

默认情况下, docker-compose run不会发布服务的端口。 您可以通过--service-ports选项来发布在--service-ports中定义的端口,也可以使用-p选项来发布所有端口。

请参阅docker-compose运行的文档

编辑

尝试与--service-ports (它不起作用的up命令,我们应该以某种方式stop和再次run )也不会改变这种行为,港口是暴露的,但不能curl ,无法达到127.0.0.1


这是因为你正在使用docker-compose 2语法。

默认情况下,它会在每个撰写项目容器之间创build一个内部networking (或在某些情况下覆盖networking )。

您可以使用docker inspect <container_name>来获取容器networking状态。

也使用netstat它给了一个奇怪的行为从docker,似乎只侦听tcp6接口:

 $ sudo netstat -lt|grep 2048 tcp6 0 0 [::]:2048 [::]:* LISTEN 501/docker 

可能的解决scheme :

1-从外部主机curl! 有用 :)

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

2-在ports指定本地主机IP( 127.0.0.1 )部分:

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

你可以简单地使用curl localhost:2048curl localhost:2048

3 – 更改networking驱动程序( network_mode )以桥接

**这种方法不适用于新的docker版本**

从主机的ipcurl,而不是127.0.0.1


那么问题是什么?

这似乎是从docker桥方法的根本问题。 docker使用iptablesINCOMING连接指向正确的容器端口

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

正如你所看到的,它只dportinput连接传送到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