网上找了许多讲关于Flask应用部署的文章几乎都是一个helloworld的Demo,按照helloworld来部署都没问题,但实际项目部署时还是遇到了不少问题。在这里简单写下自己成功部署的过程,防止下次部署时就忘记了,好记性不如烂笔头这句话不是盖的。


部署环境:

OS: Ubuntu 14.04.4 LTS
Python: 2.7.6
Nginx: nginx/1.4.6(Ubuntu)
uwsgi: 1.9.17.1-debian
supervisord: 3.0b2

这个署架构中Nginx主要作为前置服务器,负责分发处理来自客户端的请求,uwsgi作为后端Flask应用的容器,supervisor作为监控程序,即看门狗。

由于项目源码是直接放在阿里云服务器上(项目已开源http://github.com/yelongyu/chihu.git),所以这里省略了项目上传这一步,并假设已经安装好了Python开发环境,若未配置好Python开发环境,请先配置好,本文假设项目所在的位置为/home/chihu

环境配置:

sudo apt-get install uwsgi-plugin-python      # 这个不装的话当发起请求时uwsgi会报错

若是Python3的话改为:

sudo apt-get install uwsgi-plugin-python3

STEP 1: Nginx安装配置

安装Nginx

1. 输入Nginx安装命令

sudo apt-get install nginx

2. 启动Nginx服务器:

sudo service nginx start

启动Nginx服务器并用浏览器访问测试一下Nginx是否安装成功,若成功,进入下一步。

3. 配置Nginx

进入/etc/nginx/sites-enabled/文件夹 注意不是sites-available

直接配置/etc/nginx/nginx.conf也可以,不过要根据其语法来配置,其实最后nginx.conf还是会调用/etc/nginx/sites-enabled/default的配置。

  • 先将默认配置文件default备份(养成修改配置前先备份的习惯):
mv default default.bak
  • 编辑配置文件:
vim default
  • 写入配置内容:
server {
listen 80; # 服务器监听端口
server_name 110.110.110.110; # 这里写你的域名或者公网IP
charset utf-8; # 编码
client_max_body_size 75M; # 之前写的关于GET和POST的区别,这里应该是原因之一吧 location / {
include uwsgi_params; # 导入uwsgi配置
uwsgi_pass 127.0.0.1:8000; # 转发端口,需要和uwsgi配置当中的监听端口一致
uwsgi_param UWSGI_PYTHON /home/chihu/venv; # Python解释器所在的路径(这里为虚拟环境)
uwsgi_param UWSGI_CHDIR /home/chihu; # 项目根目录
uwsgi_param UWSGI_SCRIPT manage:app; # 项目的主程序,即Flask app所在的位置
}
}

输入:wq保存配置文件。配置好了之后别急着启动Nginx,记得先通过nginx -t测试一下配置文件是否正确,若检测配置文件失败,再好好检查下配置文件有没有疏漏。

此时访问Nginx服务器应该会得到502 Bad Gateway的提示,因为请求被Nginx转发了,但是并没有转发服务器来处理请求(还没有配置好uwsgi)。


STEP 2: uwsgi安装配置

安装uwsgi

sudo apt-get install uwsgi

编写uwsgi配置文件

在项目文件根目录新建配置文件uwsgi.iniuwsgi支持多种配置文件格式: xml, ini, json等)

vim uwsgi.ini

写入配置内容如下:

[uwsgi]                                                                        

socket = 127.0.0.1:8000             # uwsgi的监听端口                                              

plugins = python                    # 这行一定要加上,不然请求时会出现-- unavailable modifier requested: 0 --错误提示                                                   

chidir = /home/chihu                # 项目根目录                                           

wsgi-file = manage.py               # flask程序的启动文件                                           

callable = app                      # 程序变量名

输入:wq保存配置文件,可以通过uwsgi uwsgi.ini来启动uwsgi。


STEP 3: 启动及测试

Nginxuwsgi都配置好了之后下一步就是启动Nginxuwsgi了。

  • 启动Nginx
sudo service nginx restart
  • 启动uwsgi

    进入项目根目录,即uwsgi.ini所在的目录,执行以下命令。
uwsgi wsgi.ini

若一切正常的话就可以在终端上看到uwsgi的启动信息了。

测试:

打开浏览器访问服务器,若可以正常访问,说明Nginxuwsgi配置成功了,但离真正项目上线还差一段,因为uwsgi是直接在前台启动的,当我们的连接终端跟服务器断开的时候uwsgi进程也被关闭了,所以我们需要让uwsgi在后台运行。

STEP 4: 进程监控

原本打算用uwsgi emperor的方式运行uwsgi即让uwsgi成为守护进程(daemon),但是折腾了一天还是没解决问题,遂换supervisor。(折腾uwsgi emperor到后面发现问题是,当单独使用uwsgi的时候一切正常,但一使用uwsgi emperor就会出现os.environ.get()获取不到环境变量的问题,但环境变量明明可以通过env看到,直接在Python终端上执行os.environ.get()也可以获取到.....等有时间再回过头了折腾。)

单独一个uwsgi程序运行短时间可能没问题,但是网络状况瞬息万变,万一uwsgi进程挂了网站也就访问不了了.....为了防止出现意外情况,还需要一个监控程序来监控uwsgi的状况,这里该supervisor出场了。具体什么是supervisor可以Google之。

1. 首先安装supervisor

sudo apt-get install supervisor

2. 生成默认配置文件

echo_supervisord_config > supervisord.conf

3. 加入监控程序的配置

[program:project_name]          # project_name这里写上你的项目名称,如我的为[project:chihu]
command = uwsgi --ini /home/chihu/uwsgi.ini # 跟手动启动的命令一样
stopsignal=QUIT
autostart=true
autorestart=true
stdout_logfile=/var/log/uwsgi/supervisor_chihu.log # 运行日志
stderr_logfile=/var/log/uwsgi/supervisor_chihu_err.log # 错误日志

4. 启动supervisord

supervisorctl reload

5. 检查uwsgi进程是否正常运行

ps aux|grep uwsgi

如果一切正常,此时应该可以看到uwsgi进程

尝试kill掉uwsgi进程看supervisor会不会重新启动一个新的uwsgi进程

sudo killall uwsgi

若再次通过ps aux|grep uwsgi查看发现有新的uwsgi进程在运行,那差不多可以祝你成功了, God bless you。

ERROR

supervisorctl reload

提示错误

error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 224

issue

只需手动启动supervisord即可:

sudo supervisord -c configfile.conf

这里涉及到一个启动程序的用户的问题,好几次莫名不能通过os.environ.get()到系统中的环境变量,导致程序出错。一步一步排查猜测是因为启动程序的用户不匹配的问题,遂将启动程序的用户从root改为普通的登陆用户,问题解决,但这里还有疑问,因为环境变量是设置在/et/environment当中的,按理这里设置的应该是全局都可以访问的环境变量,但是当用root用户启动程序时就不能访问到环境变量,为了这个问题折腾了好几天,总算解决了,但是当中的疑惑还是需要好好思考探索。


后记:

折腾了两天终于搞定,有时候教程看着简单,你的配置也和教程一样,但就是由于各种错误无法运行,虽然说计算机非0即1,是我们人类最忠实可靠的伙伴,但是有时候就差那么一点点,有可能是软件环境不对亦或是我们电脑的打开方式不对...总之,就是要有那么个折腾的过程,所谓吃一堑长一智,不折腾折腾估计过后就忘了怎么回事了,还是要勤动手不放弃,虽然被一个uwsgi emperor折腾得快要怀疑人生了,但我还是坚定不移地...改道supervisor了 :)

初次写教程,文中可能有疏漏或写得不够恰当的地方,还请各位看官多多包涵,欢迎指正和交流。如果部署的过程中有问题也欢迎留言,虽然不能保证可以解决。

-EOF-

参考:

https://segmentfault.com/a/1190000004294634 # uwsgi及Nginx配置

http://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/#comment-2401229330 # uwsgi emperor

http://letgoof.me/2013/deploy-django-project-with-uwsgi-nginx-and-supervisor/ # supervisor配置

http://liyangliang.me/posts/2015/06/using-supervisor/ # supervisor & supervisord

Python基础 - Ubuntu+Nginx+uwsgi+supervisor部署Flask应用的更多相关文章

  1. flask部署:Ubuntu下使用nginx+uwsgi+supervisor部署flask应用

    之前一直用的Centos或者Red hat,自从使用Ubuntu后,发现Ubuntu使用起来更方便,自此爱上Ubuntu. 一.从github上下载flask应用 1.我已经成功将自己编写好的应用上传 ...

  2. flask +gevent+nginx+Gunicorn+supervisor部署flask应用

    上篇   可以完美部署flask ,但是视乎在结合gevent+apscheduler 实现异步非阻塞后台和定时任务的时候视乎不是那么完美.请教了前辈,决定使用flask+gevent+nginx+g ...

  3. CentOS 下部署Nginx+Gunicorn+Supervisor部署Flask项目

    原本之前有一部分东西是在Windows Server,但是由于Gunicorn不支持Windows部署起来颇为麻烦.最近转战CentOS,折腾一段时间,终于简单部署成功.CentOS新手,作为一个总结 ...

  4. Nginx+Gunicorn+Supervisor部署Flask应用

    Flask 内置了简单的 Web 环境,让我们在开发的时候只需要专注于应用实现,而真正要在生产环境运行时这个简单的 Web 环境就不够用了,还需要一系列操作才能让 Web 应用高效的运行起来.现在记录 ...

  5. ubuntu NGINX uwsgi https 部署Django 遇到的问题

    搞了3天终于把Django成功部署到Ubuntu,记录一下: 引用来自泡泡茶壶: Ubuntu下的Nginx + Uwsgi + Django项目部署详细流程 前提说明: Django作为小程序的后端 ...

  6. Nginx+uwsgi+supervisor+Ubuntu+flask

    Nginx+uwsgi+supervisor+Ubuntu+flask Nginx+uwsgi+supervisor在Ubuntu上部署flask应用 网上找了许多讲关于Flask应用部署的文章几乎都 ...

  7. [技术博客]ubuntu+nginx+uwsgi+Django+https的部署

    ubuntu+nginx+uwsgi+Django+https部署文档 配置机器介绍 操作系统:Ubuntu 18.04.2 LTS 64位 python版本:Python 3.6.7 Django版 ...

  8. flask+uwsgi+supervisor部署流程

    背景: 小鱼最近搞了个工程,python用的2.7(用3也可以),后端使用的是flask,服务器用的linux,使用 flask+uwsgi+supervisor部署 ,查阅相关博客.调试.实操,已经 ...

  9. ubuntu+nginx+uwsgi部署django web项目

    前言 将本地开发的django项目部署至linux上的uwsgi服务器,并配置nginx,完成基于ubuntu+nginx+uwsgi的上线运行.下面整理相关步骤. 服务器配置virtualenv 如 ...

随机推荐

  1. bzoj 3672 购票 点分治+dp

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1177  Solved: 562[Submit][Status][ ...

  2. 【agc001d】Arrays and Palindrome

    Portal -->agc001D Description 给你一个\(m\)个数的排列\(A\),这个\(A\)中元素的顺序可以随便调换,\(A\)中的元素的和为\(n\),现在要你构造一个数 ...

  3. Jenkins(二)---jenkins之Git+maven+jdk+tomcat

    git+maven+jdk+tomcat  这四个软件可以百度在linux下的安装,不再赘述. server A --->   jenkins主机ip:192.168.100.119 serve ...

  4. bzoj1874 [BeiJing2009 WinterCamp]取石子游戏

    1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 925  Solved: 381[ ...

  5. bzoj 1798 线段树

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7163  Solved: 2587[Submit ...

  6. P1075 质因数分解

    P1075 质因数分解 题目描述 已知正整数 n 是两个不同的质数的乘积,试求出两者中较大的那个质数. 输入输出格式 输入格式: 一个正整数 n . 输出格式: 一个正整数 p ,即较大的那个质数. ...

  7. Liunx常用命令(Mile)

    记录一些平时经常用到的liunx命令,解决用过一段时间不用又忘记的问题.慢慢添加,持续更新~~~ 1.文件操作 a.zip.war包解压 war包 用的zip的方式压缩 ,也可以用的zip的 解压命令 ...

  8. StringBuffer类和String 类的 equals 和 ==

    注意: equals(Object obj)equals方法的参数是任意对象 Object类的equals方法就是用==判断的,即判断两个对象是否为同一个对象 StringBuffer类没有重写equ ...

  9. HDU 1160 FatMouse's Speed (最长上升子序列)

    题目链接 题意:n个老鼠有各自的重量和速度,要求输出最长的重量依次严格递增,速度依次严格递减的序列,n最多1000,重量速度1-10000. 题解:按照重量递增排序,找出最长的速度下降子序列,记录序列 ...

  10. 天梯赛 L2-023. (模拟) 图着色问题

    题目链接 题目描述 图着色问题是一个著名的NP完全问题.给定无向图 G = (V, E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解决这 ...