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

问题描述 投票:0回答:2

我似乎无法找到一种方法让端口发布与

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 port docker-compose
2个回答
53
投票

默认情况下,

docker-compose run
不发布服务的端口。您可以传递
--service-ports
选项来发布 docker-compose.yml 中定义的端口,或者使用
-P
选项来发布所有端口。

请参阅 docker-compose run

的文档

28
投票

编辑

尝试使用

--service-ports
(它不适用于
up
命令,我们应该以某种方式再次
stop
run
)它也不会改变这种行为,端口已公开,但不能
curl
由于上述原因无法访问
127.0.0.1


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

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

您可以使用

docker inspect <container_name>
获取容器网络状态。

还使用

netstat
它给出了 docker 的奇怪行为,它似乎只监听
tcp6
接口:

$ sudo netstat -lt|grep 2048

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

可能的解决方案:

1- 来自外部主机的卷曲!它有效:)

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:2048

进行卷曲

3 - 将网络驱动程序(network_mode)更改为bridge

** 此方法在较新的 docker 版本上不再适用 **

4- 从主机 IP 获取而不是 127.0.0.1


那么问题出在哪里?

看来根本问题来自于 docker 桥接方法。 docker 使用

iptables
nat INCOMING 连接到正确的容器端口

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

正如您所看到的,只有

dport
的传入连接到
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
© www.soinside.com 2019 - 2024. All rights reserved.