我正在尝试使用docker-compose设置多容器服务。
某些容器需要在重新启动时从新容器重新启动(例如,文件系统应该像图像中一样)。 我怎样才能做到这一点?
我在restart: always
文件中找到了可以放在我服务上的docker-compose.yml
选项,但这并没有给我一个新的文件系统,因为它使用相同的容器。
我还看到--force-recreate
的{{1}}选项,但这不适用,因为只在运行命令时重新创建容器。
这可能不是一个码头构成问题,而是更多的一般码头问题:确保容器在重新启动时处于新鲜状态的最佳方法是什么?以新鲜州,我指的是一个与同一图像中的全新容器相同的状态。重新启动的是docker命令docker-compose up
或docker restart
和docker stop
。
答案 0 :(得分:2)
在泊坞窗中,不变性通常指的是图像层。它们是不可变的,任何更改都会被推送到文件系统的容器特定的copy-on-write层。容器特定层将持续容器的生命周期。因此,要让这些文件不存在,您有两种选择:
根据它的定义,您不能使用重启策略执行#1。重新启动策略为您提供相同的容器文件系统,并重新启动应用程序。但是如果你使用docker的swarm模式,它会在它们退出时重新创建容器,所以如果你可以迁移到swarm模式,你就可以实现这个结果。
选项#2看起来比实际困难。如果您没有写入容器文件系统或卷,那么在哪里? The answer is a tmpfs volume that is only stored in memory and is lost as soon as the container exits.在撰写时,这是tmpfs: /data/dir/to/not/persist
行。这是docker命令行中的一个示例。
首先,让我们创建一个在/data
安装了tmpfs的容器,添加一些内容,然后退出容器:
$ docker run -it --tmpfs /data --name no-persist busybox /bin/sh
/ # ls -al /data
total 4
drwxrwxrwt 2 root root 40 Apr 7 21:50 .
drwxr-xr-x 1 root root 4096 Apr 7 21:50 ..
/ # echo 'do not save' >>/data/tmp-data.txt
/ # cat /data/tmp-data.txt
do not save
/ # ls -al /data
total 8
drwxrwxrwt 2 root root 60 Apr 7 21:51 .
drwxr-xr-x 1 root root 4096 Apr 7 21:50 ..
-rw-r--r-- 1 root root 12 Apr 7 21:51 tmp-data.txt
/ # exit
很简单,它表现为普通容器,让我们重新启动它并检查目录内容:
$ docker restart no-persist
no-persist
$ docker attach no-persist
/ # ls -al /data
total 4
drwxr-xr-x 2 root root 40 Apr 7 21:51 .
drwxr-xr-x 1 root root 4096 Apr 7 21:50 ..
/ # echo 'still do not save' >>/data/do-not-save.txt
/ # ls -al /data
total 8
drwxr-xr-x 2 root root 60 Apr 7 21:52 .
drwxr-xr-x 1 root root 4096 Apr 7 21:50 ..
-rw-r--r-- 1 root root 18 Apr 7 21:52 do-not-save.txt
/ # exit
如您所见,目录返回为空,我们可以根据需要将数据添加回目录。唯一的缺点是,即使您在该位置的图像中有内容,目录也将为空。我尝试过命名卷的组合,或者使用mount语法并将volume-nocopy选项传递给0,没有运气。因此,如果您需要初始化目录,则需要通过从其他位置复制来将其作为容器入口点/ cmd的一部分。
答案 1 :(得分:1)
为了不对容器进行任何更改,只要您不将任何目录从主机映射到容器就足够了。
通过这种方式,每次容器运行时(使用docker run
或docker-compose up
),它都会以新的文件系统启动。
docker-compose down
也删除容器,删除任何数据。
答案 2 :(得分:0)
到目前为止,我找到的最佳解决方案是容器本身确保在启动或停止时进行清理。我在开始时通过清理来解决这个问题。
我使用/srv/template
中的docker COPY
指令将我的应用文件复制到Dockerfile
,并在我的ENTRYPOINT
脚本中显示类似内容:
rm -rf /srv/server/
cp -r /srv/template /srv/server
cd /srv/server