用docker部署flask+gunicorn+nginx


說來慚愧,寫了好幾個flask django項目都是在原型階段直接python app.py 運行的,涉及到部署用nginx和gunicorn 都是讓別人幫我部署的,據說好像說很麻煩的樣子,我就沒自己做。

現在自己有時間了,搞了一下,發現也沒什么復雜的,花半天搞定。哞哈哈哈。

心得:

       1 不要怕。(要么怕滿屏洋文,要么怕新知識新技術一個坑接一個坑。其實比看論文/寫論文容易多了吧!)因為怕而逃避,拖延,最要不得

       2 不要自己zuan3。技術問題如果路數不對,可能很吃時間,搞N天搞不定;但其實都是一層窗戶紙。

         不是搞科研,犯不上自己再發明一遍輪子耽誤時間。其實搞研究一樣要多讀別人的文獻,技術就更需要多讀多練了。空想空談的“空疏”,比學了一堆技能的“支離”更要不得。

          1 完全不懂的技術框架,有官方文檔看官方文檔和demo

          2幾種自己不太懂的技術配合的解決方案組合問題,如“OO+XX”這種:先去github找現成的solution

          3 1和2照做中,遇到具體問題,先stackoverflow,沒有再google

     要善於借助外網的力量,並形成習慣。

 

github上有現成的demo,還是比較容易的。我fork下來,又稍微修改了幾點,厚臉皮pull request了。

dockerfile 使用python官方鏡像

# nginx-gunicorn-flask with python3

FROM python
LABEL author=""
LABEL purpose = ''


RUN apt update
RUN apt install -y nginx supervisor
RUN pip3 install gunicorn
RUN pip3 install setuptools

ENV PYTHONIOENCODING=utf-8

# Build folder
RUN mkdir -p /deploy/app
WORKDIR /deploy/app
#only copy requirements.txt.  othors will be mounted by -v
COPY app/requirements.txt /deploy/app/requirements.txt
RUN pip3 install -r /deploy/app/requirements.txt

# Setup nginx
RUN rm /etc/nginx/sites-enabled/default
COPY nginx_flask.conf /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-available/nginx_flask.conf /etc/nginx/sites-enabled/nginx_flask.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf

# Setup supervisord
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY gunicorn.conf /etc/supervisor/conf.d/gunicorn.conf

# run sh. Start processes in docker-compose.yml
#CMD ["/usr/bin/supervisord"]
CMD ["/bin/bash"]

和原作者不同的幾處修改,說明一下:

官方源現在也可以apt update 也帶了pip3了,只不過setuptools還是要手動裝(MD都裝利索了會死啊),就沒必要自己用ubuntu裝python3.6了

dockerfile語法有些過時了,改成LABEL author了

把gunicorn改成了用pip3安裝,而不是apt安裝,否則,用supervisord運行,會報錯:

gunicorn gunicorn (exit status 1; not expected)

或者

FATAL Exited too quickly (process log may have details)

原作者是在build鏡像的時候把代碼全都COPY進去了,我改成只copy  requirements.txt 用於安裝python包就可以了。代碼之類的我還是喜歡用-v掛載。

結尾,把 supervisord 改成bash。因為難免要調試一下。這樣起container之后,attach進去可以手動啟動flask。

把自動的supervisord 放在docker-compose.yml里,更靈活一些。

 

幾個配置文件,其實沒有太多可說的:

nginx_flask.conf

server {
    listen      80;

    location / {
        proxy_pass http://localhost:5000/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ^~ /static/ {
        root /deploy/app/;
    }
}

照着別人的demo增加static(其實不加的話,是不是也能緩存呢?)

注意^~ 有空格 和路徑寫法  root /deploy/app/  不要多寫static

 Gunicorn.conf

[program:gunicorn]
command=gunicorn --workers=3 app:app -b localhost:5000
directory=/deploy/app

supervisord.conf

[supervisord]
nodaemon=true

[program:nginx]
command=/usr/sbin/nginx

然后,用docker-compose管理容器

docker-compose.yml

version: "3.3"

services:
  api:
    #restart: always
    stdin_open: true
    tty: true
    build: ./dockerfile
    image: nginx-gunicorn-flask:latest
    volumes:
      - ./app:/deploy/app
      - ./nginx_flask.conf:/etc/nginx/sites-available/nginx_flask.conf
      - ./gunicorn.conf:/etc/supervisor/conf.d/gunicorn.conf
      - ./supervisord.conf:/etc/supervisor/conf.d/supervisord.conf
    ports:
      - "80:80"
    #command: '/bin/bash' 
    command: '/usr/bin/supervisord'

如果是調試,不希望自動運行,就把最后一句command注釋了。啟動之后attach進去

4個掛載點,第1個是全部代碼;后面是3個conf文件,各掛到各自該去的地方。

唯一注意的是這種掛單文件的時候,冒號前后不能加空格,否則報錯。(之前實驗了絕對路徑,加雙引號。。。以為是yml版本太低…但都不對),現在這樣寫最簡單。

 

現在這樣啟動之后,代碼在host,用IDE修改代碼后,容器里躲在Nginx和gunicorn之后的flask一樣自動熱更新,oyeah!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM