使用新代码更新Docker容器

时间:2018-09-04 19:38:41

标签: python docker

我看了其他一些答案,但似乎都不是我想要的。

我有一个写的python机器人,我转过一个通过

启动的docker容器

docker run -dit --restart unless-stopped -v /home/dockeradmin/pythonApp/:/pythonApp--name python-bot-app python-bot

我的问题是,当我更改python项目的代码时如何更新docker容器。现在,通常我将只重建映像,停止/修剪容器,然后再次启动它,但这似乎非常浪费。

有没有简单或“正确”的方法来做到这一点?

3 个答案:

答案 0 :(得分:3)

  

我有一个写的python机器人,我转过一个通过

启动的docker容器
docker run -dit --restart unless-stopped \
  -v /home/dockeradmin/pythonApp/:/pythonApp \
  --name python-bot-app  python-bot

这是在开发环境(如笔记本电脑)中运行容器的非常常用的方法。容器上的名称使您可以轻松找到并管理容器。该卷装载将容器中的当前代码包括在该映像中同一位置的任何内容之上。如果重新启动容器,则卷挂载将使用容器中的新代码重新启动应用程序,这应该意味着测试python中的更改仅涉及以下内容:

docker container restart python-bot
  

我的问题是,当我更改python项目的代码时如何更新docker容器。

当您开始在生产环境中部署应用程序时,以上情况并不理想。您需要轻松地重新部署某些东西,如果出现错误,撤消的能力会迅速改变,最重要的是,您需要避免状态漂移的风险。进入生产的标准工作流程包括:

  1. 签到代码更改为版本控制
  2. 让构建服务器检测到这些更改并使用唯一标记创建新图像
  3. 将该图像推送到注册表服务器
  4. 根据您的组织政策在开发,配置,阶段和产品环境中部署该映像

重要的部分是您不就地升级容器,所有代码都在映像内部,而不是与卷一起装载(您仍然有用于数据的卷),并且您也不给容器任何独特的东西这样将无法像容器名称一样进行缩放。

  

现在,我通常只重建图像,停止/修剪容器,然后再次启动它,但这似乎非常浪费。

在单节点实现上,您可以从docker-compose开始替换该容器,它将为您处理停止和重新启动步骤。进入多节点环境时,您需要Swarm Mode或Kubernetes处理应用程序的滚动更新,提供HA并避免在应用程序更新期间出现任何中断。

使用容器时,可以通过有效地对映像进行分层,重新使用构建缓存以及使用注册表服务器运送映像来最大程度地减少浪费。 Docker的文件系统层在彼此之上构建以创建映像,如果仅在最后一层中更改一些文件,则在部署更新的映像时仅发送那些更改。对应用程序的任何更改都将至少涉及重新启动该应用程序,并且容器只是一点点额外的内核API调用,即可通过设置来创建自己的名称空间和限制来运行该应用程序。与重新创建容器而不是重新启动容器相比,您唯一的附加功能是增加了一些内部管理,以删除旧图像以及可能已停止的一些容器。但是,在了解整个环境是可重现的而没有任何状态漂移的情况下获得的优势值得您付出更多的努力。

答案 1 :(得分:0)

有一种“简单”但可能不是“正确”的方法-我可以将其归类为“解决方法”。

首先启动您的工作容器,我将以ubuntu为例,但是您当然可以根据需要进行调整:

docker run -dit --name work-container -v /path-to-code:/code ubuntu bash -c "while true; do sleep 10; done"

因此该命令将在无休止循环的后台为您启动ubuntu。在-v部分中,您应该安装更改的代码。现在打开新控制台并输入:

docker exec -it work-container bash

因此该命令在该后台容器内启动新的shell。因此,在该shell中,您可以在容器内执行任何操作,例如cd /code && ./do-something-with-your-python。将代码安装在容器中的/ code下后,您将实时看到更改,您可以运行一些程序,然后按ctrl + c并在更改代码后重新启动它。

答案 2 :(得分:0)

在代码更改时重建映像是一种规范的方法,如果做对了,这一点也不浪费。

您的pythonApp代码应COPY放入图像中作为最后一步(经验法则:dockerfile中最频繁更改的步骤应该排在最后)。这意味着重建将非常快,因为将缓存所有其他步骤。如果仅对源代码进行几kB的更改,则只会导致一个新的几kB的新层。停止和启动容器也很轻。

采用这种方法无需担心。