Flask後端:Docker+Gunicorn+Nginx部署

Docker+Gunicorn+Nginx部署Flask後端

tips:

  • 本文主要介紹如何在docker中部署Flask APP
  • 代碼倉庫

背景

  1. Flask自帶的服務啓動,非常方便在開發環境中調試使用,但是用於生產環境卻不是好的選擇。
  2. 一般生產環境中部署Flask都是基於WGSI容器。
  3. 生產環境可以用python的虛擬環境來部署Flask,但是部署方式比較麻煩,且不易移植。

Gunicorn

Gunicorn "綠色獨角獸"是一個Python WSGI UNIX的HTTP服務器。這是一個預先叉工人模式,從Ruby的獨角獸(Unicorn )項目移植。Gunicorn服務器大致與各種Web框架兼容,只需非常簡單的執行,輕量級的資源消耗,以及相當迅速。Gunicorn直接用命令啓動,不需要編寫配置文件,相對uWSGI要容易很多。官網

Docker

Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及應用運行的上下文環境到一個可移植的鏡像中,然後發佈到任何支持Docker的系統上運行。 通過容器技術,在幾乎沒有性能開銷的情況下,Docker 爲應用提供了一個隔離運行環境。
Docker有以下幾個有點:

  • 簡化配置
  • 代碼流水線管理
  • 提高開發效率
  • 隔離應用
  • 快速、持續部署

Flask

一、測試Flask App

  1. 服務器(ubuntu)中新建文件夾 sudo mkdir /projects/FlaskTest
  2. 進入文件夾 cd /projects/FlaskTest
  3. 新建文件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
    ...
    

    五、創建並啓動容器

    1. 控制檯執行命令sudo docker run -d -p 8000:80 flask-test:latest
    2. 控制檯執行sudo curl http://127.0.0.1:8000 返回hello world
    3. 控制檯執行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

    1. 編寫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配置

    1. 安裝好nginx之後,執行命令cd /etc/nginx/conf.d 進入到conf.d目錄
    2. 新建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;
        }
    }
    
  • 重啓nginx執行命令 sudo service nginx reload
  • 外網訪問配置好的url即可,例如:http://www.qinzhiqian.xyz
  • 總結

    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章