在文件更改时重buildDocker容器
为了运行ASP.NET Core应用程序,我生成了一个dockerfile,它构build应用程序,并复制容器中的源代码,该容器由Git使用Jenkins提取。 所以在我的工作区中,我在dockerfile中执行以下操作:
WORKDIR /app COPY src src
当Jenkins使用Git正确更新我的主机上的文件时,Docker不会将其应用于我的映像。
我的基本build设脚本:
#!/bin/bash imageName=xx:my-image containerName=my-container docker build -t $imageName -f Dockerfile . containerRunning=$(docker inspect --format="{{ .State.Running }}" $containerName 2> /dev/null) if [ "$containerRunning" == "true" ]; then docker stop $containerName docker start $containerName else docker run -d -p 5000:5000 --name $containerName $imageName fi
我尝试了不同的东西,例如--rm
和--no-cache
参数,以及在构build新容器之前停止/移除容器。 我不确定我在这里做错了什么。 看来docker正在更新正确的图像,因为COPY src src
的调用会导致层id和没有caching调用:
Step 6 : COPY src src ---> 382ef210d8fd
什么是更新容器的推荐方法?
我的典型场景是:应用程序在Docker容器中的服务器上运行。 现在部分应用程序被更新,例如通过修改文件。 现在容器应该运行新版本。 Docker似乎build议创build一个新的映像,而不是修改一个现有的容器,所以我认为像我这样做的一般重build方式是正确的,但实施中的一些细节有待改进。
经过一番研究和testing,我发现我对Docker容器的生命周期有一些误解。 简单地重启一个容器并不会让Docker使用一个新的图像,当时图像被重build。 相反,Docker仅在运行容器之前获取图像。 所以运行一个容器后的状态是持久的。
为什么需要删除
所以重build和重启是不够的。 我以为容器的工作就像一个服务:停止服务,做你的改变,重新启动它,他们将适用。 那是我最大的错误。
因为容器是永久的,所以你必须首先使用docker rm <ContainerName>
来移除它们。 一个容器被删除后,你不能简单地通过docker start
来启动它。 这必须使用docker run
来完成, docker run
本身使用最新的镜像来创build一个新的容器实例。
集装箱应尽可能独立
有了这些知识,可以理解为什么在容器中存储数据被认为是不好的做法,而Dockerbuild议使用数据卷/挂载主导向器:因为必须销毁容器来更新应用程序,所以内部存储的数据也会丢失。 这会导致额外的工作closures服务,备份数据等等。
因此,将这些数据完全从容器中排除是一个明智的解决scheme:当数据安全地存储在主机上并且容器仅保存应用程序本身时,我们不必担心数据。
为什么-rf
可能不会真的帮你
docker run
命令,有一个名为-rf
的清理开关。 这将停止永久保持docker集装箱的行为。 使用-rf
,Docker在退出后将销毁容器。 但是这个开关有两个问题:
- Docker也删除没有与容器相关联的名称的卷,这可能会导致数据中断
- 使用这个选项,不可能使用
-d
开关在后台运行容器
在快速testing的开发过程中, -rf
开关是一个很好的select,因此在生产中不太合适。 特别是因为缺less在后台运行容器的选项,这将主要是需要的。
如何删除一个容器
我们可以通过简单地删除容器来绕过这些限制:
docker rm --force <ContainerName>
在运行容器上使用SIGKILL的--force
(或-f
)开关。 相反,您也可以在以下时间停止容器:
docker stop <ContainerName> docker rm <ContainerName>
两者是平等的。 docker stop
也在使用SIGTERM 。 但是使用--force
切换会缩短脚本,特别是在使用CI服务器的时候:如果容器没有运行, docker stop
会抛出一个错误。 这会导致Jenkins和其他许多CI服务器错误地认为构build失败。 要解决这个问题,你必须首先检查容器是否按照我在问题中所做的那样运行(请参阅containerRunning
variables)。
用于重buildDocker容器的完整脚本
根据这个新的知识,我以如下方式修正了我的脚本:
#!/bin/bash imageName=xx:my-image containerName=my-container docker build -t $imageName -f Dockerfile . echo Delete old container... docker rm -f $containerName echo Run new container... docker run -d -p 5000:5000 --name $containerName $imageName
这完美的作品:)
- DotNet构buildCLI在terminal中工作,但不在Docker构build中
- .NET Core SDK与Docker的运行时版本
- 在Docker上连接到MySql
- 具有ASP.NET核心库的Docker容器
- .Net Core WebApi拒绝在Docker容器中的连接
- AWS Codebuild .NET Core构buildDocker镜像
- 如何从docker容器中的bash检查.net核心dll的版本
- 如何将Visual Studio 2015debugging器附加到以前部署的asp.net核心docker容器
- 在ASP.NET Core中构builddocker:“没有这样的文件或目录”错误