利用uWSGI和Nginx部署Django

来源:互联网 发布:cnc用什么软件 编辑:程序博客网 时间:2024/06/09 18:09

主要内容来自于

https://uwsgi.readthedocs.io/en/latest/tutorials/Django_and_nginx.html


系统情况:

Ubuntu 14.04.2 LTS (实际是麒麟版)

python3 version 3.5.2(源上直接apt-get)

pip3 version 8.1.1(源上直接apt-get)

若无特殊指代,localhost即为127.0.0.1


虽说本文类别定为“翻译”,但是并没有将上述链接所代表的网页直接翻译,而是取得其中的关键步骤,另加自己的细节调整。


安装virtualenv并激活

安装virtualenv

我对virtualenv的理解非常浅,目前就理解为一种处理python多版本问题的“沙盒”解决方案,把想使用的python版本和对应的工具放到一个位置,不必担心系统层面的冲突。

实际安装时,使用

sudo pip3 install virtualenv


激活virtualenv

我目前理解激活(activate)virtualenv指创建一个virutalenv环境。由于我将使用python3,而在Ubuntu14中,系统的默认的python是2.7,那么在激活前的创建过程中需要指定所使用的python。在创建的同时需要指定一个virtualenv名称,virtualenv会创建相应的文件夹。实际创建virtualenv时使用如下命令

virtualenv -p /usr/bin/python3 uwsgi-tutorial

uwsgi-tutorial即指的是virtualenv名称,是沿用原网页上的描述。上述命令是我搜索得到的,原网页位置为stackoverflow。命令执行之后,会在当前文件夹下生成uwsgi-tutorial文件夹,进入该文件夹,那么我们现在所在位置为

/home/yaoyu/MySites/uwsgi-tutorial

其中yaoyu是我的用户名,MySites是我用来存放网站文件的位置(我就都不遮盖了。。)

此时,运行脚本bin/activate(该脚本位于/home/yaoyu/MySites/uwsgi-tutorial/bin)以激活该virtualenv

source bin/activate

成功激活后,终端的prompt会在最前面加上当前virtualenv的描述。

在virtualenv中安装Django

安装Django,并创建一个示例project。

pip install Django
django-admin.py startproject mysite
cd mysite

mysite即为Django的project名,并且也是文件夹名(当然mysite下面还有一个mysite)。此时,我们的位置变为

/home/yaoyu/MySites/uwsgi-tutorial/mysite

可以现在立即测试Django project的可用性,并同时测一下端口的可用性。

python manage.py startserver 0:8000

若正常启动,则通过浏览器访问localhost:8000应能看到Django的信息。此时使用的是Django自带的development server,终端中用Ctrl+C终止Django的development server的运行。

在virtualenv中安装uWSGI

安装uWSGI(在CenOS中可能需要先安装python3x-devel,3x代表版本号)

pip install uWSGI

为了简单测试uWSGI,编写test.py文件。当前我们仍位于

/home/yaoyu/MySites/uwsgi-tutorial/mysite


新建的test.py文件内容为

def application(env, start_response):start_response('200 OK', [('Content-Type','text/html')])return [b"Hello World"] # python3
测试uWSGI的有效性

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


此时若正常启动uwsgi,那么通过浏览器访问localhost:8000即可看到Hello Word字样。Ctrl+C 终止uwsgi。

之后可测试uWSGI与刚刚建立的Django project的数据交换。


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


我们当前仍在/home/yaoyu/MySites/uwsgi-tutorial/mysite,module wsgi即保存在


/home/yaoyu/MySites/uwsgi-tutorial/mysite/mysite/wsgi.py


此时利用浏览器访问localhost:8000应当可以看到Django的信息。


安装并配置nginx

从源上直接安装nginx。


sudo apt-get install nginx


安装完毕后,启动nginx。


sudo /etc/init.d/nginx start


此时,使用浏览器访问localhost:80(注意端口,也可以不带端口),应当可以看见nginx的欢迎信息。


为了与uWSGI连接,需要一个uwsgi_params文件和一个nginx的conf文件。uwsgi_params文件可以从如下地址获取。

https://github.com/nginx/nginx/blob/master/conf/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;
将该uwsgi_params文件复制到Django project的文件夹,即


/home/yaoyu/MySites/uwsgi-tutorial/mysite


并在同样位置创建mysite_nginx.conf文件,内容为

# mysite_nginx.conf# the upstream component nginx needs to connect toupstream django {    # server unix:///home/yaoyu/MySites/uwsgi_tutorial/mysite/mysite.sock; # for a file socket    server 127.0.0.1:8001; # for a web port socket (we'll use this first)}# configuration of the serverserver {    # the port your site will be served on    listen      8000;    # the domain name it will serve for    server_name .example.com; # substitute your machine's IP address or FQDN    charset     utf-8;    # max upload size    client_max_body_size 75M;   # adjust to taste    # Django media    location /media  {        alias /home/yaoyu/MySites/uwsgi-tutorial/mysite/media;  # your Django project's media files - amend as required    }    location /static {        alias /home/yaoyu/MySites/uwsgi-tutorial/mysite/static; # your Django project's static files - amend as required    }    # Finally, send all non-media requests to the Django server.    location / {        uwsgi_pass  django;        include     /home/yaoyu/MySites/uwsgi-tutorial/mysite/uwsgi_params; # the uwsgi_params file you installed    }}
mysite_nginx.conf文件的内容包括上游数据源的描述,目前为localhost:8001,nginx监听8000端口向client提供web服务,server的media文件位置以及static文件位置,最后是这个server的根位置。将mysite_nginx.conf以符号连接的形式插入到nginx的默认服务器列表里。


sudo ln -s /home/yaoyu/MySites/uwsgi-tutorial/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/


收集Django project的static文件。修改/home/yaoyu/MySites/uwsgi-tutorial/mysite/mysite/settings.py,添加如下一行

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
然后执行
python manage.py collectstatic
将自动生成一个新文件夹static。启动nginx进行测试


sudo /etc/init.d/nginx restart


此时由于没有任何实际server在运行,于是访问localhost:8000是显示Bad Geteway。但是仍可以测试nginx的运行。在


/home/yaoyu/MySites/uwsgi-tutorial/mysite


下新建media文件夹,进入media文件夹,并复制一个png图片进来,然后利用localhost:8000/media/png文件名.png的形式通过浏览器查看这个图片,若成功显示图片,代表nginx的配置是正确的。

nginx,uWSGI和Django联调

首先通过uwsgi和test.py还有nginx进行联调。在


/home/yaoyu/MySites/uwsgi-tutorial/mysite


运行


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


此时通过浏览器访问localhost:8000,此时应有Hello world字样。uwsgi通过localhost的8001端口向nginx提供数据,nginx再通过localhost的8000端口向浏览器提供数据。用Ctrl+C退出uwsgi。


现在利用Unix socket代替TCP端口。上面的测试使用的是8001端口,通过修改mysite_nginx.conf中upstream django中的描述(即将原来注释掉的socket描述恢复,而注释8001端口的描述。)再重启nginx服务


sudo /etc/init.d/nginx restart


另外,在Ubuntu系统上,nginx服务是默认已www-data用户和www-data用户组启动的。这里可以将当前用户添加至www-data用户组


sudo usermod -a -G www-data yaoyu


可能需要重新登录。之后可利用group或者id命令查看。


启动uwsgi


uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664 --chown-socket=yaoyu:www-data


推荐此时再另开一个Terminal,并输出nginx的error log


tail -f /var/log/nginx/error.log


通过浏览器访问localhost:8000,此时若出现Bad Gateway错误,并且nginx的error log提示Permission denied。这表示nginx没有对mysite.sock文件的操作权限(仅限Ubuntu系统,对于CentOS或者Fedora可能是与SELinux有关)。处理方案是采用tmpfiles.d,可参考

https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html

方案原理是将socket文件放置在一个nginx和uWSGI都有足够权限的位置,比较理想的位置是/run(或者其变种/var/run),在/run下建立一个文件夹位置,并设定该文件夹的权限。具体做法是在/etc/tmpfiles.d下新建一个conf文件,这里我们用mysite-socket.conf命名,其内容为

# Create directory for my sites.d /run/mysite-socket 0775 www-data www-data -
这表示建立/run/mysite-socket 文件夹,并设定好权限位以及所有者和所有群,并不设定过期清空时间。

然后,修改mysite_uwsgi.conf的描述,将socket文件指向于/run/mysite-socket文件夹内。重启计算机。之后查看/run的内部是否有mysite-socket文件夹,并确认它的权限位和所有者情况。


调试成功后进行Django的联调。通过Ctrl+C退出uWSGI,在


/home/yaoyu/MySites/uwsgi-tutorial/mysite


重新启动uWSGI


uwsgi --socket /run/mysite-socket/mysite.sock --module mysite.wsgi --chmod-socket=664 --chown-socket=yaoyu:www-data


在浏览器中访问localhost:8000应当可以看到Django的信息。用Ctrl+C退出uWSGI。


为了避免使用命令启动uWSGI并实现自动化启动uWSGI,编写uWSGI的ini文件。命名为mysite_uwsgi.ini

# mysite_uwsgi.ini file[uwsgi]# Django-related settings# the base directory (full path)chdir           = /home/yaoyu/MySites/uwsgi-tutorial/mysite# Django's wsgi filemodule          = mysite.wsgi# the virtualenv (full path)home            = /home/yaoyu/MySites/uwsgi-tutorial# process-related settings# mastermaster          = true# maximum number of worker processesprocesses       = 10# the socket (use the full path to be safesocket          = /home/yaoyu/MySites/uwsgi-tutorial/mysite/mysite.sock# ... with appropriate permissions - may be neededchmod-socket    = 664chown-socket    = yaoyu:www-data# clear environment on exitvacuum          = true


使用ini文件启动uWSGI


uwsgi --ini mysite_uwsgi.ini


同样通过浏览器访问localhost:8000,成功后终止uWSGI。

在virtualenv外安装调试uWSGI

为了能够部署服务器,uWSGI不能仅运行在virtualenv中,需要在其外也能够正常运行。


以上的调试工作实际上完全在uwsgi-tutorial virtualenv中进行的,现在退出该virtualenv。执行


deactivate


安装uWSGI


sudo pip3 install uwsgi


安装完毕后,在


/home/yaoyu/MySites/uwsgi-tutorial/mysite


下测试uWSGI


uwsgi --ini mysite_uwsgi.ini


通过浏览器访问localhost:8000,应看到Django信息。用Ctrl+C退出uWSGI。


uWSGI的emperor mode

运行于emperor mode下的uWSGI,可以通过监视conf文件的变化,重新启动服务。emperor mode需要使用uWSGI的vassal文件夹进行配置,新建


/etc/uwsgi/vassals (需要root权限)


在该文件夹下添加符号连接


sudo ln -s /home/yaoyu/MySites/uwsgi-tutorial/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/


以emperor mode启动uWSGI


sudo uwsgi --emperor /etc/uwsgi/vassals --uid yaoyu --gid www-data


利用浏览器访问localhost:8000,应可看到Django信息。利用Ctrl+C退出uWSGI(emperor mode)。


配置uWSGI随系统启动

配置/etc/rc.local文件(需要root权限),将上述uWSGI的emperor mode启动命令添加到rc.local文件的exit 0前。(貌似不加uid和gid也可以。)


/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid yaoyu --gid www-data --daemonize /var/log/uwsgi-emperor.log


保存文件,重新启动系统。重新启动之后,直接通过浏览器访问localhost:8000,应当可以看到Django信息。


总结

多看官方网页,多用google,耐心不要急。初期尽量使用源,而不要自己编译python3什么的,别说我没提醒过。。。




原创粉丝点击