Docker应用程序部署
我的web应用程序由3个docker容器组成: app
(带代码的主容器), redis
和node
。 我有部署shell脚本,它执行以下操作:
- 从git克隆主(
git clone <...> $REVISION
) - 从文档根目录中删除所有文件(
rm -rf $PROJECT_DIR
) - 将所有克隆到文档根目录(
mv $REVISION $PROJECT_DIR
) - 停止所有正在运行的容器:(
docker-compose stop
) - 删除所有停止的容器(
docker-compose rm -f
) - 构build容器(
docker-compose build
) - 运行所有构build的容器(
docker-compose up -d
) - 运行所有init,并通过
docker exec
在容器内启动脚本(例如:config编译器,nginx重载)
这对我来说工作得很好,但是我对这个scheme有一些疑问:
- 在步骤6中 ,如果我不将文件更改为节点容器,则会使用已经构build的映像 – 速度很快。 但是,如果我改变了一些东西,容器会重新生成 – 速度很慢,会增加未使用的图像
- 在最糟糕的情况下(当我修改节点代码时),部署时间可能持续约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),但由于它在同一主机上,没有问题。