Docker应用程序部署

时间:2015-11-29 15:43:49

标签: deployment docker web-deployment dockerfile docker-compose

我的网络应用程序包含3个泊坞容器:app(包含代码的主容器),redisnode。我有部署shell脚本,它执行以下操作:

  1. 从git(git clone <...> $REVISION)克隆主人
  2. 从文档根目录(rm -rf $PROJECT_DIR
  3. 中删除所有文件
  4. 将克隆到文档根目录(mv $REVISION $PROJECT_DIR
  5. 的所有内容移动
  6. 停止所有正在运行的容器:(docker-compose stop
  7. 删除所有已停止的容器(docker-compose rm -f
  8. 构建容器(docker-compose build
  9. 运行所有构建的容器(docker-compose up -d
  10. 通过docker exec运行所有init并在容器内启动脚本(例如:config compilers,nginx reload)
  11. 这对我来说很好,但我对这个方案有几个疑问:

    1. 第6步中,如果我没有将文件更改为节点容器,它将使用已经构建的图像 - 它很快。但是,如果我改变某些东西,容器将再次构建 - 它很慢并且增加了未使用的图像
    2. 在最糟糕的情况下(当我对节点代码进行更改时)部署可能持续大约2-3分钟,在最好的情况下 - 大约30秒。但即便如此,对某些用户来说也是一段停机时间。
    3. 我认为,我需要构建新容器的可用性(在旧容器的parralel继续工作),并且只有在成功状态之后 - 更改最新容器的标记,这是使用的通过应用程序。我怎么能这样做?

      非常感谢你的评论。

1 个答案:

答案 0 :(得分:2)

除了标记然后“最新”之外,我所做的是按版本标记我的所有图像。所以我有一个带有多个标签的图像。只需使用多个标记即可。当您按版本标记时,它可以让您在没有问题的情况下移动“最新”标记:

docker build -t=myApp .
docker tag myApp:latest myApp:0.8.1

现在当你docker images时,你会看到两次列出相同的图片,只有不同的标签( “最新”和“0.8.1”)。所以当你去构建像你这样的东西时:

# the original container is still running while this builds ...
docker build -t=myApp .
# now tag "latest" to the newest version
docker tag myApp:latest myApp:0.8.2
# and now you can just stop and restart the container ...
docker rename myApp myApp-old
docker run -d --name=myApp -p 80:80 myApp:latest

这是你可以做的事情,但看起来你真的需要一种方法来交换容器而不会有任何停机时间。零停机时间容器更改。

我已经使用了几年为您的Docker容器使用Nginx反向代理的过程。 Jason Wilder详细介绍了in this blog post这样做的过程。

我将向您概述这将为您做些什么。 jwilder/nginx-proxy泊坞窗映像将充当容器的反向代理,默认情况下,循环负载平衡基于主机名的容器入站连接。在构建并运行具有相同VIRTUAL_HOST环境变量的容器后,nginx-proxy会自动循环对两个容器进行负载平衡。这样,您就可以启动新容器,并开始处理请求。然后你可以放下你的另一个旧容器。零停机更新。

一些细节:nginx-proxy图像使用Jason Wilder的docker-gen实用程序自动获取docker容器信息,然后将请求路由到每个。这意味着您使用新的环境变量(VIRTUAL_HOST)启动普通容器,nginx-proxy将自动开始将入站请求路由到容器。这最适合用于“共享”许多容器中的端口(例如tcp / 80)。此反向代理也意味着它可以处理HTTPS以及HTTP身份验证,因此您无需在Web容器中处理它。后端是未加密的(HTTP),但由于它位于同一主机上,没问题。