Flask 项目打包 && 线上部署

本文涉及的相关技术:flask + gunicorn + gevent+ docker

本文图片已失效,推荐阅读:Flask 项目打包 线上部署 !!!

作者:小牛呼噜噜 ,首发于公众号小牛呼噜噜,系列文章还有:

  1. 聊聊x86计算机启动发生的事?
  2. Linux0.12内核源码解读(2)-Bootsect.S
  3. Linux0.12内核源码解读(3)-Setup.S
  4. 图解CPU的实模式与保护模式
  5. Linux0.12内核源码解读(5)-head.s
  6. Linux0.12内核源码解读(6)-main.c
  7. Linux0.12内核源码解读(7)-陷阱门初始化
  8. 图解计算机中断
  9. Linux0.12内核源码解读(9)-blk_dev_init和chr_dev_init
  10. 什么是系统调用机制?结合Linux0.12源码图解

图床简介

前端时间小牛不是写了个自用的图床,最近有闲暇的时候,迭代了一下,准备打包到服务器上

迭代内容是:之前只能从固定的文件夹中去读取图片,感觉太麻烦了,小牛在公司还用不了;目前还支持了 点击、拖拽、复制粘贴上传图片,并将本地的服务打包到服务器中,随时随地使用网页版图床

Flask代码

前期准备:flask+gevent+gunicorn 相关依赖都已安装好

app.py:

1
2
3
4
5
6
7
8
9
10
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
return 'hello docker&flask'

if __name__ == '__main__':
app.run(host='0.0.0.0')

因为举例子,所以项目没有采用blueprint 的方式去构建

python start.py 即可运行项目

host='0.0.0.0' 是因为笔者想在公网环境中访问,这样项目的路径ip就是当前服务主机的ip,不写的话只能通过127.0.0.1调用。

一般还有其他2种启动方式:

python -m flask run -p 8088 -h 127.0.0.2,这种可以指定项目启动时的ip和端口

flask run -p 8088 -h 127.0.0.2 纯flask启动,但作用和上面一种一样

上述启动方式,平时我们测试开发使用足以,但我们的程序一般得部署到服务器上,这样可就不够看了,我们要寻求更长久的真正的部署。这时 gevent+gunicorn的作用就来了

Gunicorn || gevent

Gunicorn: 是一个 UNIX 下的 WSGI HTTP 服务器 ,Flask应用是一个符合WSGI规范的Python应用,不能独立运行(类似app.run的方式仅适合开发模式), 处理高并发有所欠缺,需要依赖其他的组件提供服务器功能。通过优化 Gunicorn 配置提高性能

gevent:gevent一般搭配gunicorn来部署。gunicorn 默认使用同步阻塞的网络模型(-k sync),对于大并发的访问可能表现不够好,需要套一个gevent来增加并发量

docker: 近几年非常火的开源项目,核心功能容器,能够让开发者打包我们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。将项目与环境进行隔离

Flask部署关系图如下:

编写gunicorn配置文件

gunicorn.conf.py文件

sudo vim gunicorn.conf.py

添加代码:

1
2
3
workers = 5
worker_class = "gevent"
bind = "0.0.0.0:8080"

导出依赖

在app.py同级目录执行即可,将当前python环境的依赖全部写入requirements.txt 文件中,我们构建容器时,会去读取依赖配置

pip freeze > requirements.txt

编写dockerfile文件

这是最核心,也最容易出错的地方,笔者这边用的是最简单的写法,作为例子引入。详情可取查看官方文档

1
sudo vim Dockerfile  #创建文件
1
2
3
4
5
6
7
8

FROM python:3
MAINTAINER xiaoniuhululu
COPY requirements.txt ./
EXPOSE 5000
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]

简单解释一下参数:
FROM # 指明我们创建的镜像,所依赖的基础镜像,我们这边是python3

MAINTAINER # 维护者信息

COPY # 将宿主机的文件cp到创建的镜像当前路径下

EXPOSE ## 仅仅只是声明端口。
帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口

RUN # 你需要在创建镜像之前,需要执行的命令

CMD # 创建容器后执行的第一个命令,一般是启动命令

定制镜像

上述的步骤 无论你是在windows环境 还是linux都可以,但接下来我们后续步骤在服务器环境(linux,不太建议用windows服务器 太浪费资源了)中操作

在当前目录下 有dockerfile执行命令
docker build -t upload-picture-flask . //-t 镜像的名字及标签, . 表示 在当前目录下寻找dockerfile

然后倒杯咖啡,慢慢的等待,因为制作镜像的过程需要联网下载大量的包,非常耗时,说个小技巧如果你的项目所需的依赖非常大,很看网速,容易失败,这个时候你可以去下一个对应的docker镜像到本地,然后在dockerfile添加from docker-你需要的镜像,就是将这个依赖作为多个基础镜像 定制你的项目镜像

查看生成的镜像

1
docker images 

以守护程序创建并启动容器

1
docker run -d -p 5000:5000 --name flaskUploadPicture upload-picture-flask:latest

-p容器内外端口映射

--name flaskUploadPicture 指定别名

upload-picture-flask:latest 所依赖的镜像,即我们刚刚生成的

(复制命令容易出错,请手打命令)

查看所有容器运行状态:

docker ps -a

效果

如果不行的话,检查外部映射的端口服务器防火墙 是否放开

如果还是不行的话,我们以下操作来核实原因

docker logs 容器id 查看docker日志

docker exec -it 容器id /bin/bash 进入镜像内部

图床最终效果图:

目前由于服务器压力大,准备放开10个人名额,大家要是想体验一下该图床的,关注公众号小牛呼噜噜找到微信联系小牛即可


本篇文章到这里就结束啦,如果喜欢的话,多多支持,欢迎关注!