Docker+Gunicorn+Nginx部署Flask後端
tips:
- 本文主要介紹如何在docker中部署Flask APP
- 代碼倉庫
背景
- Flask自帶的服務啓動,非常方便在開發環境中調試使用,但是用於生產環境卻不是好的選擇。
- 一般生產環境中部署Flask都是基於WGSI容器。
- 生產環境可以用python的虛擬環境來部署Flask,但是部署方式比較麻煩,且不易移植。
Gunicorn
Gunicorn "綠色獨角獸"是一個Python WSGI UNIX的HTTP服務器。這是一個預先叉工人模式,從Ruby的獨角獸(Unicorn )項目移植。Gunicorn服務器大致與各種Web框架兼容,只需非常簡單的執行,輕量級的資源消耗,以及相當迅速。Gunicorn直接用命令啓動,不需要編寫配置文件,相對uWSGI要容易很多。官網
Docker
Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及應用運行的上下文環境到一個可移植的鏡像中,然後發佈到任何支持Docker的系統上運行。 通過容器技術,在幾乎沒有性能開銷的情況下,Docker 爲應用提供了一個隔離運行環境。
Docker有以下幾個有點:
- 簡化配置
- 代碼流水線管理
- 提高開發效率
- 隔離應用
- 快速、持續部署
Flask
一、測試Flask App
- 服務器(ubuntu)中新建文件夾
sudo mkdir /projects/FlaskTest
。 - 進入文件夾
cd /projects/FlaskTest
。 - 新建文件
app.py
,寫入內容。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'hello world'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80,)
gun.conf
# 並行工作進程數
workers = 2
# 指定每個工作者的線程數
threads = 4
# 監聽內網端口80
bind = '0.0.0.0:80'
# 工作模式協程
worker_class = 'gevent'
# 設置最大併發量
worker_connections = 2000
# 設置進程文件目錄
pidfile = 'gunicorn.pid'
# 設置訪問日誌和錯誤信息日誌路徑
accesslog = 'gunicorn_acess.log'
errorlog = 'gunicorn_error.log'
# 設置日誌記錄水平
loglevel = 'info'
# 代碼發生變化是否自動重啓
reload=True
二、編寫Dockerfile
在FlaskTest
目錄中新建Dockerfile
文件,寫入內容。
FROM python:3
MAINTAINER "username<usereamil>"
ENV PIPURL "https://pypi.tuna.tsinghua.edu.cn/simple"
WORKDIR /projects
COPY app.py app.py
RUN pip --no-cache-dir install -i ${PIPURL} --upgrade pip
RUN pip --no-cache-dir install -i ${PIPURL} gunicorn==19.9.0
RUN pip --no-cache-dir install -i ${PIPURL} flask==1.0.2
RUN pip --no-cache-dir install -i ${PIPURL} gevent==1.4.0
CMD gunicorn -c gun.conf app:app
說明
Dockerfile 文件是用於定義 Docker 鏡像生成流程的配置文件,文件內容是一條條指令,每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建;這些指令應用於基礎鏡像並最終創建一個新的鏡像,可以認爲用於快速創建自定義的Docker鏡像。
1.FORM
指定基礎鏡像(必須有的指令,並且必須是第一條指令)
2.MAINTAINER
用於提供信息的指令,用於讓作者提供本人的信息;不限制其出現的位置,但建議緊跟在FROM之後
格式:
MAINTAINER <name>
3.ENV
設置環境變量,可以在RUN之前使用,然後RUN命令時調用,容器啓動時這些環境變量都會被指定
格式:
ENV <key> <value> 一次定義一個變量
ENV <key>=<value> ... 一次可定義多個變量
4.WORKDIR
WORKDIR指令可以來指定工作目錄(或者稱爲當前目錄),以後各層的當前目錄就被改爲指定的目錄,如果目錄不存在,WORKDIR會建立目錄
格式:
WORKDIR <工作目錄路徑>
5.COPY
格式:
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
COPY 指令將從構建上下文目錄中 <源路徑> 的文件/目錄複製到新的一層的鏡像內的 <目標路徑> 位置
6.RUN
用於執行命令行命令
格式:
RUN <命令>
7.CMD
類似於RUN指令,用於運行程序;但二者運行的時間點不同;CMD在docker run時運行,而非docker build
三、構建鏡像
FlaskTest目錄下執行 sudo docker build . -t=flask-test:latest
命令,該命令作用是創建/構建鏡像,-t
指定名稱及版本號flask-test:latest
,點 .
構建內容爲當前上下文目錄。大致執行內容如下輸出
Sending build context to Docker daemon 4.096kB
Step 1/10 : FROM python:3
...
Step 2/10 : MAINTAINER "username<usereamil>"
...
Step 3/10 : ENV PIPURL "https://pypi.tuna.tsinghua.edu.cn/simple"
...
Step 4/10 : WORKDIR /projects
...
Step 5/10 : COPY . .
...
Step 6/10 : RUN pip --no-cache-dir install -i ${PIPURL} --upgrade pip
...
Step 7/10 : RUN pip --no-cache-dir install -i ${PIPURL} gunicorn==19.9.0
...
Step 8/10 : RUN pip --no-cache-dir install -i ${PIPURL} flask==1.0.2
...
Step 9/10 : RUN pip --no-cache-dir install -i ${PIPURL} gevent==1.4.0
...
Step 10/10 : CMD gunicorn -c gun.conf wsgi_gunicorn:app
...
Successfully built 277d7a1a9f4e
Successfully tagged flask-test:latest
四、查看鏡像
控制檯執行命令sudo docker images
查看所有的鏡像,確認構建的 flask-test:latest
鏡像是否存在
REPOSITORY TAG IMAGE ID CREATED SIZE
flask-test latest 277d7a1a9f4e 13 minutes ago 965MB
python 3 59a8c21b72d4 2 weeks ago 929MB
...
五、創建並啓動容器
- 控制檯執行命令
sudo docker run -d -p 8000:80 flask-test:latest
- 控制檯執行
sudo curl http://127.0.0.1:8000
返回hello world
- 控制檯執行
sudo docker ps
查看啓動的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47e55887d773 flask-test:latest "/bin/sh -c 'gunicor…" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp unruffled_zhukovsky
-d
後臺守護模式-p
指定容器與宿主機端口映射
六、更優雅的啓動容器,使用docker-compose
- 編寫
docker-compose.yaml
文件
version: "2"
services:
flask_test:
image: flask-test:latest
build: .
container_name: flask_test
restart: always
ports:
- "8000:80"
docker-compose up -d
啓動容器sudo docker ps
驗證容器flask_test
是否啓動- version:docker-compose的版本
- services:需要管理的服務
- flask_test:FlaskApp服務名稱
- image:FlaskApp服務鏡像來源
- build:如果鏡像不存在,當前位置構建鏡像。存在則跳過
- container_name:啓動的容器名稱
- restart:容器啓動屬性, always一直重啓
- ports:容器與宿主機的端口映射
Nginx配置
- 安裝好nginx之後,執行命令
cd /etc/nginx/conf.d
進入到conf.d
目錄 - 新建
flask_test.conf
文件並填入以下內容
server {
listen 80;
server_name www.qinzhiqian.xyz;
# api代理轉發
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8000;
}
}
sudo service nginx reload
總結
- 本文將Flask部署在docker容器中,Flask優化部署相關的內容參考Flask後端實踐 番外篇 Docker部署優化
- 下一篇文章將介紹Flask-APScheduler定時任務與坑點解決方法