第一篇(准备工作):【django云服务器部署流程(1)】django+uwsgi+nginx:准备工作
·写在前面:
近期参加比赛需要制作小程序,本人负责后端,所以在学习django的搭建和部署,前期还算顺利,但是在使用华为云(学校申请的代金券用不完了)的云耀云服务器部署的时候,静态文件没法在网页访问到,于是查阅了很多资料,包括各种教程与错误的解决,应该看了几百个博客,所以下面我不单独列举这些资料了,只把我觉得重要的写下来。
·再次强调:
本人的这篇文章不是讲原理的,因为我也不懂,只是把我在学习及部署中的过程与遇到的问题做一个分享,流程不一定严格如此,仅供参考,部分步骤可换顺序。
根据之前做的准备工作,把项目上传到服务器以后还无法直接正常运行,项目所依赖的库需要进行安装,为了避免版本不兼容的情况,此处使用的是【准备工作】中导出的环境依赖文件requirements.txt,由于我在服务器没有创建虚拟环境,所以可以直接在项目根目录输入指令进行安装(自己对照文件挨个安装也行,但没多大必要):
pip install -r requirements.txt
一般来说,项目在本地没有问题的话,在安装完依赖以后就可以运行起来的。进入项目根目录下,执行如下指令(一定注意!!下面用的端口是没被其他进程占用,并且在安全组中添加了该端口):
python manage.py runserver 0:8001
# 如果端口被占用,使用下列指令查看该端口被谁占用
# 可以选择使用其他端口,或者结束占用该端口的进程
ps -ef|grep 进程PID #查看端口占用情况
kill -9 进程PID #结束占用端口的进程
(如果碰到‘sqlite3库不存在的报错,可以参考:’【Python库—sqlite3】ModuleNotFoundError: No module named ‘_sqlite3‘)
大家在本地运行的时候应该已经用过这指令了,这里不再赘述。我的测试结果如下:
上述结果也可以看到,静态资源的访问是无法访问的(如果你的settings.py里面的DEBUG设置为True则不会这样),其他正常,这就表明你的项目在服务器成功运行起来了。(搜到的资料说django框架仅在开发模式下提供静态文件服务:开启DEBUG模式时,django的内置服务器提供静态文件服务;关闭DEBUG模式后,django便不提供静态文件服务了。这个问题我当时没能解决,后来看到有人使用配置路由的方式解决,但是由于我后续使用uwsgi+nginx,所以也没测试这样的方法可不可行,仅给大家提供方向,有兴趣的可以尝试一下)
我知道的Linux安装uwsgi有两种方式,一种是使用Linux指令,一种是使用python的pip指令,本人采用后者,指令如下:
pip install uwsgi
如果想验证uwsgi的服务是否正常,可以使用下列指令进行检验,如果运行下列指令并未报错,并且在浏览器可以看到自己创建的页面(看不到静态资源正常),那么你的uwsgi应该是没问题的:
# 8001端口的要求与第二步的端口要求一致,大家可自行更改
# /root/test1为项目根目录
# test1.wsgi为项目自带的wsgi.py文件,test1为上一级目录
uwsgi --http :8001 --chdir /root/test1 -w test1.wsgi
在项目根目录下创建一个uwsgi.ini文件,使用vi或者vim指令进行编辑,或者直接使用vim指令,编写完成后保存退出即可(进入文件后按 ‘i’ 进行编辑,编辑完成后按esc→ ‘:’ → ‘w’ → ‘q’ → 回车),本人采用的指令及配置内容如下(只是一些基本配置,更多的配置大家可以根据需要自行搜索补充):
vim uwsgi.ini #编辑uwsgi.ini文件,没有的话会自动创建
#下列是uwsgi.ini文件的内容,第一行的[uwsgi]必须写
[uwsgi]
# 使用http访问,0表示任何IP,8001表示端口号,要求同上
http=0:8001
# 项目的绝对路径
chdir=/root/test1
# 项目的wsgi.py文件,如果你怕写乱,此处建议写绝对路径
wsgi-file=/root/test1/test1/wsgi.py
# 允许主线程存在
master=true
# 开启进程的数量
processes=1
# 开启多线程
enable-threads=false
# 当服务器退出的时候自动清理环境,删除socket文件和pid文件
vacuum=true
# 使进程在后台运行,并将日志打到指定的日志文件
daemonize=uwsgi.log
# 指定pid文件的位置,记录主进程的pid号,主要用于关闭服务
pidfile=uwsgi.pid
使用下述指令进行uwsgi配置文件的测试:
# 开启uwsgi,可通过浏览器进行验证
uwsgi --ini uwsgi.ini
# 关闭uwsgi,需要使用到配置文件中指定的路径下的pid文件,该文件在开启uwsgi后会自动创建
uwsgi --stop uwsgi.pid
开启uwsgi后进入浏览器,可以看到,除了静态资源都可以正常访问,而静态资源的访问结果如下,这种情况表示你的uwsgi是没有问题的,并且你的配置文件也是正确的:
▲ 我在第一次配置的时候,由于知识面不够广,一直以为是我的uwsgi配置错了,所以我一直在搜资料怎么正确配置uwsgi才能访问静态资源。部署完项目后,我回过头搜索资料,找到几个方法,下面提供一个简洁的,大家可以参考,但是由于后续会配置nginx,所以跳过这个调整也可。这种方法是在uwsgi.ini文件内增加一个配置(一定注意,第二个等号后面没有空格!!!):
# 为项目增加静态资源映射
static-map = /'浏览器访问的目录'='静态资源文件夹路径'
# 我写的是: static-map = /static_new=/root/pycharm/static
这个映射表示:输入‘浏览器访问目录’后,自动去‘静态资源文件夹路径’下寻找文件:
我看到有些资料讲,settings.py中的STATIC_URL是用于引用STATICFILES_DIRS或STATIC_ROOT所指向的静态文件的,DEBUG=True时,其引用的是STATICFILES_DIRS;而DEBUG=False时则引用STATIC_ROOT。并且有人提到,不收集静态资源的话,css、img、js的样式可能会失效(执行下列指令后可以看到,新收集的静态资源里面比原来的静态资源多一个admin文件),相关的原理讲解也挺多的,大家感兴趣也可以研究一下。步骤如下:
# 在settings.py文件中增加一句代码如下。配置完成后 STATIC_ROOT=项目根目录+"文件路径"
STATIC_ROOT = os.path.join(BASE_DIR, "文件路径")
# 配置完保存退出,执行下列指令收集静态资源
# 它会把原来的静态资源收集到上述代码配置的文件中,并且还会多一个admin文件夹
python manage.py collectstatic
这是我认为使用uwsgi+nginx部署django项目最关键的一步。
如果使用apt-get安装报错,可能是因为没有nginx的安装源,可以通过增加安装源,或者手动下载安装包进行安装。
# 更新apt-get
sudo apt-get update
# 安装nginx
sudo apt-get install nginx
# 验证配置是否正确,不正确会报错。也可以看到默认的配置文件,建议大家记录一下
nginx -t
# 查看nginx版本(详细版本用指令:nginx -V)
nginx -v
# 启动nginx(我的好像是安装就已经启动了)
service nginx start #或者 start nginx
# 快速停止nginx
nginx -s stop
# 正常关闭nginx
nginx -s quit
# 配置文件修改重装载命令
nginx -s reload
进行完上述操作,都正常的话,就可以在浏览器输入你的IP(默认使用80端口,该端口可以不加)看到如下显示(如果看不到,可以检查一下你的80端口是否被占用、安全组是否添加80端口):
配置nginx过程中我遇到了非常多的坑,一开始不了解nginx的基本原理,跟着各种教程乱配,以及软连接的创建,导致我没有备份nginx的原始配置文件就把它修改了,我不知道怎么改回去,其次是我创建了软连接(后面我使用了个人感觉比较安全的方法,但是有一点点麻烦,不过至少避免了乱创软连接导致的混乱),水平有限我也不知道原来指向哪里,所以没法修改回去,没办法我只能把nginx卸载重装了。
步骤:如果安装nginx与验证过程中没有出现错误,就直接按照下面的操作进行
uwsgi --stop uwsgi.pid
nginx -s stop
socket = 0.0.0.0:8002 #复制时删掉注释;0.0.0.0表示所有IP,端口需要选用空闲端口
user root; #设置权限,后面会讲这个问题
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types; #这个文件有的教程说复制到项目根目录,我写了绝对路径
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
#下面两行是nginx的请求与错误日志,路径自行设计,可查看其内容修改bug
access_log /var/log/nginx/access1.log;
error_log /var/log/nginx/error1.log;
gzip on;
upstream django {
server 127.0.0.1:8002; #这个地方很重要,需要用与步骤1.2中写的端口一致
}
server{
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
listen 8001; #监听端口,浏览器访问的就是这个端口
server_name 1**.**.**.**5; #你的服务器IP
client_max_body_size 75M;
charset utf-8;
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params; #这个可以根据自己nginx的文件找到在哪
}
location /static_new/ { #配置静态资源,此处写什么,在浏览器访问就需要写什么
alias /root/test1/static_new/; #静态资源的绝对路径,最后的/一定要加
}
location /templates/ {
alias /root/test1/templates/;
}
}
}
uwsgi --ini uwsgi.ini
# 此处的配置文件为1.3创建的文件;-c 表示加载配置文件启动
sudo nginx -c /root/test1/my_nginx.conf
# 如果后续再次修改配置文件,可再次使用这个命令,如果报错,则使用2.2的指令重新加载一次
nginx -s reload
根据前面配置的端口、目录,在浏览器进行访问(关键是静态资源)
通过上图可以看到,项目已经按照前面的配置部署好了,同样是访问8001/static_new/1.jpg,结果与uwsgi配置静态资源映射时得到的结果不同,也表示项目的部署是OK的,至此,该项目在云服务器的部署已经完成。
以上就是部署项目的相关过程,希望这篇文章能给大家带来一些帮助,也希望大佬能不吝赐教,如果文中有问题感谢大家积极指证,非常感谢大家,有疑问可以提问~。
本篇文章的前一篇(准备工作):【django云服务器部署流程(1)】django+uwsgi+nginx:准备工作
新增(完整流程):【django云服务器部署】django+uwsgi+nginx 部署的完整流程