Centos7 下部署django
Posted on 一 12 12月 2016 in python
前几天在阿里云上部署了一个系统。顺便了解了一下nginx, uwsgi, django部署的流程
首先安装nginx,这个比较简单
sudo yum install nginx
安装uwsgi, 这里要注意,最好用pip安装,而不用yum安装。通常用yum或者apt-get安装的,需要在命令后面加上 --plugin python
pip install --user uwsgi
一步一步使用uwsgi, 第一个WSGI project, 保存为foobar.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
部署到9090端口
启动uWSGI作为http服务器转发请求到WSGI application
uwsgi --http :9090 --wsgi-file foobar.py
浏览器访问 http://localhost:9090
就可以看到效果。
如果是在服务器,可以用 curl -i "http://localhost:9090"
开启并发处理,监控
uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191
开启了4个进程,2个线程(这里我其实不是太清楚), 127.0.0.1:9191
会输出各个进程和线程的状态 这里推荐一个项目 djano-uwsgi
uWSGI 支持HTTP, FastCGI, SCGI,和 uwsgi。但是对uwsgi协议支持是性能最好的。nginx也支持uwsgi协议。所以可以配合来使用
nginx配置
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
上面的配置意思是把服务器3031端口的的请求转成uwsgi协议
然后uWSGI使用uwsgi协议
uwsgi --socket 127.0.0.1:3031 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191
部署Django应用
Django应用目录在/home/foobar/myproject
uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --wsgi-file myproject/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191
上面命令的参数太多了,uWSGI支持配置文件,新建uwsgi.ini文件
[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
wsgi-file = myproject/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:9191
然后运行
uwsgi uwsgi.ini
以上内容是从官方的教程提取出来的。下面是我实际中结合文档的操作
django deployment checklist
运行 python mannage.py check --deploy
会检查settings.py里面的设置是否合适,比如关闭debug等等
django Deploying static files
在settings.py里面要设置一个STATIC_ROOT
,
STATIC_ROOT = os.path.join(BASE_DIR, "collected_static/")
在部署服务器
上运行 python manage.py collectstatic
, 把静态文件拷贝到collected_static
目录上,否则运行之后报404错误
新建nginx的配置文件,eng_nginx.conf
# the upstream component nginx needs to connect to
upstream ent {
server unix:///run/uwsgi/ent.sock; # for a file socket
#server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name xxx.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 /favicon.ico{
alias /var/www/ent/ent/media/favicon.ico; # your Django project's media files - amend as required
}
# Django media
location /media {
alias /var/www/ent/ent/media; # your Django project's media files - amend as required
}
location /static {
alias /var/www/ent/ent/collected_static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass ent;
include /var/www/ent/ent/uwsgi_params; # the uwsgi_params file you installed
}
}
这里使用了unix sock方式,而没有使用端口方式, sock文件路径是 /run/uwsgi/ent.sock
,这个路径是systemd动态创建的,不需要手动创建。
uwsgi_params
可以使用project中的,也可以使用nginx安装路径的。
static
请求要指定到上一步对应的目录中。
media
也是要指定到对应目录。
注意上面两个目录必须包含nginx运行的用户组,有可能是www-data
,也有可能是nginx
,并且当前用户要加入到nginx的用户组。
sudo chown -R user:nginx collected_static
sudo chown -R user:nginx media
uwsgi配置
这里直接使用 uWSGI的emperor 模式
# create a directory for the vassals
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
# symlink from the default config directory to your config file
sudo ln -s /path/to/your/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/
# run the emperor
uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
# touch emperor.ini
cd ..
touch emperor.ini
[uwsgi]
# the base directory (full path)
chdir = /home/maemo/workspace/python/ent
# Django s wsgi file
module = ent.wsgi:application
;home = /var/www/ent/uwsgi
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 1
socket = /run/uwsgi/ent.sock
# ... with appropriate permissions - may be needed
chmod-socket = 664
# clear environment on exit
vacuum = true
die-on-term = true
;logto = /tmp/ent.log
;logfile-chmod = 666
daemonize = /var/log/uwsgi/ent.log
mysite_uwsgi.ini的内容:
[uwsgi]
uid = maemo
gid = nginx
# the base directory (full path)
chdir = /var/www/ent/ent
# Django s wsgi file
module = ent.wsgi:application
;home = /var/www/ent/uwsgi
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 1
#socket = /var/www/ent/ent.sock
socket = /run/uwsgi/ent.sock
# ... with appropriate permissions - may be needed
chmod-socket = 664
# clear environment on exit
vacuum = true
die-on-term = true
;logto = /tmp/ent.log
;logfile-chmod = 666
daemonize = /var/log/uwsgi/ent.log
emperor.ini 内容如下:
[uwsgi]
emperor = /etc/uwsgi/vassals
#uid = user
#gid = nginx
上面指定了uWSGI的用户是user,用户组是nginx,当然,这个在上面的mysite_uwsgi.ini也可以单独配置,这个很重要
另外,mysite_uwsgi.ini中的sock
文件与ent_ngixn.conf中的sock
一定要是相同的
使用systemd启动和停止uWSGI
cd /etc/systemd/system
sudo touch emperor.uwsgi.service
emperor.uwsgi.service的内容如下:
[Unit]
Description=uWSGI Emperor
After=syslog.target
[Service]
ExecStart=/home/user/.local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
User=maemo
Group=nginx
[Install]
WantedBy=multi-user.target
注意到上面uwsgi
是绝对路径,因为我是用pip安装到当前用户的
RuntimeDirectory=uwsgi
这一句就会自动在/run/
下面创建uwsgi/ent.sock
文件,在旧版本的systemd
中可能要参考其它方法
启动nginx和uWSGI
sudo systemctl restart nginx.service
sudo systemctl restart emperor.uwsgi.service
在这个过程中,我遇到很多错误,最有用的是看nginx和uWSGI的log,通过log再到网上去查能很快解决问题