如何编辑已停止/无法启动的Docker容器中的文件

24 浏览
0 Comments

如何编辑已停止/无法启动的Docker容器中的文件

尝试修复我应用程序中分散在多个容器中的错误和调试问题时,我经常在容器中编辑文件:\n

    \n

  • 要么我非常懒,安装了nano并直接在容器中编辑,要么
  • \n

  • 我将文件从容器中复制出来进行编辑,然后再复制回去并重新启动容器
  • \n

\n这些都是在构建容器的新内容之前的中间步骤,而构建容器的时间比上述步骤要长得多(当然,这只是中间操作/摆弄)。\n现在,我经常破坏容器的启动程序,在这些破坏的情况下,启动程序要么是一个Node脚本,要么是一个Python Web服务器脚本,这两种脚本通常由于语法错误而失败。\n有没有办法保存这些容器?由于它们无法启动,我无法进入它们,因此对我来说它们就是丢失了。在修复了构建输入中有问题的文件后,我会执行rm/rmi/build/run的步骤。\n有什么办法可以在停止的容器中编辑文件,或者将文件复制进去,或者在停止的容器中启动一个shell - 任何可以让我修复这个容器的方法?\n(这有点像在远程计算机上工作并破坏网络配置 - 这样连接就会永远丢失,必须使用备份(如果有的话))。\n如何从主机编辑Docker容器文件?看起来相关,但已经过时。

0
0 Comments

问题出现的原因:无法编辑停止或无法启动的Docker容器中的文件。

解决方法:直接编辑容器文件系统,找到容器运行时根目录的路径。运行命令docker container inspect id/name,查找JSON输出中的UpperDir键,这就是你的目录。然后找到该目录,但并不包含所有文件,因为它是OverlayFS,所以文件可能在其他目录中。目录名称可能与"UpperDir"不同,例如,在我的情况下是"Source"。你可以在"MergedDir"上工作,它将包含来自较低目录的所有文件,并在其上进行差异。如果你修改了某些内容,它将出现在差异中,就像在容器中一样...

0
0 Comments

如何编辑已停止/无法启动的Docker容器中的文件

有两种可能性。

1)直接在主机上编辑文件系统。这种方法有一定的危险性,可能会完全破坏容器,可能还会影响其他数据,具体取决于出错的情况。

2)更改启动脚本为永远不会失败的脚本,比如启动一个bash,进行修复/编辑,然后再将启动程序更改为所需的程序(例如node或之前使用的程序)。

更多细节:

1)使用docker ps命令查找正在运行的容器,或使用docker ps -a命令查找所有容器(包括已停止的容器),然后使用docker inspect命令查找“Id”,它是容器的唯一标识符。

这部分内容包含实现细节,可能会发生变化,请注意这种方法可能会导致容器丢失。

进入/var/lib/docker/aufs/diff/9bc343a9..(长容器ID)目录,您将找到与容器基于的映像不同的所有文件。您可以覆盖文件,添加或编辑文件。

再次强烈不推荐此方法。

2)根据https://stackoverflow.com/a/32353134/586754中的描述,可以在类似/var/lib/docker/containers/9bc343a99..(长容器ID)/config.json的路径中找到配置文件config.json。

在这里,您可以将args从例如"nodejs app.js"更改为"/bin/bash"。现在重新启动docker服务并启动容器(您应该看到它现在正确启动)。您可以使用docker start -i(容器名称)确保它不会立即退出。现在,您可以与容器一起工作,或稍后使用docker exec -ti(容器名称)/bin/bash附加到容器。

此外,docker cp命令非常有用,用于复制在容器外部编辑的文件。

只有当容器几乎“丢失”时才应该退回到这些方法,因此任何更改都将是一种改进。

如果您有更好的答案,请随时给出,我将移除“answered”标签。

我使用了第二种方法,我不得不重新启动docker服务,以强制覆盖每次编辑config.json文件。

我有config.v2.json文件,每次启动僵尸容器时,它都会恢复我的Path/EntryPoint更新,然后再次停止。使用“docker cp”更新entrypoint.sh脚本以仅运行bash就可以解决这个问题。

我遇到了相同的问题。你是如何解决的?

我使用docker cp而不是在主机上进行编辑。像这样:找到入口点脚本位置:“docker inspect container_name | grep Entry”。获取脚本:“docker cp container_name:/entrypoint.sh ./”。(编辑它)将脚本放回容器中:“docker cp entrypoint.sh container_name:/entrypoint.sh”。您可以使入口点运行bash或运行一个sleep循环,例如“while:; do sleep 10; done”。脚本的第一行需要是“#!/bin/bash”。

谢谢Curtis!!你为我解决了大难题.....我如释重负,以为我的工作丢了....

0
0 Comments

问题的原因是由于错误的配置更改导致容器无法启动。解决方法是将文件从停止的容器中复制出来进行编辑,然后再将其复制回相同的位置。如果要删除文件,只有在docker container inspect中得到的UpperDir中出现,才可以删除。如果源文件是符号链接,可能会出现错误,所以要确保复制的是原始文件。在修改后记得提交镜像,否则在容器重新启动后修改将会丢失。

0