【问题标题】:Port Publishing When Running with Docker Compose使用 Docker Compose 运行时的端口发布
【发布时间】:2016-07-19 03:01:25
【问题描述】:

我似乎无法找到一种方法来让端口发布与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


    【解决方案1】:

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

    请参阅docker-compose run 的文档

    【讨论】:

    • 哦。这不是我美好的时刻之一。我猜想在工作日结束时睡眼惺忪的时候发布 SO 问题一般来说不是一个好主意...抱歉浪费您的时间并感谢您的帮助。
    • @thaJezah。我还有一个足够相关的问题,因此不值得单独提出问题。在 Mac OS(运行 Docker 机器)上,使用 --service-portsdocker-compose 并不能解决从主机使用 curl 的问题——-p 选项是解决问题的唯一方法。这是我应该作为 GitHub 问题提交的错误还是我遗漏了其他内容?
    • --service-ports 应该按照 yaml 文件中定义的方式发布端口,但如果实际服务已经在运行,可能还没有完成?如果它不起作用,那么一定要在 GitHub 上打开一个问题(但一定要搜索现有的)。过去几周我没有密切关注 docker-compose 问题跟踪器,所以这可能是一个已知问题。
    • 奇怪的是如何在ports 选项here 旁边没有记录这一点
    • @Elle Mundy 它记录在 v3 文档的端口部分here
    【解决方案2】:

    编辑

    尝试使用--service-ports(它不适用于up 命令,我们应该以某种方式再次使用stoprun)它也不会改变这种行为,端口被暴露但不能@ 987654325@ 并且由于上述原因无法从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 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
    

    【讨论】:

    • 接受了 theJeztah 的回答,但这里仍然有一些很好的信息。奇怪的是,--service-ports 对我来说工作得很好。
    • 关于这个问题的任何更新?我现在遇到了这个问题。
    • 2) 似乎不再起作用:我收到此错误,忽略 IP 地址 (127.0.0.1:6379:6379/tcp) 服务将侦听“0.0.0.0”跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多