当前位置: 首页 > 面试题库 >

在文件更改时重建Docker容器

岳志义
2023-03-14
问题内容

为了运行ASP.NET
Core应用程序,我生成了一个dockerfile,该文件构建了该应用程序,并将源代码复制到了容器中,该容器由Git使用Jenkins获取。因此,在我的工作区中,我在dockerfile中执行以下操作:

WORKDIR /app
COPY src src

虽然Jenkins使用Git正确更新了主机上的文件,但Docker并未将其应用于我的映像。

我的基本构建脚本:

#!/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参数,docker run 构建新容器 之前
停止/删除了容器。我不确定我在做什么错。似乎docker正在正确更新映像,因为的调用COPY src src会导致图层ID且没有缓存调用:

Step 6 : COPY src src
 ---> 382ef210d8fd

推荐的更新容器的方法是什么?

我的典型场景是:应用程序在Docker容器中的服务器上运行。现在,应用程序的某些部分已更新,例如通过修改文件。现在,容器应运行新版本。Docker似乎建议构建一个新映像而不是修改现有容器,因此我认为像我一样进行重建的一般方法是正确的,但是实现中的一些细节必须改进。


问题答案:

经过一些研究和测试,我发现我对Docker容器的生命存在一些误解。在此期间重建映像时,仅重新启动容器并不会使Docker使用新映像。相反,Docker仅
创建容器 之前 获取映像。因此,运行容器后的状态是持久的。

为什么需要删除

因此,仅重建和重新启动是不够的。我认为容器就像服务一样工作:停止服务,进行更改,重新启动它,它们将适用。那是我最大的错误。

由于容器是永久性的,因此您必须先使用容器将其删除docker rm <ContainerName>。删除容器后,您不能简单地通过来启动它docker start。必须使用来完成此操作docker run,本身使用最新的图像来创建新的容器实例。

容器应尽可能独立

有了这些知识,就可以理解为什么将数据存储在容器中被视为不良做法,而Docker建议改为使用数据卷/挂载主机目录:由于必须销毁容器来更新应用程序,因此内部存储的数据也将丢失。这会导致额外的工作来关闭服务,备份数据等。

因此,将这些数据完全从容器中排除是一个明智的解决方案:当数据安全地存储在主机上并且容器仅包含应用程序本身时,我们不必担心我们的数据。

为什么-rf不能真正帮助您

docker run命令有一个名为的 清理
开关-rf。它将停止永久保留docker容器的行为。使用-rf,Docker将在退出容器后销毁该容器。但是此开关有两个问题:

  1. Docker还删除了没有与容器相关联的名称的卷,这可能会杀死您的数据
  2. 使用此选项,将无法使用-dswitch 在后台运行容器

虽然该-rf开关是节省开发过程中的工作以进行快速测试的不错选择,但它不适用于生产环境。特别是由于缺少在后台运行容器的选项,因此通常需要这样做。

如何取出容器

我们可以通过简单地删除容器来绕过这些限制:

docker rm --force <ContainerName>

--force(或-f其中使用SIGKILL上运行的容器)开关。相反,您也可以在以下之前停止容器:

docker stop <ContainerName>
docker rm <ContainerName>

两者相等。docker stop也正在使用SIGTERM。但是,使用--forceswitch会缩短脚本,尤其是在使用CI服务器时:docker stop如果容器未运行,则会引发错误。这将导致Jenkins和许多其他CI服务器错误地认为构建失败。要解决此问题,您必须首先检查容器是否正在按问题中的方式运行(请参阅containerRunning变量)。

用于重建Docker容器的完整脚本

根据这一新知识,我通过以下方式修复了脚本:

#!/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

这完美地工作:)



 类似资料:
  • 为了运行ASP. NET Core应用程序,我生成了一个dockerfile来构建应用程序并将源代码复制到容器中,该容器由Git使用Jenkins获取。所以在我的工作区中,我在dockerfile中执行以下操作: 虽然Jenkins使用Git正确更新了我主机上的文件,但Docker不会将其应用于我的映像。 我的基本建筑脚本: 我尝试了不同的方法,例如用于docker run的rm和no cache

  • 问题内容: 我正在通过创建带有一些nodejs指令的来玩docker。现在,每次更改dockerfile时,我都会通过在项目文件夹中运行来重新创建映像,但这每次都会创建一个新映像,并很快吞没我的ssd。 更改dockerfile时,是否有一种方法可以更新现有映像,或者每次更改文件时都被迫创建一个新映像? 抱歉,这是一个愚蠢的问题 问题答案: 只要没有指令,Docker构建支持缓存。如果您正在积极地

  • 是否可以更改卷本地路径? 使用Kitematic,我可以做到这一点。但我没有找到从cli执行此操作的方法。 例如,我运行docker使用: 我想重复使用容器,但如果可能,请更改体积。

  • 我是开发和的新手,在更改项目中的文件时遇到了一个问题。我的问题是: 我对项目中的任何文件(模板、视图、URL)的内容进行了更改,但在我当前运行的应用程序中,这些文件没有更新。我总是希望看到我的更改,我需要重新启动服务器(我正在使用),执行。是否有我应该安装/做的软件包或更改,以使其能够在运行时接受更改? 这是我的: 让我知道我可能提供的任何其他信息,以便更好地了解问题(如果不够清楚的话)。

  • 我们在项目中使用JBoss7,并在文件中编写了日志记录配置, 我已经尝试删除standalone_xml_history目录及其下的文件,但没有什么可以阻止覆盖行为,请任何人建议。