如何确保容器中的Web应用程序成功绑定到一个端口?

我正在Docker容器中运行简单的Web应用程序(node.js)。 应用程序侦听在主机上的8080上公开的本地端口5000。 我想运行在主机上运行的自动testing,并将HTTP请求发送到我的应用程序。 问题是,当我开始与docker run应用程序时,我不知道什么时候应用程序已准备好(当它开始在主机上的8080端口上侦听)。 我可以使用简单的超时,这将足够长,以确保容器启动和应用程序开始倾听请求,但也许有一个更聪明的方式做到这一点?


我也使用docker-compose ,我想知道它是如何知道容器是“准备使用”? 考虑以下docker-compose.yml文件:

 web: image: myapp:latest ports: - 8080:5000 links: - postgres postgres: image: postgres 

我知道docker-compose以正确的顺序启动容器,所以在这个例子中,它将首先启动postgres,然后启动web容器。 然而,postgres容器在启动时需要一些时间来初始化并准备好接受到数据库的连接。 那么理论上web容器可以在postgres容器准备好接受连接之前启动了吗?

我认为这是一个普遍的问题。 我一直通过实施一个基本的健康检查和民意测验来解决这个问题。 健康检查将取决于服务,但它看起来像这样:

 start_time = time.time() while start_time + max_wait_time > time.time(): if healthcheck(): return 

healthcheck应该是对服务真正的请求。 对于将成为SQL查询的postgres。 因为你真正关心的是webapp的可用性。 我会做一个HTTP请求到达数据库的端点。 当请求成功的200代码,你知道它已经准备好了。

请注意,主机端口不是问题:如果您可以在容器中指定,复制和运行testing,则“ test ”容器可以使用映射myapp容器的--link指令运行 。

在这种情况下, test将在端口5000上联系myapp (即使myapp容器从未将5000映射到主机上的端口8080等):这是容器通信的容器:不需要主机映射)

这样,您可以devise您的容器始终在端口5000上进行testing。

唯一剩下的障碍是同步之一,在运行和链接“ test ”容器之前,需要检测容器myapp是否已启动。
你可以在运行myapp之后运行你的test容器,但是你的test脚本需要足够聪明,等待myapp准备就绪。