【筆記】將 Python File 打包成 Docker Image

前言

因為家人有個資料統計需求,不太碰後端的我臨時用了 python 寫了支簡單的爬蟲 + 資料處理;後來覺得既然都起了這個頭,那就順便再學一下用 flask 開發 api 吧;完成後想要部署到我的 server 上,又覺得那就再趁機學一下 Docker 吧(好幾年前有用 Docker 的 Laradock 建構論文用到的程式,但早已荒廢)。

我把 Docker 相關的步驟給筆記下來,給自己日後複習,有錯誤的地方也歡迎指教。以下介紹如何 build python docker image。

安裝 Docker

MacOS 用 brew 安裝,Ubuntu 用 apt-get 安裝:

# MacOS
$ brew update
$ brew cask install docker

# Ubuntu
$ sudo apt-get update
$ sudo apt-get install docker.io

安裝完成後,使用 groups 指令查看目前 user 是否有 docker group 權限:

$ groups
<your_user_name>

若沒有出現 docker,請輸入以下指令,避免每次都要打 sudo 才能執行 docker 指令:

$ sudo usermod -G docker -a <your_user_name>

執行完上述指令後,請重新登出後再次查看是否有出現 docker:

$ groups  
<your_user_name> docker

有出現 docker 代表成功,可以試著使用 docker version 指令查看目前版本,來確保 docker 指令運行正常:

$ docker version

將程式打包成 Docker Image

假設我要打包的是 test_api.py 這支 python 檔,我會先在 local 創建一個資料夾叫 test-docker,並在底下建立這些檔案:

test-docker
    app
        test_api.py # 欲打包的檔案
    Dockerfile # 先建立空檔案,等等撰寫內容

特別注意,python 檔要設定成 host 0.0.0.0 才可以被外部訪問,所以在 test_api.py 的 app.run() 加上如下參數:

if __name__ == '__main__':
    app.run(host='0.0.0.0')

接著要將本機的 python 環境列成清單,以讓 Dockerfile 可以依照這份清單建立 Image 的環境:

$ pip freeze > requirements.txt

這樣我們的 test-docker 資料夾底下就會有 requirements.txt 的檔案了。

test-docker
    app
        test_api.py
    Dockerfile
    requirements.txt

接下來要撰寫 Dockerfile,內容如下:

# Basic Image Environment
# 使用 slim 版本減輕 Image 容量
FROM python:3.9-slim

# 指定 Image 中的工作目錄
WORKDIR /code

# 將 Dockerfile 所在目錄下的所有檔案複製到 Image 的工作目錄 /code 底下
ADD . /code

# 在 Image 中執行的指令:安裝 requirements.txt 中所指定的 dependencies
RUN pip install -r requirements.txt

# Container 啟動指令:Container 啟動後通過 python 運行 test_api.py
CMD ["python", "./app/test_api.py"]
python3.9python3.9-slimpython3.9-alpine
842MB118MB55.8MB
不同版本的 python 所佔的容量(參考來源:小惡魔-AppleBoy

這樣子打包的東西都準備好了,可以準備下一步驟。

建構 Docker Image

在 Dockerfile 所在目錄下執行:

$ docker build -t test-api:v1 .

-t 參數指定 Image 的名字(若沒有指定版號 :v1 則會變成 :latest)。除此之外,需特別注意指令最後還有一個 .。. 表示當前目錄,這裡指的是 Dockerfile 所在的目錄。

查看已建構好的 Docker Image 清單

$ docker image ls
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
test-api   v1    5e3bbceaf52a   2 minutes ago   452MB

執行 Docker Container

$ docker run -p <port> test-api:v1

接下來只要看到服務有正常運行就代表成功囉!

以下順便介紹如何刪除 Image 和 Container。

刪除 Image

首先需透過上面講過的 docker image ls 來找到欲刪除的 Image 的 ID,接著放入 docker rmi 指令中。

# 一次刪除一張
$ docker rmi <your_image_id>

# 一次刪除多張
$ docker rmi <your_image_id> <your_image_id> ...

若有其他 Container 正在使用欲刪除的 Image,則會出現以下錯誤:

Error response from daemon: conflict: unable to delete <image_id> (must be forced) - image is being used by stopped container <container_id>

刪除 Container

可以透過上面錯誤訊息提到的 container_id 直接刪除,也可以使用 docker ps -a 來查看現有 Container。

有了 Container ID 後即可下停用及刪除指令:

$ docker stop <container_id>
$ docker rm <container_id>

參考資料

5 2 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments