Django部署到Nginx阿里云服务器(uwsgi协议)

Django、Nginx、uwsgi各是什么?

  • Django:它是一个开放源代码的Web应用框架,由Python写成。Django是基于Python的web框架中最有代表性的一位。许多成功的网站和APP都基于Django。此外,它的数据库默认设置为SQLite,无需另外安装,除非你要用其他数据库。

  • Nginx:它是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。优点:轻量,占有内存少,并发能力强。

  • WSGI(补充):它的全称是Web Server Gateway InterfaceWSGI不是服务器,python模块,框架,API或者任何软件。WSGI只是一种规范,描述web server如何与web application通信,在此可理解为描述Nginx服务器Django项目间的通信。要实现WSGI协议,必须同时实现web serverweb application

  • uwsgi:与WSGI一样是一种通信协议,是uWSGI服务器的独占协议。它与mod_wsgi相比的优点为:超快的性能。低内存占用(实测为apache2的mod_wsgi的一半左右)。多app管理。

本文测试环境如下:

  • 云服务器:阿里云Ubuntu16.04
  • python版本:3.5.2

一、必要软件的安装

1. 安装Django

pip install Django

如果你遇到了python2python3多版本管理的问题,比如pip安装时它没有将Django安装到你所希望的python版本下,可以先读下我的这一篇博文:使用virtualenv创建各版本python的虚拟环境

2. 安装Nginx

sudo apt-get update
sudo apt-get install nginx
sudo /etc/init.d/nginx start    # start nginx

注意要先执行sudo apt-get update,这条命令是同步 /etc/apt/sources.list 中列出的源的索引文件,相当于获取软件最新的状态,这样才能获取到最新的软件包。不执行update,有可能会提示无法定位到nginx

安装完成后,用电脑的浏览器访问服务器的公网ip地址,如果出现Nginx的欢迎页面(如下),则表示nginx运行正常。
Django部署到Nginx阿里云服务器(uwsgi协议)_第1张图片

果然我这里没那么顺利,出现了异常,无法访问到该ip(也许是被墨菲定律眷顾吧= =!)。

因此下边开始异常解决。如果在你的服务器上运行正常,则nginx运行正常,点击跳过异常解决部分。

2.1 nginx无法访问的解决办法

问题原因猜测:
  1. nginx没有监听80端口
  2. ubuntu服务器的防火墙没有开放80端口

以下将按照这两个猜想进行排查

2.2 查看服务器端口占用

netstat -nap | grep 80

其中:
netstat:查看网络系统的状态信息;
-a或–all:显示所有连线中的Socket;
-n或–numeric:直接使用ip地址,而不通过域名服务器;
-p或–programs:显示正在使用Socket的程序识别码和程序名称;


说明nginx确实在监听80端口,运行正常。

2.3 查看防火墙设置

#查看ubuntu的ufw防火墙状态
ufw status


结果发现ufw未激活,并没有启用。

了解到阿里云服务器有一个安全组规则设置,其作用可类比防火墙,可以控制端口的开放与关闭。

2.4 阿里云安全组规则配置

前往阿里云服务器的管理控制台,点击自己的云服务器–>更多–>网络和安全组–>安全组配置–>配置规则,发现规则里没有对外开放80端口。至此,问题原因已经被找出。

理所当然地,我们应该设置对外开放80端口。选择添加安全组规则,并如下图填写。
Django部署到Nginx阿里云服务器(uwsgi协议)_第2张图片

其中授权对象的0.0.0.0/0表示允许或拒绝所有的ip访问。我们搭建的个人服务器当然是希望让更多的人访问,因此选择允许所有ip。

配置完成后,再次在浏览器中访问服务器的公网ip,可以看到上述的Welcome to nginx!

3. 安装uwsgi

sudo pip install uwsgi --upgrade

4. 小结

经过上面的步骤,我们已经搭建好了需要的软件和环境。作为web servernginx也运行良好,现在它只是不知道该如何处理不同的url请求,这就要求我们将nginx、uwsgi、django项目通过配置文件关联起来

接下来我们就开始逐一配置。

二、进行项目配置

1. django项目

为了方便测试,我使用的是通过django-admin startproject mysite生成的一个模板项目工程“mysite”。

如果你对django创建app项目还不太了解,这里给出官方教程链接:https://docs.djangoproject.com/en/2.1/intro/tutorial01/ 。如果你对英语感到陌生,不用担心,在官方教程右下角可以将语言切换至中文。

项目工程mysite放置在/var/www目录下,www目录结构如下所示,比如settings.py文件的全路径为/var/www/mysite/mysite/settings.py

.
├── html
│   └── index.nginx-debian.html
└── mysite
	├── *uwsgi.ini
	├── *run.log
    ├── manage.py
    ├── mysite
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── *static
        └── *admin
#注:带*的表示我们即将要创建的文件

接下来,我们要部署静态文件,即把Django的静态文件(CSS, JavaScript, Images等)收集到一个static文件夹中。这步不需要你手动执行,你只需要打开上述settings.py文件,加入一行:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

并且

#找到下面这一行
#ALLOWED_HOSTS = []
#换成
ALLOWED_HOSTS = ['你的公网IP', 'localhost', '127.0.0.1']

其中你的公网IP请替换成实际的IP地址,这样才能通过公网访问到django应用。

然后执行:

#此命令在外部的mysite文件夹下执行
python manage.py collectstatic


接着,你就会发现static文件夹生成好了。

为什么要创建这个static文件夹?为什么我网站的admin后台管理页面样式全没了?

你可能已经通过manage.py来运行过django项目,并且访问过默认生成的admin后台管理界面,彼时理所当然是有样式的。
如果不创建static文件夹,当使用公网ip访问admin时,客户端将无法获取到django内置的这些静态文件,就会出现样式全无的情况,也就是第二个问题的原因。

2. 配置nginx文件

vim /etc/nginx/sites-available/default

别看这个default文件写了很多东西,其实带#的都是注释,把注释拿开后,我们关注的只有:

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	root /var/www/html;
	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;

	server_name 119.23.69.193;  #第一处修改,此处改为你的服务器的公网IP
	location / {
		#以下3行是第二处修改
		include /etc/nginx/uwsgi_params;  #uwsgi_params是我们需要用到的文件
		uwsgi_pass 127.0.0.1:8000;	#将请求交由uwsgi处理,并传到127.0.0.1:8000
		#try_files $uri $uri/ =404;       
	}
	#####################第三处修改begin
	location /static {
		alias /var/www/mysite/static;	#请替换成自己实际的静态文件目录
		#这里会将请求转换成对alias指定的路径下的文件访问
	}
	#####################第三处修改end
}

请把你default文件按如上进行修改,总共有三处,请仔细查看。另外,请不要盲目复制粘贴
对于上述参数,现给出部分参数解释如下:

listen 80 default_server;:listen,即监听指令,此处监听80端口,且后面有一个参数 default_server。Nginx 的虚拟主机是通过HTTP请求中的Host值来找到对应的虚拟主机配置,如果找不到呢?那 Nginx 就会将请求送到监听了 default_server 的 节点来处理。

location / {}:表示捕捉server_name的根请求,比如我服务器的根URLhttp://119.23.69.193/ 。同理,/statichttp://119.23.69.193/static

uwsgi_pass 127.0.0.1:8000;:将请求转至本机的8000端口,不用担心阿里云安全组规则的设置,因为是本地的。

这份配置文件告诉nginx从文件系统里寻找static文件,并且将一些需要django代码介入的行为交由uwsgi来管理。也就是实现了从nginx–>uwsgi。

修改完成后,别忘了重启nginx:

sudo service nginx restart

3. 配置uwsgi文件

接下来,在外部的mysite(/var/www/mysite/) 新建一个uwsgi.ini文件和一个run.log文件,即我在www目录结构下提到的带*文件。

然后我们将以下内容添加进这个空的uwsgi.ini文件:

[uwsgi]
chdir = /var/www/mysite
module = mysite.wsgi
socket = 127.0.0.1:8000 
master = true         
daemonize = /var/www/mysite/run.log
disable-logging = true
pythonpath = /root/py3env/lib/python3.5/site-packages

chdir:它是你的项目的根目录,请自行替换成你自己的;
moudule 是你的入口wsgi模块,将mysite替换成你自己的项目名称;
socket 是通信端口设置;
master = true 表示以主进程模式运行;
daemonize 是你的日志文件目录,这个路径就是刚刚新建的run.log文件的路径;
disable-logging = true 表示不记录正常信息,只记录错误信息;
pythonpath 是你python的包的路径。由于我们使用了virtualenv环境,所以这里必须设置,请替换成你的实际路径。否则会报错:ImportError:No module named django.core.wsgi。

最后,不要忘记使得ini文件生效:

#在/var/www/mysite/目录下执行
uwsgi --ini uwsgi.ini

可以使用uwsgi --python-version命令查看uwsgi对应的python,如果不是virtualenv里的那个版本,请自行修正好。可参考:http://blog.51cto.com/leizhu/2065394

#如果要重载init文件,需要如下操作
 #查看到占用8000端口的当前的uwsgi
 netstat -nap | grep 8000

#kill掉当前的uwsgi
 kill -9 进程号

#再次运行
 uwsgi --ini uwsgi.ini

至此,就完成了nginx–>uwsgi->django项目的配置。其中nginx到uwsgi是通过本地端口8000来完成的,nginx进行转交,uwsgi来监听,最后导入相应的django模块。

写在最后

We’re done! 现在,你可以通过ip访问你的网站啦,比如我的:http://119.23.69.193/ 、又或者admin后台管理。

其实还是踩了蛮多坑才能写完这篇博文的哈哈哈哈,希望能对你有帮助呀!有什么问题欢迎留言询问。

我查看了下run.log,发现程序给出了不少调整和优化建议,看来之后要研究下这块,立个flag吧hhh!

你可能感兴趣的:(Django部署到Nginx阿里云服务器(uwsgi协议))