Docker容器是否保留文件更改?

70

这是一个非常基础的问题,但我有些困惑,希望确保我正确理解。

在从镜像启动容器并对其中的文件进行一些更改后(即:运行在容器上的WebApp的DB中存储了一些数据),在停止和重新启动容器之间继续使用相同的数据的适当方法是什么?

我的理解是否正确,即一旦容器被停止/完成(即:在交互会话后退出),那么该容器将与所有文件更改一起消失? 因此,如果我想要保留一些文件更改,则需要将容器的状态提交到新图像/图像的新版本中吗?

2个回答

92

我的理解是,一旦容器停止/结束(即交互式会话退出),那么该容器就消失了,包括所有文件更改。这个理解正确吗?

不是的,除非你使用--rm参数启动docker run命令,否则容器在退出后仍然存在。请考虑以下示例:

$ docker run -it busybox sh
/ # date > example_file
/ # exit

因为我们已经使用 exit 命令退出了 shell,所以容器不再运行:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                   NAMES

但如果我们使用-a选项,就可以看到它:

CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                      PORTS                   NAMES
79aee3e2774e        busybox:latest      "sh"                About a minute ago   Exited (0) 54 seconds ago                           loving_fermat       

然后我们可以重新启动并重新附加到它:

$ docker start 79aee3e2774e
$ docker attach  79aee3e2774e
<i press RETURN>
/ #

而我们之前创建的文件仍然存在:

/ # cat example_file
Wed Feb 18 01:51:38 UTC 2015
/ #
你可以使用 docker commit 命令将容器的内容保存为一个新镜像,你可以用它来启动新的容器,或与别人分享等。但是请注意,如果你经常使用 docker commit,那么你可能会给自己带来不便。一般来说,更好的做法是将容器视为只读的,并使用 Dockerfile 和 docker build 生成新的镜像。
在这种模型中,数据通常被保留在容器外部,通过主机卷挂载或使用数据卷容器的方式。

4
面掌 我使用了 --rm (!!!) - 太多的谷歌粘贴错误。我知道这是一个愚蠢的问题。 - Julian Cerruti
4
无论如何,非常感谢您进行了全面的解释。整个模型现在对我来说更加有意义了。针对我的情况,我将尽可能使用容器外通过主机卷挂载的数据。只有偶尔需要修改容器以安装某些内容。有了这个澄清,我现在可以让容器保持不变,并在必要时将其提交到新镜像中,以与其他开发人员共享。再次感谢,回答很棒! - Julian Cerruti
1
顺便说一句,我喜欢开头的讽刺性错别字:“……一个容器在存在之后仍然存在……”。听起来像是一个不屈不挠的容器。 - Julian Cerruti
3
如果您杀死容器79aee3e2774e,当您使用相同的镜像启动新容器时,文件是否仍然存在? - James Lin
退出后,Docker 如何决定要持久化哪些内容?例如:退出后,新的 Docker 配置仍然存在于 Docker 中,但如果您安装了 vim,则此更改将被拒绝。那么 Docker 如何知道要持久化哪些内容呢?@Larsks - grep

21

使用docker ps -a命令可以查看已经完成的容器。

可以使用docker commit container_name new_image_name将已完成的容器(包括文件系统改动)保存为一个镜像。

还可以使用docker cp containerID:/path/to/find/files /path/to/put/copy从已完成的容器中提取数据文件。

请注意,您也可以“提前计划”,通过让容器挂载主机上的目录来避免将需要永久保存的数据陷入临时容器中,例如:

 docker run -v /dir/on/host:/dir/on/container -it ubuntu:14.04 

退出后,Docker 如何决定要持久化哪些内容?例如:退出后,新的 Nginx 配置仍然在 Docker 中,但如果通过终端安装 Vim,则此更改将被拒绝。那么 Docker 如何知道要持久化哪些内容呢? - grep
我并不完全明白你的问题:Docker并不会“选择”是否要保留任何内容。对容器文件系统的修改会一直持久化,除非你移除了该容器。对于卷中的修改也是同理,只有在移除该卷之后才会消失。 - larsks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接