centos7下部署Django(nginx+uwsgi+python3+django)

先连接服务器,使用命令行里面的ssh root@xxx  即可连接,这里的“xxx”就是服务器IP地址,会车后会提示输入密码,密码输入的时候是被隐藏的,输完即可连接服务器,然后进行命令行操作。

我们的python有现成的部署虚拟环境,这个东西,你下载好之后,不同的项目用到的是不一样的环境版本配置,为了更好的做隔离,需要用这个虚拟环境做区分。

这个虚拟环境是需要安装的,要安装到服务器中之后,才能基于它,使用下面的命令,然后配置你所需要的文件。我这里没有写安装过程,日后补上。

virtualenv

linux下virtualenv其它命令

列出虚拟环境列表

workon

也可以使用lsvirtualenv

新建虚拟环境

mkvirtualenv [虚拟环境名称]

启动/切换虚拟环境

workon [虚拟环境名称]

删除虚拟环境

rmvirtualenv [虚拟环境名称] 

 

我们项目部署需要用到uwsgi,它可以开启多进程,启动多个uwsgi实例,然后让nginx来做静态文件处理,以及负载均衡和反向代理.

{启动多个uwsgi通过nginx做集群,静态文件放到nginx,静态请求通过nginx直接相应,动态请求转发给uwsgi,如果在Windows上开发的话,配置了虚拟环境,否则安装一些python包和依赖会有问题}

 

接上面的虚拟环境virtualenv



yum install lrzsz
nginx里面可以做反向代理,负载均衡(LVS更大平台做做负载均衡,haproxy也是),处理静态文件,
uwsgi处理动态请求
linux里面命令后加上&符号都是在后台运行
tornado里面部署只需要用nginx就可以,



在安装python前先安装各类基础模块
yum install gcc-c++
yum install wget openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel
yum install libxml*
yum -y install zlib*
yum remove lrzsz -y yum install lrzsz -y 关闭防火墙 systemctl stop firewalld ———————————————————————————————- 编译安装python3 mkdir /application/ cd /application/ wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz tar xf Python-3.6.3.tgz -C /usr/local/src/ cd /usr/local/src/Python-3.6.3/ ./configure –prefix=/usr/local/python3 make && make install



 

连上服务器之后先进入为项目新建的虚拟环境中,然后在git上把项目拉下来,这里用git是比较方便的,用其他方法也行,比如硬拖拽也可以,下一些依赖包即可。

然后在服务器的虚拟环境中生成requirements.txt文件,建议使用



pipreqs <path>
path是项目路径,在当前路径就用
pipreqs ./



 

一般就能直接生成,我自己遇到过报错,提示ascii编码有问题,后来发现是iTerm编辑器不能显示中文,后来改了iTerm的编码就可以运行了

然后下载项目所需要的包和依赖,在当前路径下载,或者把requirements文件的路径贴到-r后面也一样



pip install -r requirements.txt



 

然后把数据库连接做好,要连上服务器的数据库,ip,端口,库名,数据库用户名,数据库用户密码。

还要做数据库迁移,



python manage.py makemigrations & python manage.py migrate



然后启动文件
python manage.py runserver 0.0.0.0:8000



 

此时应该可以访问到你的项目地址了

将Python代码上传到Gitee_将Python代码上传到Gitee

 

如果有报错,就需要你去排查项目本身的问题了。

 

再来配置uwsgi



pip install uwsgi



 

然后创建一个uwsgi.ini 文件,可以在任何地方,前提是你必须要记住它的绝对路径,它是启动uwsgi服务的启动文件,必须要能清晰地找到它的绝对路径

我是创建在跟项目同级的目录下的

项目目录地址:/data/oldboy/

目录结构如下:

-oldboy

  -app01

  -app02

  -oldboy

    -setting

    -url

    -wsgi.py

  -static

  -templete

 

创建uwsgi文件,



cd /data/

mkdir script

cd script/

touch uwsgi.ini



 

然后在里面加上参数:

先上一个简单版本:



http = 0.0.0.0:9005  # ip:端口
chdir = /data/oldboy/  # 项目根目录 项目名称(oldboy)
wsgi-file = oldboy/wsgi.py  # 项目名称(oldboy)/wsgi.py  --->这里的wsgi.py是Django项目的启动文件(固定的),凡是Django项目,找到setting文件,它同级的有一个wsgi文件,就是它
# 如果是flask项目,就把flask项目的启动文件放这里,因为flask的目录是自定义的,找到Flask类实例化出来的变量名(例“app”),有app.run()这一行命令的文件,它就是启动文件,放到这个参数即可
# flask启动文件也要带上路径
processes = 4  # uwsgi的启动进程数量



 

还需要补充的一点就是module参数,它跟wsgi-file是可以互换的,两者取其一



module=oldboy.wsgi # 跟上面的wsgi-file写法不同,但是格式是一样的,Django项目专用写法。

flask写法:
app = hello  # 这里是写有“app.run()” 的那个启动文件的文件名
module = %(app)  # 然后这里跟上一行同时存在。这个配置还没有试过,先留着。也许有坑。



 

还有一种配置文件参数要更多一些:



[uwsgi]
# 项目目录
chdir=/data/oldboy# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 指定项目的application
module=pro.wsgi
# 指定sock的文件路径,这是跟nginx配合使用的,如果先配置好uwsgi想试一下效果,就把它先注释掉。
socket=/data/script/uwsgi.sock  
# 启用主进程
master=true
# 进程个数
workers=5
pidfile=/data/script/uwsgi.pid
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=4096
# 设置日志目录  (这里遇到坑了,如果还没有配nginx,建议先注释掉,我试过如果不注释掉无法启动uwsgi,按理说逻辑不应该是这样的,解释不通,但是现象如此,大家可以多试试。nginx配好打开注释即可)
daemonize=/data/script/uwsgi.log  
########################################



 

 

我们这里有提示过,daemonize和socket这两个参数先注释掉,然后启动uwsgi服务。此时可以关掉上面python manange.py runserver的服务了。

进入到上面的uwsgi.ini文件的目录下面,执行启动服务命令



uwsgi --ini uwsgi.ini



 

停止服务命令,同上也要在该文件的路径下才可以执行如下命令



uwsgi –stop uwsgi.pid



查看uwsgi日志 # 前提是有日志配置能生成日志 tail -f /data/script/uwsgi.log



 




就能看到如下提示:

*** Starting uWSGI 2.0.17.1 (64bit) on [Mon Mar 25 19:18:37 2019] ***

然后我们在浏览器url里面输入指定的IP端口以及项目中的地址和参数,就可以访问服务了,跟python manage.py runserver一样的效果,页面可以正常访问。

同时我们在项目目录中会看到生成了一个新的文件夹“static_all”,里面是我们的项目里面的静态文件。注意:不能用Django项目自带的static目录,要另外建立一个,不要同名。

到此,uwsgi配置就完成了,主要就是把Django项目静态文件路径加一行配置,然后下载uwsgi模块,创建一个uwsgi.ini文件,然后把必须的参数配好放进去,就能启动uwsgi服务了。

 

接下来就是配置nginx了。后续会补充docker的配置,以及flask项目的配置。

 



先查看有没有装nginx  
nginx -v
如下显示:说明有
nginx version: nginx/1.15.10

没有的话有简易安装方法,用yum



yum install -y nginx



 

 



————————————————————————————————-
编译安装nginx
cd /application/
wget http://nginx.org/download/nginx-1.10.3.tar.gz
yum install pcre-devel openssl-devel -y
tar xf nginx-1.10.3.tar.gz
cd nginx-1.10.3
useradd -s /sbin/nologin -M www
./configure
make &&make install
————————————————————————————————-
编译安装的话,启动命令跟非编译安装是不一样的,小心有坑。



 

 先找到配置文件地址



cd /etc/nginx

ls
找到nginx.conf,然后进行编辑。
如果不想用默认的进行编辑,也可以自己新建立一个文件,放到任何位置都行,重新配置也可以的(不过前提是要把默认的这个文件备份后删除原件,备份的时候另外起个文件名)。
这里是用的原文件编辑的
vim nginx.conf




 

具体参数如下:user root; # 这里用户要写成root,如果写成nobody,有坑,我踩过,改成root就能启动。worker_processes 4; # 进程数




  user root;  # 这里的user参数必须要设成root,否则会无法启动nginx服务,
  worker_processes 4;



events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; server { listen 80; server_name www.phno2.xyz; # 这里是你项目的url地址,或者写成 localhost 也行。 access_log /etc/nginx/logs/django.log; # 这是自己设定的nginx正常输出日志的日志地址 error_log /etc/nginx/logs/errordjango.log; # 也是自己设定的,nginx错误日志地址 charset utf-8; gzip on; error_page 404 /404.html; error_page 500 502 503 504 /50x.html; # 指定项目路径uwsgi location / { include /etc/nginx/uwsgi_params; # 这里的uwsgi_params是系统自带的,路径都是一样的,把路径写完整即可。 uwsgi_connect_timeout 30; uwsgi_pass unix:/data/script/uwsgi.sock; #*****这里是五颗星,必须要改动的,而且是起关键作用的参数。unix: 是固定语法,



# 它后面是uwsgi配置的时候,socket参数后面的值,一定要跟uwsgi配置文件的socket参数保持一致,要一模一样。我这里都是用的sock文件路径,可以直接写IP:port,要写IP:port的话,就uwsgi和nginx



# 在相应的位置都写上IP:port,而且必须是一样的值。
} # 指定静态文件路径 location /static/{ # 这里的static是我们自己后来加上的,用于处理静态文件,这都是固定语法, root /data/oldboy/; # root是必须要写的,之前试过用alias替代root,会报错,找不到静态文件。还有一点是这里只需要写到项目的根目录即可,项目下一级的目录就不必写了,
# 因为在Django配置里面还要加上静态文件的路由分发,如果多写一层会报错,浏览器会找不到静态文件的。亲测有效,都是自己踩过的坑。 } } }



 

 

Django项目的setting文件需要在文件末尾加一条配置项:



STATIC_ROOT = os.path.join(BASE_DIR, "allstatic")



 这是把Django所有的静态文件都收集到了这个文件里面---allstatic,让nginx集中处理用,还要执行下面的命令



cd /data/oldboy/oldboy/ # 找到项目目录下有manage.py文件的那个位置,执行这一条。



python3 manage.py collectstatic



 

然后查看项目,会自动生成一个名为“allstatic”的文件夹。



自此,nginx配置完成。

可以启动项目了。
上面已经启动了uwsgi,这里把uwsgi重新启动,之后,启动nginx



nginx



 

这就是启动命令,我是用yum安装的,用它就能启动(这个命令敲完,屏幕没有任何提示信息,即成功启动,可以去访问项目了,若是有提示信息就是报错了,查日志排错)

如果是编译安装就不是这个命令了,小心有坑。

 

查看nginx的进程



ps -ef |grep nginx

root 16293 14550 0 18:57 pts/1 00:00:00 grep --color=auto nginx  # 这一条不是进程,是你输入上面的命令,系统提示给你的反馈,忽律即可。
root 32466 1 0 13:27 ? 00:00:00 nginx: master process nginx  # master process是主进程,杀进程杀它即可停掉所有的nginx服务
root 32467 32466 0 13:27 ? 00:00:00 nginx: worker process
root 32468 32466 0 13:27 ? 00:00:00 nginx: worker process
root 32469 32466 0 13:27 ? 00:00:00 nginx: worker process
root 32470 32466 0 13:27 ? 00:00:00 nginx: worker process



 

 

停止nginx服务就杀进程即可(uwsgi服务也能杀进程停止服务)



kill 32466



 

在服务器(centos)中nginx默认日志路径



/var/log/nginx/



 

我们用yum装的许多插件,配置文件中默认日志路径就是在



/var/log/

还有一个类似启动文件的文件夹

/var/run/



这个var路径要记住,会很常用,日志在开发过程中,起到很关键的作用。

 

经常在部署时会遇到端口占用问题,这里查询端口占用情况,命令如下



netstat -tunlp |grep 27017



 

总结,核心点就是创建uwsgi配置文件,把核心参数配置好,module/wsgi-file(项目启动文件),chdir(项目根目录),然后设置nginx的配置文件核心参数,uwsgi_pass(跟uwsgi的socket相应的参数值,还有root,以及固定的unix:语法),location /static/ (静态文件路径),user(参数值必须要是root),项目的setting文件再加一个静态文件路径分发,再无其他,项目本身能运行,就已经完成了Django+uwsgi+nginx的所有配置。

 

PS:如果nginx还有media文件需要配置,参考static,逻辑一样。



gunicorn 部署

配置文件gunicorn.conf.py



import os
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
bind = "0.0.0.0:80"
workers = 2
accesslog = os.path.join(base, "check_list_app/flask_logs/access_guni.log")
errorlog = os.path.join(base, "check_list_app/flask_logs/error_guni.log")
pid = os.path.join(base, "check_list_app/flask_logs/pid_guni.log")
daemon = True



如果用配置文件启动服务,命令如下



gunicorn -c/--config gunicorn.conf.py manage:app



 

或者写成shell脚本



gunicorn.sh
#!/bin/bash
gunicorn --bind 0.0.0.0:8080 --workers 2
 --access-logfile ./flask_logs/gunicorn_access.log 
--error-logfile ./flask_logs/gunicorn_error.log 
--pid ./flask_logs/gunicorn_pid.log manage:app &



写成脚本,需要加上权限设置,



chmod u+x gunicorn.sh



直接执行脚本即可

 

最简单的命令行启动服务



gunicorn -b 0.0.0.0:80 manage:app



这里的manage是文件manage.py的名字,这个文件是启动文件,如果你的项目启动文件是run.py ,那么这里就是run:app;

这里的app是我们的项目实例化出来的对象,这里我用的是flask项目示例,所以Flask实例化对象我取名为app,如你的项目是abc = Flask(__name__),那么就替换app成为abc。

个人感觉用gunicorn比uwsgi要方便些。