ubuntu+django+uwsgi+nginx前后端分离部署完整版
1.部署之前确定你已经将你的项目上传到你的服务器当中。在我之前的文章已经提到,本文默认项目已经运行成功,并且django项目中允许所有地址进行访问。下面也有我之前的部署,其实按照下面做到虚拟环境能够运行django就可以继续向下读了。
2. 将uwsgi安装到你的virtualenv中,初步设定项目名字为induapp,项目存放在/home/ubuntu/induapp
pip install uwsgi
基础测试(这也是uwsgi文档直接就有的)
创建一个test.py文件
# 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
如果云主机能够直接外网访问的话
在浏览器访问 http://公网IP:8000即可,会提供一个“hello world”消息
如果云主机禁止外网访问
curl 127.0.0.1:8000
也能看到效果
这样意味下面的组建已经正常,不需要重复验证
web client <-> uWSGI <-> python
3.uwsgi测试运行django项目
uwsgi --http :8000 --module induapp.wsgi
module induapp.wsgi:加载指定的wsgi模块
跟上面相同的做法来验证是否能够访问到django项目,这样意味下面的组建已经正常,不需要重复验证
web client<->uWSGI<->Django
4.基本的nginx
安装nginx
sudo apt-get install nginx sudo /etc/init.d/nginx start
同上我们能够在浏览器访问80端口或者curl访问80端口
如果会报错的话,这里建议两个比较快的命令
vim /var/log/nginx/error.log
或者
sudo nginx -t
如果正常运行,意味着
web client<->the web server
其实默认的80端口很容易会被占用,并且你想要在哪里使用nginx,那么你将必须重新配置nginx来提供另一个端口的服务,所以我们选择8080来当作后台的端口,8001来当作前台的端口。
4.为站点配置nginx
首先我们需要uwsgi_params文件,可用在uwsgi发行版本的nginx目录下,或者下面的连接就有,直接复制到induapp项目根目录中,不需要进行修改。
现在就可以在项目induapp根目录下面创建induapp_nginx.conf的文件,然后编写下面文件。
# mysite_nginx.conf # the upstream component nginx needs to connect to upstream django { # server unix:///path/to/your/mysite/mysite.sock; # for a file socket server 127.0.0.1:8000; # for a web port socket (we'll use this first) } # configuration of the server server { # the port your site will be served on listen 8080; # the domain name it will serve for server_name 127.0.0.1; # 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/ubuntu/induapp/media; # your Django project's media files - amend as required } location /static { alias /home/ubuntu/induapp/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/ubuntu/induapp/uwsgi_params; # the uwsgi_params file you installed } }
将这个文件链接到/etc/nginx/sites-enabled,这样nginx就可以看到它了:
sudo ln -s ~/induapp/induapp_nginx.conf /etc/nginx/sites-enabled/
5.基本nginx测试
sudo /etc/init.d/nginx restart
让nginx来测试test.py
我们可以查看端口号占用情况并杀掉进程
netstat -apn|grep 8000 kill -9 id> uwsgi --socket :8000 --wsgi-file test.py
显然可以看出,已经配置了nginx在8000端口与uWSGI通信,而对外使用8080端口,访问8080端口来进行检查。
6.使用Unix socket而不是端口
使用Unix socket会比端口更好,开销更少。
编写induapp_nginx.conf,修改它来匹配:
upstream django { server unix:///home/ubuntu/induapp/induapp.sock; # for a file socket # server 127.0.0.1:8000; # for a web port socket (we'll use this first) }
然后重启nginx
sudo /etc/init.d/nginx restart
再次运行uwsgi
uwsgi --socket mysite.sock --wsgi-file test.py
这次,socket会告诉uwsgi使用哪个文件
在浏览器或者curl尝试访问8080端口
如果那不行
检查nginx错误日志(/var/log/nginx/error.log)。如果你看到像这样的信息:
connect() to unix:///path/to/your/mysite/mysite.sock failed (13: Permission denied)
那么可能你需要管理这个socket上的权限,从而允许nginx使用它。
尝试:
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666 # (very permissive)
或者:
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664 # (more sensible)
你可能还必须添加你的用户到nginx的组 (可能是 www-data),反之亦然,这样,nginx可以正确地读取或写入你的socket。
值得保留nginx日志的输出在终端窗口中滚动,这样,在解决问题的时候,你就可以容易的参考它们了。
6.使用uwsgi和nginx运行django应用
运行我们的Django应用
uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664
现在,uWSGI和nginx应该不仅仅可以为一个”Hello World”模块服务,还可以为你的Django项目服务。
在induapp项目中配置induapp_uwsgi.ini文件
[uwsgi] project = induapp base = /home/ubuntu socket = 127.0.0.1:8000 chdir = %(base)/%(project) home = %(base)/anaconda3/envs/djangoEnv module = %(project).wsgi master = true processes = 10 socket = %(base)/%(project)/%(project).sock chmod-socket = 666 vacuum = true pythonpath = /home/ubuntu/anaconda3/envs/djangoEnv/lib/python3.6/site-packages
值得注意的是要是没有最后一行的pythonpath很可能在初始化uwsgi应用的时候出现 no moudle named xxx的错误。
chdir是项目路径,home是虚拟环境路径。
使用这个文件运行
uwsgi --ini induapp_uwsgi.ini # the --ini option is used to specify a file
打印出来的结果能够预测Django站点是否预期工作
7.系统安装uwsgi
停用虚拟环境
source deactivate
然后在系统中安装uWSGI:
sudo pip install uwsgi
再次检查是否能运行
uwsgi --ini induapp_uwsgi.ini
Emperor模式
# 系统启动时运行uWSGI # 最后一步是让这一切在系统启动的时候自动发生。 # 对于许多系统来说,最简单 (如果不是最好的)的方式是使用 rc.local 文件。 # 编辑 /etc/rc.local 然后在”exit 0”行前添加: /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid ubuntu --gid ubuntu --daemonize /var/log/uwsgi-emperor.log
选项表示:
- emperor: 查找vassals (配置文件)的地方
- uid: 进程一旦启动后的用户id
- gid: 进程一旦启动后的组id
文档中的用户是www-data,
/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log
但常常因为权限不够高,访问时候会出现502的错误,所以我们这里直接使用Ubuntu来提高我们的权限。
7.完成前台的部署
将前台的静态文件打包到一个文件夹上传到服务器中,我们这里是/home/ubuntu/knowGraph
我们在项目根目录创建induapp_web_nginx.conf文件并进行编写。
server { listen 8001; server_name 127.0.0.1; location / { root /home/ubuntu/knowledgeGraph; index index.html; } location /neo4j { proxy_pass http://127.0.0.1:8080; proxy_send_timeout 1800; proxy_read_timeout 1800; proxy_connect_timeout 1800; client_max_body_size 2048m; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $http_host; # required for docker client's sake proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /admin { proxy_pass http://127.0.0.1:8080; proxy_send_timeout 1800; proxy_read_timeout 1800; proxy_connect_timeout 1800; client_max_body_size 2048m; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
下面就是对这个文件的解析
该文件监听的是8001端口,location / 对应的是前端静态文件的初始化界面。/neo4j和/admin对应的是django的url。基本上格式可以不做修改,我们值得注意的是proxy_pass http://127.0.0.1:8080(也就是刚刚我们后台运行在nginx的端口。)注意的是http://127.0.0.1:8080后面不应该带/号,不然访问127.0.0.1:8001/neo4就会变成访问127.0.0.1:8080,跟我们想要的结果不同。
将这个文件链接到/etc/nginx/sites-enabled,这样nginx就可以看到它了: sudo ln -s ~/induapp/induapp_web_nginx.conf /etc/nginx/sites-enabled/
最后的最后,重启服务
sudo /etc/init.d/nginx restart uwsgi --ini induapp_uwsgi.ini -d /home/induapp/induapp.log
原文出处:zhihu -> https://zhuanlan.zhihu.com/p/45828888