uWSGI+Nginx+Django配置总结(Ubuntu与Centos都可用)

1 篇文章 0 订阅
1 篇文章 0 订阅

环境:Centos7.5 或 Ubuntu16.04.6 如果配置中遇到了什么问题欢迎留言,随时修改博客中的问题,欢迎指正。我开启的80端口供nginx使用,8000端口供uwsgi使用。
框架:Django
说明:部分内容转载,特别感谢大佬的博客:https://blog.csdn.net/u012145252/article/details/82147440本文只是结合自身的实际情况做了一些记录,供学习使用。

正式将之前先说一下大概步骤,我们先将uwsgi与django服务配置好,再将nginx与uwsgi服务之间的联系给配置好,如果你在看这篇文章之前对于这三者的关系不太清楚的话也不要紧,耐心的看完你就明白了,现在开始之前,你只需要了解他们三者的这个配置顺序就行了。配置顺序不是固定的,本文以这种顺序进行配置,主要是为了方便调试与理解,现在我们开始!

一、 uWSGI部署

首先,需要在自己服务器中安装uwsgi,如果是在虚拟环境中使用,则安装在虚拟环境中,如果是直接配置在服务器上就直接安装:

pip3 install uwsgi

安装完成后可以使用uwsgi --version查看版本信息。

测试运行uWSGI

首先我们需要一个测试代码,来帮助我们走过测试这一关,以免直接使用庞大的网站源代码来配置。

在项目根目录创建一个test-uwsgi.py,代码如下,请注意函数名,必须为application,因为这是uwsgi服务默认通知Dajngo的接口。在我们自己经常使用的Django框架的wsgi.py的配置文件中也能看到。

def application(env,start_response):
    start_response('200 OK',[('Content-Type','text/html')])
    return [b"Hello Hero, all for one "]

以下命令表示运行uwsgi服务,同样是在8000端口上开放web访问。

  • 注意–http 后是一个空格再接:端口号。
uwsgi --http :8000 --wsgi-file test-uwsgi.py

访问web服务器8000端口,正常显示test-uwsgi.py脚本中返回显示的文本。

因为我们现在要做的是基于nginx和uwsgi部署django,从客户端发起请求到服务器响应请求,会经过一下几个环节:

the web client <-> the web server(nginx) <-> the socket <-> uwsgi <-> Django

而单独测试uWSGI运行,访问显示正常的话,说明下面3个环节是通畅的:

the web client <-> uWSGI <-> Python

ctrl+c中止程序,再来进行以下的测试。

使用uWSGI运行django项目

在虚拟环境下,进入到django根目录下后敲以下命令:

 uwsgi --http :8000 --module projectname.wsgi

效果和直接敲以下命令

python manage.py runserver 0.0.0.0:8000

是一样的。

说明:以上的projectname.wsgi是调用了项目根文件夹下的wsgi.py的网关服务配置文件,默认情况下是不需要用户进行更改的。Django的项目文件夹路径我就不哆嗦了,学过都知道,查一下也就大概了解了。因此必须要在项目的根目录执行该命令。

注:–module projectname.wsgi为加载指定的wsgi模块,你项目起的是什么名字,一般就是项目名.wsgi。
这样测试下来,可证明web客户端通过uWSGI到Django是通畅的:

the web client <-> uWSGI <-> Django

ctrl+c中止程序,再来进行以下的测试

uWSGi热加载Djangoa项目

在启动命令后面加上参数:

uwsgi --http :8000 --module pojectname.wsgi --py-autoreload=1

同样,这个时候访问服务器8000端口,也就是访问了django项目(pojectname)。

而且还多了一个参数:
--py-autoreload 监控python模块以触发重载(仅在开发中使用)

类似的发布命令

/..dir../uwsgi --http 0.0.0.0 :8000 --chdir /home/operation/work/luffy --module luffy.wsgi` 
 #此时修改django代码,uWSGI会自动加载django程序,页面生效 # 除此外,还可以接上很多参数

uwsgi部署加强

一、 使用uwsgi配置文件运行django项目

上面的配置都是属于测试阶段,如果测试一遍没有问题后,我们就可以进行系统的配置了。uwsgi支持ini,xml等多种配置方式,以ini为例,在项目根目录下新建uwsgi.ini,示例配置如下:

[uwsgi] #代表这里是uwsgi的配置文件,必须要写这个在第一行

# 指定运行目录,其实就是项目的根目录
# 导入django项目的wsgi模块,我的项目叫GradingSystem,其中application就是默认的网关配置文件的那个函数
module = GradingSystem.wsgi:application
dir=/web/GradingSystem
# 载入wsgi-file,这里是指明网关配置文件在项目文件夹下的路径
wsgi-file = GradingSystem/wsgi.py

# 补充,uwsgi启动时的用户和用户组,注意要按你自己的实际权限进行配置
# 我这边是因为项目属主是gxa,而gxa我设置了添加进了gxa组
# 但这种情况下uid仍不能设置gxa,除非你的项目目录所有文件属主都改为了gxa
uid = centos
gid = www

# 开启master主进程
master = true

# 开启多少个进程数,workers项也等同processes
# threads项则是设置运行线程,测试倒不用设置上线程
processes = 10

# 设置使用的socket端口或socket地址
# socket = 0.0.0.0:8000
# 上面的socket建议配置成一个GradingSystem.socket文件后使用nginx来连接uWSGI运行,不然容易报socket的请求头错误和权限错误等。
#socket = /web/GradingSystem/GradingSystem.socket

#以上信息来源于转载,是大佬博主的建议,但是我采用之后出现了网关错误的问题,可能是我哪里没有搞明白,但是换成下面的配置后就正常了,这个socket指定的端口代表的是uwsgi服务监听的端口

# 在配置uwsgi时,如果直接使用socket进行配置,那么浏览器无法通过http协议进行访问,必须在前面加上nginx转发才可以通过nginx间接访问,因此只测试uwsgi时使用http进行配置。
#socket = 0.0.0.0:8000
http = 0.0.0.0:8000

# 配置生成的sock文件的权限,一般对网站用户的权限都设置为如此,较为安全
chmod-socket = 664

# 退出时清空环境,其实就是将自动生成的GradingSyster.sock和相关pid文件给干掉。
vacuum = true

#设置uwsgi服务的缓存区大小
auffer-size = 65536


uwsgi指定配置文件启动django项目,建议使用web指定的用户执行:

uwsgi --ini /..dir../uwsgi.ini

(其中…dir…是项目在服务器上的路径)

二、 配置网站的用户组问题

首先强调一下,根目录权限设置的必要性:
为了安全,以及网站服务器的运行,我们需要使用特定的用户和用户组,按照常规做法,我们就会选择使用www用户组下面的www用户来运行网站服务器,不论是nginx还是apache,我们都可以这么做。

www用户运行的服务器需要读取网站根目录的各种资源,包括动态脚本,比如php脚本,或者是html、css、javaScript等文件。当然了,我们也可以通过在php脚本中切换到其他的用户来执行特别的脚本,这点和在shell脚本中切换用户是一样的。

除此之外我们还可以新建一个自定义用户,新建一个自定义用户组,并将项目文件的所属设置为该用户组的该用户,并且设置相应的目录访问权限。

1、假如web服务器是apache,那么用户访问web页面的时候,就是通过apache服务(httpd)的所有者的身份进行访问,所以要将 apache也就是httpd服务的所有者和所有组设为apache或者自定用户,不要用root,这个一般安装的时候就会有默认设置(或者修改apache配置文件的User和Group项)。

2、网站程序的所有者不要和apache服务的所有者一样,如果一样就相当于给了普通访问者对web文件的所有操作权!一旦web程序有漏洞,那就
over了!默认一般是root,尽量改为其他用户,比如自己建立一个daemon,切记不要和apache服务的所有者一样。

3、对于网站根目录权限,按照最小权限的原则,应设置为755

4、对于缓存目录或者上传目录例如缓存目录:caches目录,由于此目录必须要有写权限,也就是目录同是有rwx三个权限,这时候可以直接建立一个
caches空目录,然后chown daemon.daemon
./caches,就是把caches所有者、所有组改为自定义的daemon就ok了,这样如果访问web页面,就会以apache的身份进入
caches建立缓存目录及文件,默认系统都是以最小权限建立!

5、对于普通目录,最小权限为755,普通用户不给写权限

6、对于普通文件,最小权限为644,普通用户不给执行权限
总而言之,言而总之就是:目录不要给写权限,文件不要给执行权限(除非特殊情况,如目录要上传)

以上是较为严格的网站目录权限设置,由于在我自己配置的时候,还没有查到这一条资料。因此我对权限的管理没有上面说的这么细致,但是操作的方法都是相同的。以下操作在root权限下执行

1. 创建用户组(可以不创建,使用默认和用户名相同的组)

groupadd groupname

2. 创建用户并指定用户组

useradd -g groupname username

或者使用默认用户组,配置网站服务的用户不建议如此做

useradd username

3. 修改用户密码

passwd username

4.赋予用户一定的root的权限(如果没有特殊需要一般网站服务不需要)

visudo

在最后一行添加:

username ALL=(root) /usr/bin/*, /usr/local/elasticsearch-2.4.4/*, !/usr/bin/passwd [A-Za-z]*

注意:ALL=(root)是说su只能切换到root用户, 后面用逗号隔开的是用户的权限,/usr/bin/*表示可以执行基本命令,/usr/local/elasticsearch-2.4.4/*是我自己的elasticsearch的文件路径下所有权限, !/usr/bin/passwd [A-Za-z]*表示不可以修改除了自己的所有用户的密码。

5.将网站的项目根目录的所属者分配给新增的用户
我们假设http服务器运行的用户和用户组是www,网站用户为centos,网站根目录是/home/centos/web。
方法/步骤:

1
我们首先设定网站目录和文件的所有者和所有组为centos,www,如下命令:
chown -R centos:www /home/centos/web

2
设置网站目录权限为750,750是centos用户对目录拥有读写执行的权限,这样centos用户可以在任何目录下创建文件,用户组有有读执行权限,这样才能进入目录,其它用户没有任何权限。
find -type d -exec chmod 750 {} \;

3
设置网站文件权限为640,640指只有centos用户对网站文件有更改的权限,http服务器只有读取文件的权限,无法更改文件,其它用户无任何权限。
find -not -type d -exec chmod 640 {} \;
4
针对个别目录设置可写权限。比如网站的一些缓存目录就需要给http服务有写入权限。例如discuz x2的/data/目录就必须要写入权限。
find data -type d -exec chmod 770 {} \;

经过以上设置之后,就可以使用指定的用户去启动网站的服务了,而不是再如同上面测试环境中使用root启动这个服务,使用root启动服务是不安全的。

uWSGI开机启动服务

继续以django的项目为例,让uWSGI开机就启动服务,编辑文件/etc/rc.local, 添加下面内容到这行代码之前exit 0:

/..uwsgi再系统中的路径../uwsgi --ini /..Django项目中uwsgi配置文件的路径../uwsgi_luffy.ini

要注意的是记得ini配置文件中设置好用户用户组,sock文件,sock文件的权限后台运行等配置。

二、Nginx部署

  • Nginx的作用主要是监听作用,当客户端有静态请求时,将请求指定的静态文件返回给客户端;当客户端发送的是动态url请求时,将该请求从监听端口取出交给uwsgi服务的监听端口,uwsgi的端口接到请求后,交给项目文件夹下的各个Django服务(视图中的函数)进行处理,处理好之后,再由uwsgi返回给nginx,最后nginx将内容返回给客户端。
  • 可以理解到,这就是一个三者合作的过程。因此,我们这一步的配置主要是需要配置nginx的监听端口,以及接收到动态请求后,需要交给哪一个uwsgi的监听端口去处理。除此之外,还要配置nginx本身的静态需求文件夹,包括了项目的根目录、项目的静态文件夹static路径,以及媒体文件夹media路径。

下面是我的项目配置情况:


nginx配置uwsgi和django

  • uwsgi_params文件拷贝到项目文件夹下。
    uwsgi_params文件一般在/etc/nginx/目录下,也可以从nginxgithub页面下载。

  • uwsgi_params配置文件如下:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
  • 拷贝到项目下:
sudo cp /etc/nginx/uwsgi_params /..项目目录../
  • 属主属组等权限重新修改
sudo chown www:centos uwsgi_params
sudo chmod 664 /..项目所在的目录../uwsgi_params
  • 在项目文件夹下创建文件nginx.conf,填入并修改下面内容:
http{
	include  /etc/nginx/mime.types;
	upstream django {
    # server unix:///path/to/your/mysite/mysite.sock; 
    # 用于文件套接字
    server 127.0.0.1:8000; 
    # 用于Web端口套接字(我们将首先使用它)
	}
	# //解决web部署到nginx后js,css等不能访问。
# 服务器配置
server {
    #您的网站将在其上服务的端口
    listen  80; #nginx的监听端口,相当于是我们提供服务的第一道墙

    # 指定提供服务的主机地址,我们将uwsgi服务于nginx服务配置再一台服务器的,因此指定本机即可
    server_name 127.0.0.1; 
    # 设置nginx传送内容的字符集格式,解决网页乱码问题
    charset utf-8;

    # 设置请求体大小;可用于解决大文件上传不了的问题
    client_max_body_size 500M;   # adjust to taste

    location / {
        uwsgi_pass  django;
        include  /web/GradingSystem/uwsgi_params; 
        # 您安装的uwsgi_params文件(这个很重要,我是将uwsgi的这个文件拷贝到了项目文件夹下面)
    }

    location /static/ {
        alias /web/GradingSystem/static/; 
        # 您的Django项目的静态文件-根据需要进行修改
    }

    # Django media
    location /media/  {
        alias /web/GradingSystem/static/media/;  
        # 您的Django项目的媒体文件-根据需要进行修改
    }

    # 最后,将所有非静态和媒体请求发送到Django服务器。
    
	}
}
events {
  worker_connections  1024;  ## Default: 1024
}
  • 补充一些相关参数的意思:
1.client_max_body_size
	-  限制请求体的大小,若超过所设定的大小,返回413错误。
2.client_header_timeout
	- 读取请求头的超时时间,若超过所设定的大小,返回408错误。
3.client_body_timeout
	- 读取请求实体的超时时间,若超过所设定的大小,返回413错误。
4.proxy_connect_timeout
	- http请求无法立即被容器(tomcat, netty等)处理,被放在nginx的待处理池中等待被处理。此参数为等待的最长时间,默认为60秒,官方推荐最长不要超过75秒。
5.proxy_read_timeout
	- http请求被容器(tomcat, netty等)处理后,nginx会等待处理结果,也就是容器返回的response。此参数即为服务器响应时间,默认60秒。
6.proxy_send_timeout
	- http请求被服务器处理完后,把数据传返回给Nginx的用时,默认60秒。

这个配置文件告诉nginx从文件系统中拉起media和static文件作为服务,
同时响应django的request。

为此,我也在相应的项目目录下先建立起media和static文件夹。

为方便nginx运行时使用配置信息,创建一个nginx.conf的软链接到nginx默认的sites-enabled目录。

sudo ln -s /..项目所在../nginx.conf /etc/nginx/sites-enabled/nginx.conf

如果不生成这个软连接,那么Nginx启动时默认加载的配置文件就是它默认的那一个,当然可以使用nginx -c /.../nginx.conf命令启动nginx,它将加载指定配置文件的配置信息,并启动nginx。


django部署static文件(如果项目已经有了static,可以确认一下目录路径是否正确)

  • 在项目文件夹下,建立好静态文件目录:
mkdir static
  • django的setting文件中,添加一行:
STATIC_ROOT = os.path.join(BASE_DIR,static/)
  • 运行(这个必须得运行
python manage.py collectstatic
  • 在项目文件夹下,建立一个media媒体文件目录(用于存放图片音乐等文件做测试)
mkdir media
  • 在media目录中,我传入了一个图片文件2333.png用于测试nginx。

  • 参数STATIC_ROOT用在哪?
    通过python3 manage.py collectstatic收集所有你使用的静态文件保存到STATIC_ROOT!

  • STATIC_ROOT 文件夹 是用来将所有STATICFILES_DIRS中所有文件夹中的文件,以及各app中static中的文件都复制过来,把这些文件放到一起是为了用nginx等部署的时候更方便。

重新加载nginx配置文件进行测试

  • 先进行检测,看之前的配置文件有无错误。
sudo /usr/sbin/nginx -t
  • 重新加载nginx让软链接的luffy_nginx.conf生效。
sudo /usr/sbin/nginx -s reload
  • 访问http://..ip_advers..:80/media/2333.png看能否正常访问到图片资源,注意这里我们使用的服务端口是为nginx服务运行的端口。

注意在做这一步之前,我是己经配置好域名和传送了一个用于测试的图片到服务器上。
做这一步的时候,我也遇到了很多坑,报了很多莫名奇妙的错,但是总结一下,如果nginx服务有问题,请使用systemctl status nginx查看服务状态,使用systemctl restart nginx命令重启nginx服务,再进行测试。

我己经能成功访问到资源了,所以接下来再做下一步测试。

测试nginx 应用 uWSGI 和 test.py

还记得之前写好的一个测试的test-uwsgi.py文件吗?
我们就用配置好的nginx来访问uwsgi启动的test-uwsgi.py好了。
首先,启动uwsgi,并且端口是nginx配置中的负载均衡池8000端口:

uwsgi --socket :8000 --wsgi-file test-uwsgi.py

访问http://ip:80/,实际上访问的就是uwsgi的8000端口。

如能正常访问。表明下面的环节通畅:

the web client <-> the web server <-> the socket <-> uWSGI <-> Python

测试成功后中止程序,到此为止,我们将服务器的uwsgi与nginx和Django三者的关系打通了,最后以 Nginx,WSGI,Django 之间的对话再来阐述一下三者的关系:

Nginx:Hey,WSGI,我刚收到了一个请求(动态http请求),我需要你作些准备,然后由Flask来处理这个请求。
WSGI:OK,Nginx。我会设置好环境变量,然后将这个请求传递给Django处理。 Django:Thanks
WSGI!给我一些时间,我将会把请求的响应返回给你。 WSGI:Alright,那我等你。
Django:Okay,我完成了,这里是请求的响应结果,请求把结果传递给Nginx。 WSGI:Good
job!Nginx,这里是响应结果,已经按照要求给你传递回来了。 Nginx:Cool,我收到了,我把响应结果返回给客户端。大家合作愉快~

欢迎评论区留言,哪里写的不对的烦请提出,我及时修改,大家共同进步!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值