本文首發於微信公眾號:Hunter後端
原文連結:Docker筆記三之執行Django系統
這一篇筆記介紹一下如何使用 Docker 執行 Django 系統。
流程大概是這樣,拉取一個 python 映象,然後將我們的 Django 系統放到該映象中構建一個新的映象,執行新映象產生的容器就有我們的 Django 服務了。
以下是本篇筆記目錄:
- 映象和系統準備
- Dockerfile 準備
- 構建映象
- 執行容器
- 其他Dockerfile命令
1、映象和系統準備
映象拉取
首先我們需要準備一個 Python 3.6 的映象,用於後面構建我們的 Django 映象。
透過下面的命令拉取:
docker pull python:3.6
然後透過 docker images
可以看到在 REPOSITORY 下名一個 python, TAG 為 3.6 映象
Django 系統準備
根據隔壁 Django 筆記,我們可以建立一個新系統,也可以用自己的專案系統,這裡我們命名為 hunter,放在 ~/ 目錄下,這個目錄地址可以自定義
python 依賴準備
然後準備一個 requirements.txt,這包含了我們執行系統所需要的全部依賴,可以在我們建立的 Django 系統下透過 pip freeze 命令獲得:
pip3 freeze > requirements.txt
requirements.txt 這個檔案我們也放在 ~/ 目錄下
2、Dockerfile 準備
然後我們需要新建一個 Dockerfile 檔案,這個檔案的作用是依據我們寫好的命令,在一個基礎映象上將我們需要執行的 Django 系統或者其他系統傳到映象裡成為一個新的映象
我們建立的 Dockerfile 也放在 ~/ 目錄下
FROM python:3.6
RUN mkdir /hunter -p
WORKDIR /hunter
ADD ./requirements.txt /hunter
RUN cd /hunter
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
ADD ./hunter /hunter
CMD ["python3", "manage.py", "runserver", "0:9898"]
- FROM 構建新的映象的基礎映象,即使用哪個指定的映象作為基礎來構建新的映象
- ADD 複製指令,類似於 COPY 指令,在這裡,使用 COPY 指令也可以,不同點在於對壓縮檔案的處理
- RUN 執行指令,在構建新映象的時候執行
- CMD 也是執行指令,不過是在容器執行的時候執行,相當於是容器啟動時的預設指令
- WORKDIR 指定工作的目錄,在容器執行起來後,使用命令進入容器,預設進入的也是 WORKDIR 的目錄
所以我們上面的 Dockerfile 的內容是:
- FROM 命令:在 python:3.6 的基礎映象上操作
- RUN 命令:在映象內建立 /hunter 資料夾
- WORKDIR 命令:指定映象內工作目錄為 /hunter
- ADD 命令:將宿主機的 requirements.txt 檔案複製到映象內 /hunter 目錄下
- RUN 命令:在映象內進入 /hunter 資料夾下
- RUN 命令:在映象內根據 /hunter 資料夾下的 requirements.txt 檔案安裝 python 依賴
- ADD 命令:將宿主機的 Django 系統檔案整個複製到映象內的 /hunter 資料夾下
- CMD 命令:指定容器啟動時執行的命令
以上命令在我們構建映象的時候會依次執行。
注意: CMD 指定的程式會被 docker run 的時候後面新增的程式指令覆蓋
與 CMD 還有個作用類似的命令,ENTRYPOINT,這個用法後面再介紹
就此,我們構建新映象的步驟和命令就此指定了。
3、構建映象
接下來的操作就是根據 Dockerfile 構建一個新映象
進入 ~/ 資料夾下,有以下幾個檔案及資料夾:
hunter/
requirements.txt
Dockerfile
基本的命令如下:
docker build . -t tag -f Dockerfile
-t 參數列示構建新映象時手動打的一個 tag
-f 表示指定的 Dockerfile 檔案,如果不使用 -f 引數,會預設尋找當前資料夾的 Dockerfile
接下來我們打一個 tag 為 Django:1.0.0 的映象,使用前面我們建立的 Dockerfile
docker build . -t django:1.0.0 -f Dockerfile
在這裡 -f 引數可以不新增,因為會預設使用當前資料夾的 Dockerfile 檔案
可以看到下面這種類似的輸出內容:
Step 7/8 : ADD ./hunter /hunter
---> 84a62ad79b51
Step 8/8 : CMD ["python3", "manage.py", "runserver", "0:9898"]
---> Running in 33bcc53af8cf
Removing intermediate container 33bcc53af8cf
---> 926fce7b8cea
Successfully built 926fce7b8cea
Successfully tagged django:1.0.0
然後使用 docker images
命令可以看到有一個 django:1.0.0 的映象了。
4、執行容器
接下來我們可以根據 image id 或者 django:1.0.0 這個 tag 來執行容器:
docker run -p 9898:9898 django:1.0.0
然後當前介面會顯示 Watching for file changes with StatReloader 這種資訊
然後訪問我們的系統 localhost:9898 類似這種,在當前介面就會輸出相應的訪問資訊
而如果我們想要停止執行這個容器,可以在新開一個shell,透過 docker ps 找到正在執行的容器,然後 docker stop xxxx停止或者直接在當前介面 ctrl + c
在後臺執行這個容器可以如下操作:
docker run -itd -p 9898:9898 django:1.0.0
在這裡我們使用 -p 引數將容器的 9898 埠對映到宿主機的 9898 埠
注意: 為了以示區分,假設埠對映為 -p 5678:9898,前面的 5678 是宿主機的埠,後面的 9898 是容器內的埠
在容器執行起來之後,如果想進入該容器,可以 透過 docker ps 找到這個執行的容器,然後 使用下面的命令進入容器內檢視
5、其他Dockerfile命令
除了在前面介紹的 Dockerfile 命令,還有掛載的命令 VOLUME,埠宣告的命令 EXPOSE,環境變數設定的命令 ENV,還有與 CMD 相似的指令執行的命令 ENTRYPOINT 等
EXPOSE
可用於宣告這個映象使用的埠,在執行的時候可以使用 -p 引數對映這個埠,但似乎並無太多實際意義,可以用於在 Dockerfile 中宣告,後期便於檢視
VOLUME
掛載的命令,我們可以在後面的執行 MySQL 映象的時候介紹
ENV
命令為環境變數,可以在構建映象的時候就指定變數,也可以在 執行容器的時候指定命令,可以直接在 Dockerfile 中如此宣告:
ENV key value
ENTRYPOINT
與 CMD 類似的作用,但 ENTRYPOINT 不會被容器啟動時的指定的指令覆蓋,而 CMD 命令會被覆蓋
比如:
docker run -itd image_id bash
這裡就指定了新的 CMD 命令為 bash,那麼原來的 CMD 命令就被覆蓋,不會執行了
如果想要覆蓋 Dockerfile 中的 ENTRYPOINT 命令,僅在容器 run 的時候,使用 --entrypoint 的引數,則會覆蓋 ENTRYPOINT 指定的程式
在 Dockerfile 中,如果存在多個 ENTRYPOINT 命令,僅最後一個生效,比如:
# Dockerfile
ENTRYPOINT ["python3", "manage.py", "runserver", "0:7979"]
ENTRYPOINT ["python3", "manage.py", "runserver", "0:9898"]
則系統會執行 最後一條,使用 9898 的埠
ENTRYPOINT 和 CMD 搭配使用
因為 entrypoint 不會被覆蓋,所以可以放入不會變的命令
而 CMD 會被後面的引數覆蓋,所以可以放入會被更改的資料,比如埠,或者其他會變的配置檔案位置
以 Django 系統為例,我們可以將 python3 manage.py 這兩個命令給 entrypoint,將埠的設定給 CMD,因為埠我們是可以更改的。
示例如下:
ENTRYPOINT ["python3", "manage.py", "runserver"]
CMD ["0:9898"]
然後我們重新構建映象,獲得新的 image_id,然後執行容器,加上 CMD 命令更換埠為 9999:
docker run -itd -p 9898:9999 image_id 0:9999
透過上面的命令將系統執行起來後,還是可以訪問宿主機的 localhost:9898,但是容器內部使用的埠已經變成了 9999
我們可以進入容器內部,檢視執行的程式,可以看到在容器內已經是 使用的 9999 埠在執行
docker exec -it container_id bash
ps aux
如果想獲取更多後端相關文章,可掃碼關注閱讀: