转:http://Python.jobbole.com/84286/

原文出处: Vladik   译文出处:开源中国   

我职业生涯的大部分都在使用微软的架构,最近我决定走出技术的舒适区,步入开源软件世界。我现在日常工作的项目是一个RESTful服务,这个服务需要在主流硬件上运行,且能够按照需要进行水平拓展。为完成这项工作我决定使用Flask和Nginx。Flask是一个轻量级的Python Web框架,Nginx是一个非常稳定的Web服务器,它们在廉价硬件平台上工作良好。

在这篇文章中我将指导你完成使用Nginx服务器托管Flask应用的安装、配置过程。我所使用的操作系统是Ubuntu 13.04。

前提条件

在我们开始安装Nginx及其他所需软件之前先安装一些前提软件。首先,我们需要PIP与virtualenv:

1
2
3
sudo apt-get install python-setuptools
sudo easy_install pip
sudo pip install virtualenv

使用apt-get安装Nginx的话,我们需要添加Nginx库到apt-get source中:

 
1
sudo add-apt-repository ppa:nginx/stable

注意:如果“add-apt-repository”命令在你的Ubuntu版本中不存在的话,你需要安装“software-properties-common”包,使用命令:sudo apt-get software-properties-common(感谢get_with_it在评论中提到)

升级已有的包,确保系统上有uWSGI所需的编译器和工具:

 
1
sudo apt-get update

Nginx

安装并运行Nginx:

 
 
1
2
sudo apt-get install nginx
sudo /etc/init.d/nginx start

Nginx是一个提供静态文件访问的web服务,然而,它不能直接执行托管Python应用程序,而uWSGI解决了这个问题。让我们先安装uWSGI,稍候再配置Nginx和uWSGI之间的交互。

 
 
1
sudo pip install uwsgi

里程碑 #1

打开浏览器访问你的服务器,你应该能看到Nginx欢迎页:

示例应用

我们将托管的应用是经典的“Hello, world!”。这个应用只有一个页面,已经猜到页面上将有什么内容了吧。将所有应用相关的文件存放在/var/www/demoapp文件夹中。下面创建这个文件夹并在其中初始化一个虚拟环境:

 
 
1
2
sudo mkdir /var/www
sudo mkdir /var/www/demoapp

由于我们使用root权限创建了这个文件夹,它目前归root用户所有,让我们更改它的所有权给你登录的用户(我的例子中是ubuntu)

 
1
sudo chown -R ubuntu:ubuntu /var/www/demoapp/

创建并激活一个虚拟环境,在其中安装Flask:

 
 
1
2
3
4
cd /var/www/demoapp
virtualenv venv
. venv/bin/activate
pip install flask

使用下面的代码创建hello.py文件:

 
 
1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def hello():
    return "Hello World!"
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080)

里程碑 #2

让我们执行我们刚创建的脚本:

 
 
1
python hello.py

现在你可以通过浏览器访问你服务器的8080端口,看,应用生效了:

注意:因为80端口已被Nginx使用,这里我使用8080端口。

现在应用是由Flask内置的web服务托管的,对于开发和调试这确实是个不错的工具,但不推荐在生产环境中使用。让我们配置Nginx来挑起这个重担吧。

配置Nginx

首先删除掉Nginx的默认配置文件:

 
 
1
sudo rm /etc/nginx/sites-enabled/default

注意:如果你安装了其他版本的Nginx,默认配置文件可能在/etc/nginx/conf.d文件夹下

创建一个我们应用使用的新配置文件/var/www/demoapp/demoapp_nginx.conf

 
 
1
2
3
4
5
6
7
8
9
10
11
12
server {
    listen      80;
    server_name localhost;
    charset     utf-8;
    client_max_body_size 75M;
 
    location / { try_files $uri @yourapplication; }
    location @yourapplication {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/demoapp/demoapp_uwsgi.sock;
    }
}

将刚建立的配置文件使用符号链接到Nginx配置文件文件夹中,重启Nginx:

 
 
1
2
sudo ln -s /var/www/demoapp/demoapp_nginx.conf /etc/nginx/conf.d/
sudo /etc/init.d/nginx restart

里程碑 #3

访问服务器的公共ip地址,你会看到一个错误:

别担心,这个错误是正常的,它代表Nginx已经使用了我们新创建的配置文件,但在链接到我们的Python应用网关uWSGI时遇到了问题。到uWSGI的链接在Nginx配置文件的第10行定义:

 
 
1
uwsgi_pass unix:/var/www/demoapp/demoapp_uwsgi.sock;

这代表Nginx和uWSGI之间的链接是通过一个socket文件,这个文件位于/var/www/demoapp/demoapp_uwsgi.sock。因为我们还没有配置uWSGI,所以这个文件还不存在,因此Nginx返回“bad gateway”错误,让我们马上修正它吧。

配置uWSGI

创建一个新的uWSGI配置文件/var/www/demoapp/demoapp_uwsgi.ini

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[uwsgi]
#application's base folder
base = /var/www/demoapp
 
#python module to import
app = hello
module = %(app)
 
home = %(base)/venv
pythonpath = %(base)
 
#socket file's location
socket = /var/www/demoapp/%n.sock
 
#permissions for the socket file
chmod-socket    = 666
 
#the variable that holds a flask application inside the module imported at line #6
callable = app
 
#location of log files
logto = /var/log/uwsgi/%n.log

创建一个新文件夹存放uWSGI日志,更改文件夹的所有权:

 
 
1
2
sudo mkdir -p /var/log/uwsgi
sudo chown -R ubuntu:ubuntu /var/log/uwsgi

里程碑 #4

执行uWSGI,用新创建的配置文件作为参数:

 
 
1
uwsgi --ini /var/www/demoapp/demoapp_uwsgi.ini

接下来访问你的服务器,现在Nginx可以连接到uWSGI进程了:

我们现在基本完成了,唯一剩下的事情是配置uWSGI在后台运行,这是uWSGI Emperor的职责。

uWSGI Emperor

uWSGI Emperor (很拉风的名字,是不?) 负责读取配置文件并且生成uWSGI进程来执行它们。创建一个初始配置来运行emperor – /etc/init/uwsgi.conf

 
 
1
2
3
4
5
6
7
8
9
description "uWSGI"
start on runlevel [2345]
stop on runlevel [06]
respawn
 
env UWSGI=/usr/local/bin/uwsgi
env LOGTO=/var/log/uwsgi/emperor.log
 
exec $UWSGI --master --emperor /etc/uwsgi/vassals --die-on-term --uid www-data --gid www-data --logto $LOGTO

最后一行运行uWSGI守护进程并让它到/etc/uwsgi/vassals文件夹查找配置文件。创建这个文件夹,在其中建立一个到链到我们刚创建配置文件的符号链接。

 
 
1
sudo mkdir /etc/uwsgi

同时,最后一行说明用来运行守护进程的用户是www-data。为简单起见,将这个用户设置成应用和日志文件夹的所有者。

 
 
1
2
sudo chown -R www-data:www-data /var/www/demoapp/
sudo chown -R www-data:www-data /var/log/uwsgi/

注意:我们先前安装的Nginx版本使用“www-data”这个用户来运行Nginx,其他Nginx版本的可能使用“Nginx”这个替代用户

由于Nginx和uWSGI都由同一个用户运行,我们可以在uWSGI配置中添加一个安全提升项。打开uWSGI配置文件,将chmod-socket值由666更改为644

 
 
1
2
3
...
#permissions for the socket file
chmod-socket    = 644

现在我们可以运行uWSGI了:

 
 
1
sudo start uwsgi

最后,Nginx和uWSGI被配置成启动后立即对外提供我们的应用服务。

问题解决

如果出现错误的话,第一个检查的地方是日志文件。Nginx默认将错误信息写到/var/log/nginx/errors.log文件。

我们已经配置了uWSGI emperor将日志写到/var/log/uwsgi/emperor.log。这个文件夹还包含着每个配置应用的单独日志。我们的例子是 – /var/log/uwsgi/demoapp_uwsgi.log

静态文件

如果你的应用提供静态文件的话,将下面的规则添加到demoapp_nginx.conf文件:

 
 
1
2
3
location /static {
    root /var/www/demoapp/;
}

上面配置的结果就是所有在/var/www/demoapp/static文件夹中的文件将由提供Nginx对外服务(谢谢Bastianh指出)

托管多个应用

如果你想在一台服务器上托管多个Flask应用,为每个应用创建一个单独的文件夹,像我们前面所做的一样,创建Nginx及uWSGI配置文件到应用文件夹的符号链接。

使用Distribute部署应用

使用distribute部署Flask应用的话,首先,按照Flask文档里的步骤将应用转化成package,然后复制distribute通用安装包到服务器上,使用虚拟环境中的Python来安装它。如下:

 
 
1
python setup.py install

最后且同样重要的是,uwsgi配置里应用属性的值要设置成包含Flask应用的包的名称。

转:在 Ubuntu 上使用 Nginx 部署 Flask 应用的更多相关文章

  1. Ubuntu上通过nginx部署Django笔记

    Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式.今天在Ubuntu上使用Nginx部署Django服务,虽然不是第一次搞这个了,但是发现还是跳进了好多坑,g ...

  2. Ubuntu 14.04 上使用 Nginx 部署 Laravel

    本教程将会涉及以下工具: Ubuntu 14.04 LTS PHP 5.5 MySQL Laravel 5.0 Nginx 参考文章:Ubuntu 14.04 上使用 Nginx 部署 Laravel ...

  3. 通过Nginx部署flask项目

    用Flask开发之后,很多人,喜欢用nohup python manage.py & 这样的形式,放到后台运行,其实这样只是个发开模式,很简陋,无法支持并发,进程监控等功能.所以采用nginx ...

  4. Ubuntu下使用Nginx+uWSGI+Flask(初体验)

    Ubuntu 18.04,Nginx 1.14.0, uWSGI 2.0.17.1,Flask, 前言 Windows不支持uWSGI!为了上线自己的项目,只能选择Linux. 自己前面开发了一个Fl ...

  5. 怎么在linux ubuntu 上的nginx 绑定域名

    前一篇介绍了,如果在ubuntu上运行nodejs,毕竟访问的时候都是用ip地址+端口号,但是上production 环境都需要域名的,IP地址当然不行 读过上一篇的朋友知道了,如果在upstart ...

  6. Ubuntu 下使用 Nginx 部署 .NET Core 2.0 网站

    前言 本文介绍如何在 Ubuntu 16.04 服务器上安装 .NET Core 2.0 SDK.创建项目与发布,并使用 Nginx 部署 .NET Core 2.0 Web 项目. 安装 .NET ...

  7. 使用Flask+uwsgi+Nginx部署Flask正式环境

    环境准备 在开始正式讲解之前,我们将首先进行环境准备. Step1:安装Python,pip以及nginx: sudo apt-get update sudo apt-get install pyth ...

  8. 利用Docker Hub上的Nginx部署Web应用

    Docker Hub上提供了很多镜像,如Nginx,我们不需要自己从ubuntu开始装Nginx再做发布,只需要先下载镜像到本地 docker pull nginx 在/opt下新建文件夹API,将需 ...

  9. ubuntu下使用nginx部署Laravel

    问题描述 Laravel是PHP下当今最受欢迎的web应用开发框架,github上start数远超第二名Symfony,以前我用这个框架做项目的时候通常就是扔到apache里面,然后配置.htacce ...

随机推荐

  1. 如何卸载掉eclipse中的插件

    First-->Help->About Eclipse Second--> Third-->

  2. HTML入门(二)表格_字体_超链接_布局

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. BZOJ做题记录[0512~?]

    觉得做一道开一篇真不好...好多想找的东西都被刷下去了... 至于?的日期究竟到什么时候...还是看心情...但是估计不会超过七天吧 最后更新时间:05/19 10:42 [05/14 10:56]我 ...

  4. 【CodeForces】901 B. GCD of Polynomials

    [题目]B. GCD of Polynomials [题意]给定n,要求两个最高次项不超过n的多项式(第一个>第二个),使得到它们GCD的辗转次数为n.n<=150. [算法]构造 [题解 ...

  5. lintcode 443.岛屿的个数

    在v2ex上看到有人提到了这个,感觉挺简单的,没忍住还是试一下.... 基本的染色法. AC代码: public class Solution { /** * @param grid a boolea ...

  6. python3爬虫.3.下载网页图片

    目标,豆瓣读书, 下载页面书籍图片. import urllib.request import re #使用正则表达式 def getJpg(date): jpgList = re.findall(r ...

  7. python 输出 a+b

    AC代码: 单组输入: s=input().split() print(int(s[0])+int(s[1]))

  8. Linux下的压缩解压缩

    Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进  行压缩了,所以首先就来讲讲t ...

  9. linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4262445.html 操作系统:ubuntu10.04 前言:     在嵌入式开发中,只要是带操作系统的 ...

  10. tracert和traceroute使用

    Traceroute提取发 ICMP TTL到期消息设备的IP地址并作域名解析.每次 ,Traceroute都打印出一系列数据,包括所经过的路由设备的域名及 IP地址,三个包每次来回所花时间. 转自 ...