使用Shell脚本对多个Docker容器执行“git pull”是否是一种好的做法?

使用Shell脚本对多个Docker容器执行“git pull”是否是一种好的做法?,git,docker,Git,Docker,我有一个遗留项目,其中服务器中有多个Docker容器,它们使用来自同一git存储库的代码 目前,如果代码有更新,我需要远程访问每个docker容器,然后逐个提取代码 例如,我需要跑步 docker exec -it {container_id} bash 然后我重复执行git pull命令 因此,我考虑创建一个shell脚本,自动更新所有Docker容器一次。但我不确定这是否是一个好的实践。在所有docker容器中执行命令的简单shell脚本如下 #!/bin/bash CON=$(dock

我有一个遗留项目,其中服务器中有多个Docker容器,它们使用来自同一git存储库的代码

目前,如果代码有更新,我需要远程访问每个docker容器,然后逐个提取代码

例如,我需要跑步

docker exec -it {container_id} bash
然后我重复执行git pull命令


因此,我考虑创建一个shell脚本,自动更新所有Docker容器一次。但我不确定这是否是一个好的实践。

在所有docker容器中执行命令的简单shell脚本如下

#!/bin/bash

CON=$(docker ps -aq)

for i in $CON
do
        echo $i
        docker exec -it $i bash -c 'echo \"Hello\"'
done

在所有docker容器中执行命令的简单shell脚本如下

#!/bin/bash

CON=$(docker ps -aq)

for i in $CON
do
        echo $i
        docker exec -it $i bash -c 'echo \"Hello\"'
done

运行docker exec的自动化脚本几乎从来都不是好的做法

在这种情况下,标准的Docker实践是相当清楚的。所有应用程序代码都属于Docker映像。您从未尝试更新正在运行的容器中的代码或依赖项;相反,您构建一个包含新代码的新映像,然后将旧容器替换为新容器

因此,对于每个源代码存储库,如果根目录中还没有Dockerfile,则在其根目录中放置一个Dockerfile。每当你有变化的时候,就做些类似的事情

docker build -t myorg/myapp:$(git rev-parse HEAD)
docker push myorg/myapp:$(git rev-parse HEAD)
在实际部署它的系统上,您可以

TAG=0123456789abcdef0123456789abcdef01234567
docker pull myorg/myapp:$TAG
docker stop myapp
docker rm myapp
docker run --name myapp ... myorg/myapp:$TAG
有很多支持软件可以简化这一过程。容器编排工具可以为您处理停止和重新启动序列;Docker Compose对于许多生产级工作负载来说有点轻量级,但您只需更改Docker-Compose.yml中的图像标记,然后重新运行Docker Compose up-d,它就会为您处理此问题。您可能需要一个私有Docker注册表来保存这些图像,并需要一个持续集成服务器来在有签入时为您运行这些步骤

这种设置有几个优点。从docker ps输出可以明显看出您实际运行的代码版本。如果部署失败,您可以很容易地恢复到以前的版本。用一组精确的候选构建建立一个预生产环境非常简单;针对它构建测试是一项工作,但是如果给定的映像不起作用,您可以决定不部署它


作为额外的好处,您的映像可以更小,因为不需要源代码管理工具,您也不需要在生产环境中放置凭据来访问源代码管理。

运行docker exec的自动脚本几乎从来都不是好的做法

在这种情况下,标准的Docker实践是相当清楚的。所有应用程序代码都属于Docker映像。您从未尝试更新正在运行的容器中的代码或依赖项;相反,您构建一个包含新代码的新映像,然后将旧容器替换为新容器

因此,对于每个源代码存储库,如果根目录中还没有Dockerfile,则在其根目录中放置一个Dockerfile。每当你有变化的时候,就做些类似的事情

docker build -t myorg/myapp:$(git rev-parse HEAD)
docker push myorg/myapp:$(git rev-parse HEAD)
在实际部署它的系统上,您可以

TAG=0123456789abcdef0123456789abcdef01234567
docker pull myorg/myapp:$TAG
docker stop myapp
docker rm myapp
docker run --name myapp ... myorg/myapp:$TAG
有很多支持软件可以简化这一过程。容器编排工具可以为您处理停止和重新启动序列;Docker Compose对于许多生产级工作负载来说有点轻量级,但您只需更改Docker-Compose.yml中的图像标记,然后重新运行Docker Compose up-d,它就会为您处理此问题。您可能需要一个私有Docker注册表来保存这些图像,并需要一个持续集成服务器来在有签入时为您运行这些步骤

这种设置有几个优点。从docker ps输出可以明显看出您实际运行的代码版本。如果部署失败,您可以很容易地恢复到以前的版本。用一组精确的候选构建建立一个预生产环境非常简单;针对它构建测试是一项工作,但是如果给定的映像不起作用,您可以决定不部署它


作为额外的好处,您的图像可以更小,因为不需要源代码管理工具,您也不需要在生产环境中放置访问源代码管理的凭据。

当然,这不是一个好做法,重复自己从来都不是一个好做法。但是您使用的是Docker,因此良好的实践已经离您远去了。如何将Docker容器重新配置为从包含git repo的同一主机目录开始?类似于:。我在这里假设容器只是读取,而不是写入任何内容,否则可能会出现数据损坏问题。当然,这不是一个好的做法,重复自己从来都不是一个好的做法。但是您使用的是Docker,因此良好的实践已经离您远去了。如何将Docker容器重新配置为从包含git repo的同一主机目录开始?类似于:。我在这里假设容器只是读取,而不是写入任何内容,否则可能会导致数据损坏 问题。