用docker部署flask+gunicorn+nginx

Posted 永远的幻想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用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个,第一个是全部代码,后面是3个conf文件,各挂到各自该去的地方。

唯一注意的是这种挂单文件的时候,冒号前后不能加空格,否则报错。(之前实验了绝对路径,加双引号。。。以为是yml版本太低…但都不对),现在这样写最简单。

 

现在这样启动之后,代码在host,用IDE修改代码,flask自动热更新,oyeah!

 

以上是关于用docker部署flask+gunicorn+nginx的主要内容,如果未能解决你的问题,请参考以下文章

Flask 学习-91.使用 gunicorn 部署 flask

flask中gunicorn的使用

Flask + Gunicorn + Nginx 部署

了解 Docker/Docker-Compose 上的 Gunicorn 和 Flask

Flask+Gunicorn+Gevent+Supervisor+Nginx生产环境部署

gunicorn部署Flask服务