前幾天介紹完了 Docker 基本使用了,不知道各位有沒有發現一個問題,就是如果有資料放在 Container 中的話,如果 Container 重啟之後資料就不見了!
那麼如果現在在 Container 有個東西必須儲存,但是又不能不見,必須保留下來,又該如何處理呢?
Docker 當然有想到這一點,而解決方式就是使用 Volume , Volume 雖然不是重要的三元件之一,但是也是很重要的東西(畢竟重要資料不見那可不是開玩笑的)。
那麼首先,還是前幾天的那個架構。
test-project
├── app.py
├── Dockerfile
└── requirements.txt
不過這邊要改一下 Dockerfile
,把它改成如下的樣子。
FROM python:3.9.10-alpine3.15
WORKDIR /test-project
# ! 注意
COPY requirements.txt .
RUN pip install -r requirements.txt
# ! 注意
VOLUME /test-project
EXPOSE 5000
# ! 注意
ENTRYPOINT ["python"]
# ! 注意
CMD ["app.py"]
接著再重 Build 一次。
$ docker build --no-cache -t flask-env .
接著我們直接把剛剛 Build 好的 Image 直接 run 起來,不過這次指令不太一樣。
$ docker run -it -p 5000:5000 -v <你本機`/test-project`的路徑>:/test-project flask-env
接著到 http://localhost:5000 應該就會看到一樣的內容。
不知道各位有沒有看懂剛剛的操作,沒看懂也沒關係,我來慢慢講解剛剛做了什麼事。
首先 Dockerfile 第三行從 COPY * .
改成 COPY requirements.txt .
,這是因為我們不想把其他東西複製進去 Image 裡面,只想要 requirements.txt
複製進去安裝好環境就可以了。
接著第五行多出了一個 VOLUME /test-project
,這行主要是設定說 Image 中可以掛載的位置,而在 run 的時候,我們使用了 -v <你本機/test-project的路徑>:/test-project
把 test-project 整個目錄掛載進去了,因此 run 起來之後我們才可以執行 python app.py 的指令。
是第七行從原本的 CMD ["python", "app.py"]
拆成兩行 ENTRYPOINT ["python"]
跟 CMD ["app.py"]
(對,ENTRYPOINT
跟 CMD
可以同時使用,Docker 會把它們串起來)。
至於這麼做的原因是因為我們這個環境安裝好了相關的套件,且並沒有將程式放進去(對 Image 來說),假設我們想要跑的是另一個檔名的程式,我們可以簡單的使用 加上另外的參數即可,就像下方的指令一樣。
# 假設想跑的是 main.py
$ docker run -it -p 5000:5000 -v <你本機`/test-project`的路徑>:/test-project flask-env main.py
這樣就可以再次利用同一個 Image ,而不需要雖然都是使用同樣的套件,但是卻需要重新打包 Image 了。
同理,如果今天是 Container 向掛載的目錄儲存檔案,也可以在本機掛載的目錄找到檔案。
那麼就先到這邊,各位切記 Container 如果重啟會將所有上次運行所儲存的檔案全部砍掉(說砍掉不正確,但可以這麼理解), Volume 可以在你意想不到的時候就你一命。
大家掰~掰~