如何保证容器中的web app成功绑定到某个端口?
How to ensure that web app in a container successfully bound to a port?
我正在 运行 在 docker 容器中安装简单的 Web 应用程序 (node.js)。应用程序侦听本地端口 5000,该端口在主机上的 8080 上公开。我想 运行 自动测试,它将 运行 在主机上进行,并将向我的应用程序发出 HTTP 请求。问题是,当我使用 docker run
启动应用程序时,我不知道应用程序何时准备就绪(何时开始侦听主机上的 8080 端口)。我可以使用足够长的简单超时来确保容器启动并且应用程序开始侦听请求,但也许有更聪明的方法来做到这一点?
我也在使用 docker-compose
,我想知道它是如何知道容器是 "ready to use" 的?考虑以下 docker-compose.yml 文件:
web:
image: myapp:latest
ports:
- 8080:5000
links:
- postgres
postgres:
image: postgres
我知道 docker-compose 以正确的顺序启动容器,所以在这个例子中它将首先启动 postgres,然后是 web 容器。但是 postgres 容器在启动时需要一些时间来初始化并准备好接受与数据库的连接。所以理论上 web 容器可以在 postgres 容器准备好接受连接之前启动,对吗?
请注意,主机端口不是问题:如果您可以在容器中指定、复制和 运行 测试,则“test
”容器可以 run with a --link
directive mapping the myapp
container。
在这种情况下,test
将联系端口 5000 上的 myapp
(总是,即使 myapp
容器从未将 5000 映射到主机上的 8080 端口:这是容器到容器通信:不需要主机映射)
这样,您可以将容器设计为始终 在端口 5000 上进行测试。
唯一剩下的障碍是同步,您需要检测容器 myapp
是否已启动,然后 运行 连接并链接您的“test
”容器。
您可以 运行 您的 test
容器紧接 运行 宁 myapp
容器,但您的 test
脚本需要足够智能并等待 myapp
准备好。
我认为这是一个普遍的问题。我总是通过实施基本的健康检查和轮询来解决它。健康检查将取决于服务,但它看起来像这样:
start_time = time.time()
while start_time + max_wait_time > time.time():
if healthcheck():
return
healthcheck 应该是对服务发出真实请求的东西。对于 postgres,这将是一个 SQL 查询。因为您真正关心的是 webapp 的可用性。我会向命中数据库的端点发出 HTTP 请求。当请求成功并返回 200 代码时,您就知道它已准备就绪。
我正在 运行 在 docker 容器中安装简单的 Web 应用程序 (node.js)。应用程序侦听本地端口 5000,该端口在主机上的 8080 上公开。我想 运行 自动测试,它将 运行 在主机上进行,并将向我的应用程序发出 HTTP 请求。问题是,当我使用 docker run
启动应用程序时,我不知道应用程序何时准备就绪(何时开始侦听主机上的 8080 端口)。我可以使用足够长的简单超时来确保容器启动并且应用程序开始侦听请求,但也许有更聪明的方法来做到这一点?
我也在使用 docker-compose
,我想知道它是如何知道容器是 "ready to use" 的?考虑以下 docker-compose.yml 文件:
web:
image: myapp:latest
ports:
- 8080:5000
links:
- postgres
postgres:
image: postgres
我知道 docker-compose 以正确的顺序启动容器,所以在这个例子中它将首先启动 postgres,然后是 web 容器。但是 postgres 容器在启动时需要一些时间来初始化并准备好接受与数据库的连接。所以理论上 web 容器可以在 postgres 容器准备好接受连接之前启动,对吗?
请注意,主机端口不是问题:如果您可以在容器中指定、复制和 运行 测试,则“test
”容器可以 run with a --link
directive mapping the myapp
container。
在这种情况下,test
将联系端口 5000 上的 myapp
(总是,即使 myapp
容器从未将 5000 映射到主机上的 8080 端口:这是容器到容器通信:不需要主机映射)
这样,您可以将容器设计为始终 在端口 5000 上进行测试。
唯一剩下的障碍是同步,您需要检测容器 myapp
是否已启动,然后 运行 连接并链接您的“test
”容器。
您可以 运行 您的 test
容器紧接 运行 宁 myapp
容器,但您的 test
脚本需要足够智能并等待 myapp
准备好。
我认为这是一个普遍的问题。我总是通过实施基本的健康检查和轮询来解决它。健康检查将取决于服务,但它看起来像这样:
start_time = time.time()
while start_time + max_wait_time > time.time():
if healthcheck():
return
healthcheck 应该是对服务发出真实请求的东西。对于 postgres,这将是一个 SQL 查询。因为您真正关心的是 webapp 的可用性。我会向命中数据库的端点发出 HTTP 请求。当请求成功并返回 200 代码时,您就知道它已准备就绪。