# 在 Docker 部署 Flask 應用程式 ## 建立應用程式 - 下面是簡單的應用程式範例 - 透過 Flask 建立一個 Web server - 監聽 port 3333 (port=3333) - 允許所有來自所有 IP(host='0.0.0.0') 的請求 - 在接下來的例子中,該程式碼將儲存在檔案 *./run.py* ```python from flask import Flask app = Flask(__name__) # 建立 app 物件 # 定義路由 當 URL 的路徑是 / 時執行 @app.route("/") def hello_world(): return "<h1>Hello, World!</h1>" # 回傳 HTML 字串 if __name__ == "__main__": # 監聽 port 3333 (port=3333) # 允許來自所有 interface 的請求 (host="0.0.0.0") app.run(port=3333, host="0.0.0.0") ``` ## 建立 Dockerfile - 在和應用程式同一層的目錄中,新增檔名為 *Dockerfile* 的檔案 - 加入以下內容並存檔 ```dockerfile FROM python WORKDIR /app COPY . /app/ RUN pip install flask EXPOSE 3333 CMD ["python3", "run.py"] ``` ### 選擇 Base Image - 選擇可以執行 Python 的 image,作為 base image,例如: - 在 Linux 的 image 中,加入 Python 執行環境 - 直接使用 Python 環境的 image 製作 - 用 `FROM` 關鍵字指定做為 base 的 image 名稱 ```dockerfile= FROM python ``` ### 指定應用程式在容器中的目錄 - 用 `WORKDIR` 指定容器中,存放應用程式檔案的目錄 - 容器啟動時,會切換到該目錄 - 此目錄的名稱和路徑可以自訂,本文以 */app* 為例 ```dockerfile= FROM python WORKDIR /app ``` ### 將應用程式檔案 Image 中 - 用 `COPY` 將應用程式的檔案從開發環境複製到 image 中 - 下例中, `COPY . /app/` 表示將目前目錄(*.*)中的所有檔案,加入 image 的 */app/* 目錄中 ```dockerfile= FROM python WORKDIR /app COPY . /app/ ``` ### Setup & Start - 寫 Docker File 前,要先知道怎麼執行應用程式 - 以上面 Flask 的例子來說: - Setup => 安裝 dependency (下載 Flask 套件) - `pip install flask` - Start => 啟動 Flask APP - `python ./run.py` - 安裝 dependency 應該是容器啟動前就要執行的,所以要用 `RUN` 執行 - 啟動 Flask APP 是容器啟動時要執行的 (可想成容器的進入點),所以要用 `CMD` 執行 - 例子中的應用程式使用 port 3333,所以要用 `EXPOSE` 指定容器要對外開放的 port ```dockerfile= FROM python WORKDIR /app COPY . /app/ RUN pip install flask EXPOSE 3333 CMD ["python3", "run.py"] ``` ## 建立 Image - 執行以下指令,讓 docker 根據 dockerfile 的內容建立 image ``` sudo docker build -t <img_name>:<tag> <path> ``` - `<img_name>`: 替換成自訂的 image 名稱,之後查看 image 時,會顯示該名稱 - `<tag>`: 自訂的"標籤名稱",查看 image 時會和 image 名稱一起顯示,可當作版本號 - `<path>`: 替換成要使用的 Dockerfile 所在的目錄 - 以下列條件為例: - 希望建立的 image 名稱為 **flask-demo** - tag 為 **1.0** - 使用目前目錄(以相對路徑表示即 *.*)底下的 Dockerfile - 則指令如下 ``` sudo docker build -t flask:1.0 . ``` - 用 `sudo docker image list` 確認 image 建立成功 ## 以新建的 Image 啟動 Container - 執行以下指令啟動容器 ``` sudo docker run -d -p <host_port>:<container_port> <img_name>:<tag> ``` - `-d`: 表示 detach,容器將在背景執行 - `-p`: 設定機器的 port 和容器的 port 該如何對應 - 當機器收到的封包是送往 `<host_port>`,該封包將被轉發到容器的 `<container_port>` - `<host_port>`: 可自訂,但不可使用已被其他程式使用的 port - `<container_port>`: 應設定成運行於容器中的應用程式所使用的 port - `<img_name>:<tag>`: 要使用的 image 名稱及其 tag - 以上述例子來說 - `<host_port>`: 這邊選用 3000 (可以選其他未被使用的 port) - `<container_port>`: 應用程式使用 3333,故設為 3333 - `<img_name>:<tag>`: 上一步驟中,建立的 image 為 `flask-demo:1.0` - 完整指令如下 ``` sudo docker run -d -p 3000:3333 flask-demo:1.0 ``` - 可以在img前面加 --rm 這個參數,讓在container結束時自動刪除 - 可用瀏覽器打開 http://<host\>:3000 確認是否成功 - `<host>` 請替換成運行 Docker 的電腦的 IP 或 domainname - 在linux中檢查port被使用情況 ``` sudo lsof -i :<port number> ``` - 刪除 container - 列出所有的 container ``` docker ps -a ``` - 刪除 container ``` docker rm <container id> ``` - 在刪除時跳出 cannot remove a running container是因為container還在運行,所以要先stop container後再刪除 ``` docker stop <container id> ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up