1. 前言
《Django部署到线上》一文中,很多步骤不是必须的,有些部分甚至是错误的,本文就精简修改一下。
目标:把djsite项目部署到/home/web目录中,并且给它分配一个域名为djsite.voidking.com。
2. 环境准备
2.1. supervisor
参考《CentOS安装配置Supervisor》,安装配置好supervisor。
2.2. python虚拟机
参考《CentOS安装配置pyenv》,安装好python3.6.1。
3. 项目部署
3.1. 代码准备
1、在/home/web目录中,执行命令克隆项目git clone https://github.com/voidking/djsite.git
2、安装djangopip install django==1.11.7
3、安装pymysqlpip install pymysql
3.2. 数据库准备
1、创建数据库
1 | # mysql -uroot -p |
2、修改mysql的binlog格式为混合模式:
1 | mysql> set global binlog_format=mixed; |
3、修改djsite/djsite/settings.py中的数据库配置vim djsite/djsite/settings.py
4、创建表结构
1 | python manage.py makemigrations |
3.3. 启动项目
1、启动命令python manage.py runserver
2、服务器测试访问curl localhost:8000/blog/index
3、本地测试访问
使用浏览器查看 http://ip:8000/blog/index ,无法访问。
启动命令改为:python manage.py runserver 0.0.0.0:8000
,此时即可在浏览器看到部署好的项目。
如果还是不能访问,尝试先关闭防火墙:systemctl stop firewalld
4. nginx配置
1、首先,在万网上配置域名解析,添加A记录,解析到阿里云服务器IP。假设解析好的域名为django.voidking.com。
2、在nginx的vhost中,添加django.voidking.com.conf,内容为:
1 | server { |
3、重启nginx,./nginx -s reload
4、测试访问
服务器:curl django.voidking.com/blog/index
本地浏览器:http://django.voidking.com/blog/index
至此,django项目已经部署成功,没有用到uwsgi。如果给django添加守护进程,那么我们的部署就接近完美了。那么,uwsgi又能干什么呢,我们继续研究。
5. uwsgi
5.1. 安装uwsgi
pip install uwsgi
编写测试:
1 | # test.py |
启动测试:uwsgi --http :8001 --wsgi-file test.py
访问 http://ip:8001 ,即可看到Hello World 。
5.2. 一般启动
1、编写wsgi.py文件
编写django_wsgi.py文件,将其放在与文件manage.py同一个目录下。
1 |
|
2、启动项目uwsgi --http :8000 --chdir /home/web/djsite/ --module django_wsgi
3、查看启动结果lsof -i :8000
,ps aux | grep uwsgi
4、测试访问
http://ip:8000/blog/index
此时,页面是没有样式的,也就是说静态资源加载失败。
5、配置静态资源uwsgi --http :8000 --chdir /home/web/djsite/ --module django_wsgi --static-map=/static=static
此时,页面样式就正常了。
5.3. 高级启动
1、新建uwsgi.ini,与manage.py在同一级目录。
1 | [uwsgi] |
2、启动uwsgiuwsgi uwsgi.ini
3、测试访问
http://ip:8000/blog/index
6. 使用supervisor管理
6.1. 守护uwsgi
1、在/etc/supervisor中新建djsite.conf文件:
1 | [program:djsite] |
2、重启supervisor
1 | ps aux | grep supervisord |
附:重启djsite命令
1 | supervisorctl -c /etc/supervisord.conf restart djsite |
3、测试访问
http://ip:8000/blog/index
页面显示正常,至此守护进程配置成功。
4、djsite.conf可以精简修改为:
1 | [program:djsite] |
6.2. 静态资源问题(可忽略)
假设,uwsgi.ini为:
1 | [uwsgi] |
静态资源就无法访问了。在不添加static-map的情况下,需要修改两个文件:
(1)修改djsite/djsite/settings.py文件,添加:
1 | STATIC_ROOT = '/home/web/djsite/static/' |
(2)修改djsite/djsite/settings.py文件为:
1 | from django.conf.urls import url,include |
6.3. admin静态资源问题
如果以python manage.py runserver
启动django,那么静态资源没有问题。
如果以uwsgi启动django,静态资源看起来没有问题,但是,如果访问 http://ip:8000/admin ,就会发现这个页面的静态资源无法获取。
一个Django应用,一般有两类静态文件。一是应用内的静态文件,二是Django自带的静态文件。应用内的静态文件在djsite/static目录下。此外,在INSTALLED_APPS中配置了django.contrib.admin, 则还会有另外一组静态文件,在Django安装位置里。
例如,一个root在Python 3.6版本安装的Django,admin的静态文件在: /usr/local/lib/python3.6/site-packages/django/contrib/admin/static/admin/。
最终,在STATIC_URL里,会有两类静态文件, /static/*
与 /static/admin/*
。
了解原理,原因就很显然了。python manage.py runserver
知道静态文件的位置,而uWSGI不知道静态文件在什么位置。
解决办法如下:
(1)修改djsite/djsite/settings.py文件:
1 | SITE_ROOT = os.path.dirname(os.path.abspath(__file__)) |
(2)收集所有静态文件到collectedstatic目录python manage.py collectstatic
(3)修改uwsgi.ini配置
1 | [uwsgi] |
7. nginx+uwsgi
以上,我们的djsite项目已经通过uwsgi方式启动起来,并且可以保持后台运行。nginx配置不改变的情况下,我们可以正常访问 http://django.voidking.com/blog/index 。此时,nginx作为反向代理,和uwsgi间通过http交互。
接下来,就配置下nginx和uwsgi通过socket结合的方式。原理:用户发送http请求到nginx,nginx通过socket把请求交给uwsgi,uwsgi拿到django的处理结果,通过socket返还给nginx,nginx通过http返回结果给用户。
1、因为nginx和uwsgi通过socket方式交互,我们需要修改uwsgi.ini的配置为:
1 | [uwsgi] |
2、重启supervisorsystemctl stop supervisord
systemctl start supervisord
3、修改nginx配置djsite.voidking.com.conf:
1 | server { |
5、重启nginx./nginx -s reload
6、测试访问
此时,访问 http://ip:8000/blog/index 失败,访问 http://django.voidking.com/blog/index 正常。因为8000端口不再提供http服务,而是一个和nginx连接的socket。
8. 加速静态资源
1、修改nginx配置djsite.voidking.com.conf:
1 | server { |
2、修改nginx.conf
1 | user root; |
3、重启nginx./nginx -s reload
9. 小结
至此,django部署完毕,我们实现了三种部署方法:
- nginx + django(http方式)
- nginx + uwsgi(http方式)
- nginx + uwsgi(socket方式)