使用 Docker 部署測試用的 Django 網站

當我們在自己的電腦中完成了一個Django的專案之後,通常都會使用 python manage.py runserver 在自己的電腦中測試,此時如果你需要把網站打包給別人使用,或是暫時不考慮效率,只是想先放在伺服器上執行看看時,使用 Docker 會是一個最簡易的方法,因為你可以完全不用考慮目標作業環境是否能夠安裝你在網站中使用到的模組,我們只要把所有的環境以及網站通通包裝在同一個 image 中,然後就可以在任一個使用相同 CPU 架構下的 Docker 環境中執行。這篇教學就記錄了其中所需要的步驟。

不具永久儲存能力的網站操作步驟

假設你已經在自己的電腦中安裝了 Docker Desktop,而且可以順利地執行 docker 指令。

首先最重要的當然是你已經完成的 Django 網站,接著請在自己的網站根目錄下建立一個用來建立 Docker Image 的 Dockerfile,內容如下,檔名當然要叫做 Dockerfile(請留意大小寫要一樣):

FROM python:3.10.13-slim

COPY . /

WORKDIR /

RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

然後,就可以在你的命令提示字元下執行以下的指令:

docker build -t docker-django-mychart:slim .

後面那個句點不能忘了,它是用來找到 Dockerfile 的關鍵。由於Docker需要到網路上下載許多的資料,所以執行的時間和你的網路速度有一定的關係。完成之後,就會在系統中建立一個叫做 docker-django-mychart 的映象檔,執行 docker images 指定即可查看,如下所示(其中 G:\demo\mychart)即為我們設計的網站專案:

 G:\demo\mychart>docker images
REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
docker-mychart   slim      eda586e33de4   47 minutes ago   704MB

這時候,我們只要使用以下的指令,就可以把網站映像檔變成Docker的容器,在Docker的環境中執行:

docker run -d -p 8000:8000 docker-mychart:slim 

然後利用 docker ps 指令,即可觀察這個容器在 Docker 中的執行狀態,如下圖所示:

此時,利用瀏覽器,瀏覽本機的 IP,也就是 127.0.0.1:8000,就可以順利地瀏覽到這個網站的所有功能了。由於我們是把執行的IP設定為0.0.0.0,表示這個網站並不會綁定任一個特定的IP,所以把這個映像檔複製到任一個Docker環境下都是可以透過該環境的IP執行這個網站。

要把目前這個映像檔移到別台機器上執行,最簡單的方式就是把它push到DockerHub上,但是如果你沒有 Docker 的帳號,或是不想這麼做的話,也可以把系統中的映像檔儲存到磁碟機中,指令如下:

docker save -o mychart-image.tar docker-mychart:slim

上面這個指令它會把docker-mychart:slim這個image儲存成 mychart-image.tar,接著我們就可以把這個檔案複製到另外一台具有 Docker 環境的機器上,然後在那台機器上執行以下的指令就可以匯入這個映像檔了(Linux 或 Mac 作業系統)。

cat mychart-image.tar | docker load

如果是 Windows 的話,則是使用以下的指令:

type mychart-image.tar | docker load

完成上述指令之後,也是一樣,透過 docker images 指令就可以檢視匯入的成果了。有了映像檔,相信同學們一定也可以順利地在另外一台電腦的Docker環境中執行這個網站了。

具永久儲存能力的網站操作步驟

如同標題所暗示的,由於Docker的容器本身並不會把資料儲存在磁碟機上,因此一旦我們停止了容器的運作時,這個網站之前如果有上傳了什麼檔案或是在資料庫中記錄了什麼資料,都會隨著容器的停止而消失,當容器重新執行時,又回到了原來的狀態了。因此,對於需要記錄狀態或是提供使用者上傳資料或檔案的網站而言,上述的方法還需要再做一些設定。

先來看修改之後的Dockerfile:

FROM python:3.10.13-slim

COPY ./requirements.txt /requirements.txt

WORKDIR /

RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["bash", "-c", "cd data && python manage.py runserver 0.0.0.0:8000"]

和第一支 Dockerfile 最大的差異在於,在這個檔案中我們不再複製所有的檔案到容器中,而是只有複製 requirements.txt,以方便用來安裝模組而已。接著,在最後一行的指令中,我們利用 bash -c 這個指令,讓我們可以在容器的 Shell 中執行兩個指令,先是把目錄切換到 data 資料夾中,然後再到資料夾中去啟用網站。

我們這樣設計的目的是在於,把 data 這個資料夾保留下來,讓它可以掛載我們目前磁碟機上的網站專案,如此就可以利用磁碟機上的檔案來執行容器中的環境了。我們還是以如下的指令來產生映像檔。這次我們使用另外一個範例網站:

docker build -t docker-mytv:slim .

映像檔建立完成之後,就可以利用以下的指令來執行(一定要在mytv這個網站專案資料夾中執行,以下是在 Windows 作業系統下的命令提示字元執行的範例):

docker run -d -v %cd%:/data -p 8000:8000 docker-mytv:slim

如果你是在 Linux 作業系統或是Windows的PowerShell下執行的話,要使用以下的指令:

docker run -d -v ${PWD}:/data -p 8000:8000 docker-mytv:slim

如果你要同時執行兩個不同的網站的話,記得要的port number改為8001,避免埠號的重複。這兩個指令都是使用 -v 這個選項,把目前的資料夾掛載到容器中,讓容器中的程式可以執行到目前資料夾的內容,而這個資料夾的內容中就包含了所有網站專案的程式以及資料檔和資料庫等等。

也因為我們的容器在執行時是使用目前的資料夾內容,那也意味著,當你要在不同的電腦中使用這個容器執行網站時,除了映像檔要複製到目標伺服器之外,網站專案的資料夾也要一併過去,同時,在執行 docker run 指令時,也一定要在網站專案的資料夾中執行才行。

參考網站資料

上面這兩個範例網站可以從 GitHub 上複製下來作為練習的對象。網址如下:

mychart: https://github.com/skynettw/dj4-1-mychart/

mytv: https://github.com/skynettw/dj4-1-mytv/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *