簡體   English   中英

使用docker-compose在停止時重新創建容器

[英]Recreate container on stop with docker-compose

我正在嘗試使用docker-compose設置多容器服務。

一些容器需要在重新啟動時從新容器重新啟動(例如,文件系統應該像圖像中一樣)。 我怎樣才能做到這一點?

我發現了restart: always選項我可以在docker-compose.yml文件中提供我的服務,但這並沒有給我一個新的文件系統,因為它使用相同的容器。

我還看到了--force-recreate docker-compose up--force-recreate選項,但這不適用,因為只有在運行命令時才重新創建容器。

編輯:

這可能不是一個docker-compose問題,而是一個普遍的docker問題: 在重新啟動容器時確保容器處於新狀態的最佳方法是什么? 在新鮮狀態下,我的意思是與同一圖像中的全新容器相同的狀態。 重新啟動的是docker命令docker restartdocker stopdocker start

在docker中,不變性通常指的是圖像層。 它們是不可變的,任何更改都會被推送到文件系統的容器特定的copy-on-write層。 容器特定層將持續容器的生命周期。 因此,要讓這些文件不存在,您有兩種選擇:

  1. 重新創建容器而不是重新啟動容器
  2. 不要將更改寫入容器文件系統,也不要將它們寫入任何持久卷。

根據它的定義,您不能使用重啟策略執行#1。 重新啟動策略為您提供相同的容器文件系統,並重新啟動應用程序。 但是如果你使用docker的swarm模式,它會在它們退出時重新創建容器,所以如果你可以遷移到swarm模式,你就可以實現這個結果。

選項#2看起來比實際困難。 如果您沒有寫入容器文件系統或卷,那么在哪里? 答案是tmpfs卷只存儲在內存中,並在容器退出后立即丟失。 在compose中,這是一個tmpfs: /data/dir/to/not/persist行。 這是docker命令行上的一個示例。

首先,讓我們創建一個容器,其中tmpfs安裝在/data ,添加一些內容,然后退出容器:

$ 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的一部分。

為了不對容器進行任何更改,只要不將任何目錄從主機映射到容器就足夠了。

這樣,每次容器運行時(使用docker rundocker-compose up ),它都會以新的文件系統啟動。

docker-compose down也會刪除容器,刪除任何數據。

我到目前為止找到的最佳解決方案是容器本身確保在啟動或停止時進行清理。 我在開始時通過清理來解決這個問題。

我使用Dockerfile COPY指令將我的app文件復制到/srv/template ,並在我的ENTRYPOINT腳本中有類似的東西:

rm -rf /srv/server/
cp -r /srv/template /srv/server
cd /srv/server

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM