基于centos7+nginx+uwsgi+python3+django2.0部署Django项目
0、序言
本文讲解如何基于centos7+nginx+uwsgi+python3+django2.0把windows上的本地项目部署到云服务器上。
本文服务器上的django项目和虚拟环境的路径将建立在 /home路径下,项目名为"BlogProject",虚拟环境名为"py3.6env"。
对于Django部署而言,nginx和uWSGI是不错的选择,但它们并非唯一的选择,也不是“官方”选择。对于它们两个,都有不错的替代品,因此鼓励你去详细研究一下。
nginx (发音为 engine-x) 是一个免费开源并且高性能的HTTP服务器和反向代理,还是一个IMAP/POP3代理服务器。
web服务器软件:可以向浏览器等web客户端提供文件 (HTML, 图像, CSS等等)。常用的软件有Apache,Nginx,IIS(在windows系统使用)。
一、概念
一个web服务器面对的是外部世界。它能直接从文件系统提供文件 (HTML, 图像, CSS等等)。然而,它无法“直接”与Django应用通信;它需要借助一些工具的帮助,这些东西会运行运用,接收来自web客户端(例如浏览器)的请求,然后返回响应。
一个Web服务器网关接口(Web Server Gateway Interface) - WSGI - 就是干这活的。 WSGI 是一种Python标准。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask,Django框架写的程序)通信的一种规范。
uWSGI是一种WSGI实现。本文我们将设置uWSGI,让它创建一个socket,并且通过WSGI协议提供响应到web服务器。
二、安装环境
OS:centos7.6
python版本:python3.6.5
django版本:Django2.0
uwsgi版本:使用本文发布时最新的2.0.18
nginx版本:使用本文发布时官网最新的1.15.11
三、安装Python3.6
1.不要删除自带的python2.7,否则会出问题,因为centos许多软件需要依赖系统自带python
2.安装依赖工具 (安装这些模块都是为了成功编译安装python3,防止出现各种异常)
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel mysql-devel gcc gcc-devel python-devel
3.下载
wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz
4.解压
tar -zxvf Python-3.6.5.tgz
5.移动至规范的放软件的目录下
mv Python-3.6.5 /usr/local
6.安装
cd /usr/local/Python-3.6.5/ ./configure make make install
./configure命令没有指定安装路径,则默认安装在/usr/local/bin,如果指定安装路径,则命令为./configure --prefix=/usr/local/python3。
安装完成之后,网上很多教程都说要建立软链接 添加变量 才能在终端中直接使用python3,但是我这里不用建立软链接,可直接在终端中直接使用python3.
pip3也不用建立软链接,可直接在终端中直接使用pip3
7.验证版本号
python3 -V
四、虚拟环境
1.安装虚拟环境virtualenv,建议大家都安装一个virtualenv,方便不同版本项目管理。
系统已经帮我们安装好virtualenv,可不用安装直接使用
2.创建虚拟环境virtualenv
在/home路径下,创建虚拟环境,这里的路径大家可以自己选择,我习惯建在/home路径下。也可以在根目录下建立两个文件夹env和BlogProject(项目路径 ),主要用于存放env和网站文件的
virtualenv py3.6env
3.进入虚拟环境
source /home/py3.6env/bin/activate
红色方框出现(py3.6env),说明是成功进入虚拟环境。
五、安装uwsgi
1.系统上安装uwsgi
pip3 install uwsgi
2.虚拟环境上安装uwsgi
进入虚拟环境,执行安装命令
pip3 install uwsgi
注意:uwsgi要安装两次,先在系统里安装一次,然后进入对应的虚拟环境安装一次。
安装完成后查询uwsgi安装情况,如图所示,则安装成功。
同样这里也不用建立软链接,可以直接在终端使用uwsgi。
3.验证
在/home/路径下建立test.py,输入以下内容:
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello Django"]
执行命令
uwsgi --http :8001 --wsgi-file test.py
浏览器访问,网页能显示 Hello Django 那么就没问题。((记得关闭系统防火墙或者在服务器安全组开放8001端口))
六、本地项目搬迁到服务器
1.备份本地数据库。
使用sqlite数据库的话,直接打包数据库文件(db.sqlite3)上传到服务器即可。
使用Mysql数据库,要先在本地Mysql里备份导出数据,然后在服务器上安装Mysql数据库软件。
mysqldump -u 用户名 - p 数据库名 > data.sql #备份导出数据
ps:服务器上安装Mysql数据库软件,请参考:CentOS7 安装并配置MySQL8.0
2.在本地项目目录下用下面的命令把当前的环境依赖包导出到requirements.txt文件。
pip3 freeze > requirements.txt
3.把项目源码(包括数据库文件,环境依赖包文件)压缩打包,上传到服务器对应的目录里(这里在git bash里使用scp命令上传数据到服务器),解压。
scp BlogProject.zip root@“服务器IP地址”:/home/BlogProject.zip #传输到home路径下
4.进入刚才步骤三创建的虚拟环境,然后进入项目路径安装requirements.txt里的依赖包。
pip3 install -r requirements.txt
5.导入数据库到服务器。(如果用的是Mysql的话)
默认使用的是SQLite数据库,就不用做此操作。数据库原来是SQLite的,想换成Mysql,请查看文章:Django中把SQLite数据库转换为Mysql数据库的配置方法
如果是Mysql数据库的,则在命令行里输入:
#把上传到服务器的data.sql,在服务器里用下面命令导入 mysql -u 用户名 -p 你的密码 use 数据库名; #这里的数据库名要项目中的settings.py文件的数据库名一致 source /home/data.sql #导入数据库文件
6.运行一下项目,如果能正常启动,在浏览器里访问服务器地址(域名),就能查看到项目,则进行下一步,不能正常运行往上检查
python3 manage.py runserver 0.0.0.0:80
ps:如果在云服务器上没有为80端口设定安全组,则不能在浏览器访问。
七、Django正常运行之后我们就开始配置一下uwsgi。
我们网站项目路径是 /home/BlogProject,在/home路径下新建文件夹BlogProject_uwsgi,专门存在uwsgi配置文件,日志文件,进程文件,另外也可以直接在项目根目录下创建BlogProject_uwsgi.ini文件,这里我选择新建文件夹。
在/home/BlogProject_uwsgi路径下新建BlogProject_uwsgi.ini文件
#BlogProject_uwsgi.ini [uwsgi] # 通过uwsgi访问django需要配置成http # 通过nginx请求uwsgi来访问django 需要配置成socket # web项目根目录 chdir = /home/BlogProject #虚拟环境的目录 home = /home/py3.6env # module指定项目自带的的wsgi配置文件位置 module = BlogProject.wsgi # 允许存在主进程 master = true # 开启进程数量 processes = 4 #每个进程的最大请求时间 harakiri = 60 #每个进程的最大请求数 max-requests = 5000 # 8001是内部端口,是django的端口号 socket = 127.0.0.1:8001 #用户id uid = 1000 #组id gid = 2000 #存放进程文件的目录 pidfile = /home/BlogProject_uwsgi/master.pid #存放日志文件的目录 daemonize = /home/BlogProject_uwsgi/BlogProject.log # 服务器退出时自动清理环境 vacuum = true
BlogProject_uwsgi.ini里面参数的设定可参考官方文档https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/uwsgi/。
八、安装nginx和配置nginx.conf文件
进入home目录,执行下面命令
cd /home/
wget http://nginx.org/download/nginx-1.13.7.tar.gz
下载完成后,执行解压命令:
tar -zxvf nginx-1.15.11.tar.gz
移动至规范的放软件的目录下
mv nginx-1.15.11 /usr/local
安装,进入解压后的nginx-1.15.11文件夹,依次执行以下命令:
cd /usr/local/nginx-1.15.11/ ./configure make make install
nginx一般默认安装好的路径为/usr/local/nginx
在/usr/local/nginx/conf/中先备份一下nginx.conf文件,以防意外。
cp nginx.conf nginx.conf.bak
然后打开nginx.conf,把原来的内容删除,直接加入以下内容:
events{ worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; server { listen 80; #80是对外的端口号 server_name 47.112.128.209:80; #nginx代理uwsgi对外的ip,改为自己的域名,没域名修改为服务器ip地址 charset utf-8; location /static/ { alias /home/BlogProject/static/; #静态资源路径 } location /media/ { alias /home/BlogProject/media/; # #媒体资源路径 } location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8001; #端口要和uwsgi里配置的一样 } } }
- 80是对外的端口号
- server_name:nginx代理uwsgi对外的ip
- 127.0.0.1:8001即当nginx收到80端口的请求时,直接将请求转发给 127.0.0.1:8001
要留意备注的地方,要和UWSGI配置文件BlogProject_uwsgi.ini,还有项目路径对应上。
进入/usr/local/nginx/sbin/目录
执行./nginx -t命令先检查配置文件是否有错:
如果出现上图红色方框的内容,则代表没有错,就执行以下命令,启动nginx:
./nginx
或者执行:
/usr/local/nginx/sbin/nginx #启动nginx
终端没有任何提示就证明nginx启动成功。可以使用你的服务器地址查看,成功之后就会看到一个nginx欢迎页面。
留意:一定要注意Uwsgi和Nginx配置文件里的项目路径和静态资源路径,填写正确了才能成功访问。不然会出现502错误。还有就是,修改Django文件和其它配置文件之后,一定要重启Uwsgi和Nginx,不然不生效。
之后,在settings.py里设置:(如果之前在本地项目设置过,可不用再设置)
a、关闭DEBUG模式。
DEBUG = False
b、ALLOWED_HOSTS设置为* 表示任何IP都可以访问网站。
ALLOWED_HOSTS = ['*']
九、访问项目的页面
1.启动uwsgi
uwsgi --ini /home/BlogProject_uwsgi/BlogProject_uwsgi.ini
执行完命令,如下图所示
查看uwsgi是否启动
ps -aux | grep uwsgi
如下图所示,表示uwsgi启动成功。
以上步骤都没有出错的话。
进入/usr/local/nginx/sbin/目录
执行:
./nginx -s reload
或者执行:
/usr/local/nginx/sbin/nginx -s reload
重启nginx 。
执行命令,查询nginx是否启动
ps -aux | grep nginx
如下图所示,表示nginx启动成功。
然后在浏览器里访问你的项目地址! (记得关闭系统防火墙或者在服务器安全组开放80端口)
访问之前建立的文件夹BlogProject_uwsgi,可以看到自动生成了日志文件(BlogProject.log)和进程文件(master.pid)。
我们可以利用进程文件(master.pid)进行uwsgi的重启,停止。
uwsgi --stop /home/BlogProject_uwsgi/master.pid #关闭uwsgi进程 uwsgi --reload /home/BlogProject_uwsgi/master.pid #重新加载uwsgi进程
除了利用进程文件(master.pid)进行uwsgi的开启,重启,停止,uwsgi还有以下方法进行操作。
Uwsgi和Nginx重启方法:
ps -aux | grep uwsgi ##查看Uwsgi进程,是否启动 killall -9 uwsgi #用kill方法把uwsgi进程杀死,然后启动uwsgi uwsgi --ini /home/BlogProject_uwsgi/BlogProject_uwsgi.ini #启动uwsgi ps -aux | grep nginx ##查看nginx进程,是否启动 killall -9 nginx #用kill方法把nginx进程杀死 /usr/local/nginx/sbin/nginx #启动ngnix /usr/local/nginx/sbin/nginx -s reload #Nginx平滑重启方法
# nginx另外一种方式停止
/usr/local/nginx/sbin/nginx -s stop # 强制停止
/usr/local/nginx/sbin/nginx -s quit # 优雅停止
关于线上部署admin后台样式没有生效的问题:
方法一:
1、在settings.py尾部:
STATIC_ROOT = os.path.join(BASE_DIR, 'BlogProject_collected')#指定样式收集目录
#或者
STATIC_ROOT = '/home/BlogProject/BlogProject_collected' #指定样式收集目录
2、收集CSS样式,在终端输入:
python manage.py collectstatic
运行这个命令之后,就会自动把后台CSS样式收集到/BlogProject_collected/目录下,如图所示。刷新页面就能恢复样式!
方法二:
在Python安装目录下(如果使用虚拟环境,则在虚拟环境目录下)找到\Lib\site-packages\django\contrib\admin\templates目录,把里面的admin目录复制到指定目录即可。
注意:以上两种方法在收集或复制前一定先在settings里配置并指定STATIC_ROOT路径,STATIC_ROOT路径可以自己定。指定的时候一定要在settings.py和nginx里指定新的路径。不然无法生效。
关于图片上传不到服务器,500错误 :
原因:上传文件的目录及其子目录没有写的权限。
解决方法:运行以下代码,给media目录及其子目录设定rwx权限。
chmod -R 777 media #-R表示递归设置权限
关于日志文件的读写权限问题:
运行以下代码, 给BlogProject_debug.log设定rw权限。
chmod 666 BlogProject_debug.log