我在使用nginx和uWSGI利用socket文件方式搭建Django网站时,发现很多地方说的有所差异,所以想找一下为什么它们会提到这些东西,然后试验一下怎样可以简易地配置它们,至于通过参数设定来达到更好的效率,目前还没有考虑。
我使用的版本:
1. Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-85-genericx86_64)
2. nginx 1.10.3
3. uWSGI 2.0.12-5
4. Django 1.11.4
5. python 2.7.12
参考网址:
1. https://segmentfault.com/a/1190000007262187
2. http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/
3. http://blog.csdn.net/bestallen/article/details/52837609
4. https://github.com/unbit/uwsgi
5. https://segmentfault.com/q/1010000002523354/a-1020000002526934
7. https://gxnotes.com/article/210372.html
8. http://blog.csdn.net/hchuchuan/article/details/49718521
9. http://www.cnblogs.com/dspace/p/5647587.html
应该不只这些,有些可能没有记录下来。其中那个github的用途是,报类似这种错“bind() [core/uwsgi.c line 1593]”的时候,可以看看那附近到底是啥,我遇到了好几次这种情况。
这些部件的访问顺序是Django->uWSGI ->socket ->nginx ->浏览器。
我的理解:nginx负责监听某个端口的外来请求,然后负责通过socket读写数据来响应请求,以及通过location指定访问静态文件和多个socket。uWSGI负责把Django网站的内容和socket建立联系,需要读写socket。
安装Django网站的步骤:
1. 需要注意Django和python版本的问题。
2. 使用virtualenv和virtualenvwrapper创建虚拟python环境,可以在各个环境中安装不同版本的依赖。
3. 进入虚拟环境,安装Django,新建项目和应用。
4. 把应用名填写到setting.py中,修改views.py和urls.py。
5. 输入python manage.py runserver即可查看。
6. 安装uWSGI后即可使用一条命令将项目和对应的环境与http连接,使得外网可以访问。uwsgi --http :5567 --chdir /home/XXX --home=/home/XXX --module XXX.wsgi。
接下来主要是nginx和uWSGI的配置问题。
通过观察查找得到的信息:
Nginx会默认以www-data用户访问,uWSGI的默认配置文件中也是以www-data用户访问,而系统中默认的文件权限是755。在uWSGI的配置文件中,有一行被注释掉的“chmod-socket= 664”,而有些地方说这里可能会用到666权限,官方文档也提到了这一点。另外有人说网站的目录权限需要设置成775,所有者改成www-data,也有人说socket文件要放到/tmp中,这意味着目录权限是777。uWSGI官方文档中提到不要使用root权限运行这个应用。
下面的剧本是从配置好nginx和uWSGI在root权限下可以使用开始的。Nginx:/etc/nginx/sites-available/XXX.conf 绑定监听服务器外网地址的固定端口,uwsgi_pass是.sock文件。uWSGI:某地址下的XXX.ini中的.sock文件与nginx的相同。Nginx使用apt安装,uWSGI使用pip安装,每次需要在命令行中输入uwsgi --ini /home/XXX/XXXl.ini运行。
剧本1:(权限设置)
1. 所有操作使用root权限,在其他情况不变时,chmod-socket使用664权限不行,使用666权限就可以,所以该socket文件需要有所有人写入的权限。要用到该文件的有uWSGI和nginx,分别是root用户和www-data用户,因为它们都要写入这个文件,而又是不同组,所以权限只能是666。
2. 为了安全起见,uWSGI不应该在root权限下运行,所以先把它的用户改成www-data,这时存socket的文件夹是root+755,有2个www-data用户需要读写它,就会被拒绝。一种办法是把socket文件夹改成www-data+755,另一种是改成root+777,似乎前一种安全一些。这时,如果网站有上传文件的功能,那个目标文件夹也得改成www-data用户的。
3. 如果还想修改,可以新建一个用户,它是属于www-data组的。这时由于socket的权限是默认的755,这个新用户没有权限写入,而uWSGI又需要写入,就把chmod-socket选项改成664,另外socket所在的文件夹也是默认的755,这个用户没有权限创建socket,所以文件夹权限要改成775。如果有上传文件功能,对应文件夹也要改成775。
4. 结果:uWSGI,新用户:www-data;socket文件夹,www-data:www-data,775;socket,664;nginx,www-data:www-data。暂时不知道分配更少权限的结果了。
剧本2:(uWSGI服务启动)
1. 常见的安装uWSGI有两种方式,apt和pip,apt会在/etc/init.d里生成文件,并且支持service调用,执行目录在/usr/bin,pip只会在/usr/local/bin里生成文件。如果两者同时安装,在命令行输入时,调用的是pip的版本,service重启时调用的是apt版本。
2. 官方文档里介绍了一种方法Upstart,似乎可以使用service来调用,然后就可以开机自启动,并且开始停止都很方便。做法是在/etc/init里建立一个uwsgi.conf文件,记录ini配置文件的位置,写一些配置,就可以随服务启动了。但是如果我只用pip安装,就识别不到这个服务,如果我增加apt的安装,它似乎只是用了/etc/init.d/uwsgi,调用/usr/bin/uwsgi,没有识别我写的uwsgi.conf文件。另外,apt安装时,/etc/uwsgi文件夹里有apps-enabled文件夹,如果把ini文件放到里面,会随服务启动调用它们,但是由于/usr/bin/uwsgi和/usr/local/bin/uwsgi不一样,同样的配置文件后者可以运行,前者则不行。并且这样做的话,服务运行后服务器会变卡,只有全部删了uWSGI和nginx才恢复。
3. 我看到有说:“如果您同时拥有/etc/init.d/uwsgi和/etc/init/uwsgi.conf”,就可以用“sudo service uwsgi restart”,自动启动/etc/init/uwsgi.conf,但是如果我只用pip安装,并没有/etc/init.d/uwsgi,如果我增加安装apt,输入后无反应,找不到是哪里弄错了。
4. 于是我删除了在pip下安装的uWSGI,重新安装了uWSGI,还要安装uwsgi-plugin-python。步骤为:在/etc/uwsgi/apps-available中放入之前写好的ini文件,链接到隔壁/etc/uwsgi/apps-enabled,让uwsgi自动识别,之前我到这一步之后会出问题,可能是我直接把ini文件放到enabled中了,因为连续两次都有问题,但是这次不会变卡。这里的ini文件需要做一个修改,要增加一行plugins = python,然后要配置好nginx。似乎这样就可以了,但是还是有问题,在重启服务时出错,还需要找到默认的配置/usr/share/uwsgi/conf/default.ini,把其中的用户名改成自己的用户名。这里的ini文件我遇到一个问题,uid如果直接写用户名,它会报错,在用户名后面会有一个’\r’,所以我这里要写数字的1000就可以了,gid是33。通过看默认的配置,发现chmod-socket设置成660就可以了,因为需要读写它的都是一个组的。然后发现似乎前面的775,755都可以改成770,750,这些文件就可以专门给www-data使用。
5. 接着尝试找一下前面设置/etc/init/uwsgi.conf后没反应的原因。用前面设置好的新用户可以运行的ini为基础,命令行输入“uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data”可以运行,但是输入“uwsgi--emperor /etc/uwsgi/vassals”不能运行,报错是当前在“/”下运行。/etc/uwsgi/vassals里是一个链接到可用ini的文件,这个ini里面写了uid为1000和gid为33。所以说如果不在—emperor模式下输入uid和gid,ini里面的输入是识别不了的,然后输入“uwsgi --emperor /etc/uwsgi/vassals --uid XXX --gid www-data”,这样就算和ini里的用户对应上也不行。但是如果删除ini中关于uid和gid的设定,就可以运行,我觉得原因是—emperor模式完全接管了uid和gid的设定,ini里就算和它一样也会有问题,级别比它低就没问题。
6. 然后我移除了/etc/uwsgi/apps-available中的内容,在/etc/init/uwsgi.conf中写入了Upstart方法的内容,最后一行是“execuwsgi --emperor /etc/uwsgi/vassals --uidXXX --gid www-data”,和命令行中的输入一样,可惜还是没有识别。查看“systemctl status uwsgi.service”,打开的依然是“/etc/init.d/uwsgi”,不知道是哪里出了问题。
7. 于是我查看了一下upstart的信息,发现ubuntu从15.04开始就逐步弃用upstart了,改而使用systemd,它提示我用systemctl status的时候我都没查一下这是什么。我这服务器根本就没装upstart,怪不得我看的那些资料提都没提这一点。既然service uwsgi restart已经可以运行了,upstart为什么不可用的原因也找到了,暂时就可以告一段落了。
一些好用的操作:
1. sudo chmod -R 775 /home/XXX/
2. sudo chown -R www-data:www-data/home/XXX/
3. sudo ln -s/etc/uwsgi/apps-available/XXX_uwsgi.ini /etc/ uwsgi /apps-enabled/XXX_uwsgi.ini
4. sudo ln -s/etc/nginx/sites-available/XXX.conf /etc/nginx/sites-enabled/
5. uwsgi --http :5567 --chdir/home/XXX --home=/home/XXX --module XXX.wsgi
6. uwsgi --socket /home/XXX/XXX.sock--chdir /home/XXX --home /home/XXX --module XXX.wsgi --chmod-socket=666
7. uwsgi --ini /home/XXX/XXX.ini
8. uwsgi --emperor/etc/uwsgi/vassals --uid www-data --gid www-data
9. /etc/init.d/nginx restart
10. service uwsgi restart
11. systemctl status uwsgi.service