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

时间:2015-10-09 10:28:57

标签: docker docker-compose

我在docker容器中运行简单的Web应用程序(node.js)。应用程序侦听在主机上的8080上公开的本地端口5000。我想运行将在主机上运行的自动测试,并向我的应用程序发出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容器在启动时需要一些时间来初始化并准备接受与数据库的连接。那么理论上可以在postgres容器准备接受连接之前启动web容器吗?

2 个答案:

答案 0 :(得分:2)

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

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

healthcheck应该是对服务提出真实请求的东西。对于将成为SQL查询的postgres。因为你真正关心的是webapp的可用性。我会向命中数据库的端点发出HTTP请求。当请求成功使用200代码时,您就知道它已准备就绪。

答案 1 :(得分:1)

请注意,主机端口不是问题:如果您可以在容器中指定,复制和运行测试,那么“<script> function sendContact() { var valid; valid = validateContact(); if(valid) { jQuery.ajax({ url: "contact-post.php", data:'userName='+$("#userName").val()+'&userEmail='+$("#userEmail").val()+'&subject='+$("#subject").val()+'&contentsub='+$("#contentsub").val(), type: "POST", success:function(data){ $("#mail-status").html(data); }, error:function (){} }); } } function validateContact() { var valid = true; $(".textbox").css('background-color',''); $(".error").html(''); if(!$("#userEmail").val()) { $("#userEmail-info").html("(required)"); $("#userEmail").css('background-color','#D2434E'); valid = false; } if(!$("#contentsub").val()) { $("#content-info").html("(required)"); $("#contentsub").css('background-color','#D2434E'); valid = false; } return valid; } </script> <div class="contact-form" id="frmContact"> <h2>Contact Us</h2> <div id="mail-status"></div> <div class="left_form"> <div> <span><label>NAME</label></span> <span><input name="userName" id="userName" type="text" class="textbox"></span> </div> <div> <span><label>E-MAIL <span class='error' id="userEmail-info" style="color:#C40401;text-align:center;margin-bottom:5px;"></span><font color="#C40401">*</font></label></span> <span><input name="userEmail" id="userEmail" type="text" class="textbox"></span> </div> <div> <span><label>PHONE</label></span> <span><input name="subject" id="subject" type="text" class="textbox"></span> </div> </div> <div class="right_form"> <div> <span><label>SUBJECT <span class='error' id="content-info" style="color:#C40401;text-align:center;margin-bottom:5px;"></span><font color="#C40401">*</font></label></span> <span><textarea name="contentsub" id="contentsub"> </textarea></span> </div> <div id="submit"> <span><input type="submit" name="submit" value="Submit" class="myButton" onClick="sendContact();"></span> </div> </div> <div class="clearfix"></div> </div> ”容器“可以run with a --link directive mapping the myapp container

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

这样,您可以将容器设计为始终在端口5000上进行测试。

唯一存在的障碍是同步问题,在运行和链接“myapp”容器之前,您需要检测容器myapp是否已启动。 您可以在运行test之后运行test容器,但您的myapp脚本需要足够智能并等待test准备就绪。