如何在本地 docker-compose 网络中连接两个服务?

时间:2020-12-19 00:25:22

标签: docker docker-compose

我已按照说明进行操作,我思考,并提出了以下配置:

 version: '3.9'
 services:
   flask:
    image: ops:imgA
      ports:
       - 5000:5000
      volumes:
       - /opt/models:/opt/models
      entrypoint: demo flask
    streamlit:
      image: ops:imgB
      ports:
        - 8501:8501
      entrypoint: streamlit run --server.port 8501 demo -- stream --flask-hostname flask

--flask-hostname flask 设置 http 连接中使用的主机名,即:http://flask:5000。我可以将其设置为任何内容。

这里的基本问题是我可以启动这些映像之一,安装 tmux,并在单个映像中运行所有内容。

但是,当我将其拆分为多个图像并使用 docker-compose up(似乎比 tmux 更好)时,容器似乎无法相互连接。

我对 docker 网站上的文档感到不安,但我已经进入故障排除阶段。这似乎是应该“正常工作”的东西(因为沿着这些路线几乎没有问题)。我可以完全控制我正在使用的盒子,并且可以打开或关闭任何需要的端口。

主要是,我想弄清楚如何在 100% 默认设置下允许这两个服务(flask 和 streamlit)相互通信。

必须有 1 或 2 个设置需要更改,仅此而已。

有什么想法吗?


更新

我可以从外部访问所有服务,所以我将打开服务之间的外部连接(使用外部 IP)作为“正常工作”的快速修复,但显然让组合在内部工作将是最好的选择。

我还确认了 docker-compose 和 docker 版本是最新的。

Update-2:从flask@127.0.0.1 更改为flask@0.0.0.0

烧瓶输出:

flask_1      |  * Serving Flask app "flask" (lazy loading)
flask_1      |  * Environment: production
flask_1      |    WARNING: This is a development server. Do not use it in a production deployment.
flask_1      |    Use a production WSGI server instead.
flask_1      |  * Debug mode: on
flask_1      | INFO:werkzeug: * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
flask_1      | 2020-12-19 02:22:16.449 INFO    werkzeug:  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
flask_1      | INFO:werkzeug: * Restarting with inotify reloader
flask_1      | 2020-12-19 02:22:16.465 INFO    werkzeug:  * Restarting with inotify reloader
flask_1      | WARNING:werkzeug: * Debugger is active!
flask_1      | 2020-12-19 02:22:22.003 WARNING werkzeug:  * Debugger is active!

流线型:

streamlit_1  |
streamlit_1  |   You can now view your Streamlit app in your browser.
streamlit_1  |
streamlit_1  |   Network URL: http://172.18.0.3:8501
streamlit_1  |   External URL: http://71.199.156.142:8501
streamlit_1  |
streamlit_1  | 2020-12-19 02:22:11.389 Generating new fontManager, this may take some time...

和精简的错误消息:

ConnectionError: 

 HTTPConnectionPool(host='flask', port=5000): 
    Max retries exceeded with url: /foo/bar 

(Caused by NewConnectionError(
  '<urllib3.connection.HTTPConnection object at 0x7fb860501d90>: 
     Failed to establish a new connection: 
       [Errno 111] Connection refused'
  )
)

Update-3:点击刷新修复了它。

1 个答案:

答案 0 :(得分:1)

服务器进程必须侦听特殊的“所有接口”地址 0.0.0.0。默认情况下,许多开发类型的服务器侦听“仅本地主机”127.0.0.1,但在 Docker 中,每个容器都有自己的私有概念 localhost。如果使用 tmuxdocker exec 在一个容器内运行多个进程,它们具有相同的 localhost 并且可以相互连接,但是如果客户端和服务器运行在不同的容器中,请求未到达服务器的 localhost 接口,如果服务器正在侦听“仅本地主机”,它将不会收到它。

您的设置在其他方面是正确的,只有您在问题中包含的 docker-compose.yml。其他一些常见问题:

  • 您必须连接到服务器进程在容器内侦听的端口。如果您使用 ports: 在外部重新映射它,则会被忽略,并且您将连接到 second ports: 号码。相应地,不需要 ports:。 (expose: 也不是必需的,根本不执行任何操作。)
  • 客户端可能需要等待服务器启动。如果客户端 depends_on: [flask] 主机名通常会解析(除非服务器立即死机)但如果启动需要一段时间,您仍然会收到“连接被拒绝”错误。请参阅Docker Compose wait for container X before starting Y
  • 两个容器都不能使用 network_mode: host。这会完全禁用 Docker 的网络功能。
  • 如果您手动声明 networks:,则两个容器都需要位于同一网络上。您不需要显式创建一个网络来使容器间通信正常工作:Compose 为您提供了一个 default 网络,如果没有其他声明,就会使用该网络。
  • 使用 Compose 服务名称作为主机名。您无需明确指定 container_name:links: