使用docker-compose在停止时重新创建容器

时间:2018-04-06 14:09:19

标签: docker docker-compose

我正在尝试使用docker-compose设置多容器服务。

某些容器需要在重新启动时从新容器重新启动(例如,文件系统应该像图像中一样)。 我怎样才能做到这一点?

我在restart: always文件中找到了可以放在我服务上的docker-compose.yml选项,但这并没有给我一个新的文件系统,因为它使用相同的容器。

我还看到--force-recreate的{​​{1}}选项,但这不适用,因为只在运行命令时重新创建容器。

编辑:

这可能不是一个码头构成问题,而是更多的一般码头问题:确保容器在重新启动时处于新鲜状态的最佳方法是什么?以新鲜州,我指的是一个与同一图像中的全新容器相同的状态。重新启动的是docker命令docker-compose updocker restartdocker stop

3 个答案:

答案 0 :(得分:2)

在泊坞窗中,不变性通常指的是图像层。它们是不可变的,任何更改都会被推送到文件系统的容器特定的copy-on-write层。容器特定层将持续容器的生命周期。因此,要让这些文件不存在,您有两种选择:

  1. 重新创建容器而不是重新启动容器
  2. 不要将更改写入容器文件系统,也不要将其写入任何持久卷。
  3. 根据它的定义,您不能使用重启策略执行#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 rundocker-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