Docker应用程序部署

我的web应用程序由3个docker容器组成: app (带代码的主容器), redisnode 。 我有部署shell脚本,它执行以下操作:

  1. 从git克隆主( git clone <...> $REVISION
  2. 从文档根目录中删除所有文件( rm -rf $PROJECT_DIR
  3. 将所有克隆到文档根目录( mv $REVISION $PROJECT_DIR
  4. 停止所有正在运行的容器:( docker-compose stop
  5. 删除所有停止的容器( docker-compose rm -f
  6. 构build容器( docker-compose build
  7. 运行所有构build的容器( docker-compose up -d
  8. 运行所有init,并通过docker exec在容器内启动脚本(例如:config编译器,nginx重载)

这对我来说工作得很好,但是我对这个scheme有一些疑问:

  1. 步骤6中 ,如果我不将文件更改为节点容器,则会使用已经构build的映像 – 速度很快。 但是,如果我改变了一些东西,容器会重新生成 – 速度很慢,会增加未使用的图像
  2. 在最糟糕的情况下(当我修改节点代码时),部署时间可能持续约2-3分钟,最好的情况是约30秒。 但即使如此,这是一些用户的停机时间。

正如我所想,我需要build立新的容器的可用性(在旧的容器parralel继续工作),只有在成功的状态 – 更改应用程序使用的最新容器的标签 。 我怎样才能做到这一点?

将非常感谢您的意见。

我所做的是标记我的所有图像的版本,除了标签,然后“最新”。 所以我有一个图像与多个标签。 只用一个以上的标签。 当您通过版本进行标记时,它可以让您移动“最新”标签而不会出现任何问题:

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

现在,当你使用docker images你会看到同样的图像被列出两次,只是使用不同的标签( 包括 “latest”和“0.8.1”)。 所以当你去build立像你这样的提到:

 # 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 

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

现在有一个使用了Nginx反向代理的Docker容器已经有好几年了。 Jason Wilder 在这篇博文中详细介绍了这样做的过程。

我会给你一个这将为你做什么的概述。 jwilder/nginx-proxy镜像将作为您的容器的反向代理,默认情况下,循环法根据主机名将入站连接平衡到容器。 在构build并运行具有相同VIRTUAL_HOST环境variables的容器之后, nginx-proxy自动轮循负载平衡两个容器。 这样,你可以启动新的容器,它将开始服务请求。 那么你可以把你的另一个旧的容器放下。 零停机更新。

只是一些细节: nginx-proxy镜像使用Jason Wilder的docker-gen实用程序自动获取docker容器信息,然后将请求路由到每个。 这意味着你用一个新的环境variables( VIRTUAL_HOST )启动你的普通容器, nginx-proxy将自动开始将入站请求路由到容器。 这最好用于在多个容器中“共享”一个端口(例如tcp / 80)。 而且这个反向代理意味着它可以处理HTTPS以及HTTPauthentication,所以你不需要在你的web容器中处理它。 后端是未encryption的(HTTP),但由于它在同一主机上,没有问题。