【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目

第一篇(准备工作):【django云服务器部署流程(1)】django+uwsgi+nginx:准备工作
·写在前面:
近期参加比赛需要制作小程序,本人负责后端,所以在学习django的搭建和部署,前期还算顺利,但是在使用华为云(学校申请的代金券用不完了)的云耀云服务器部署的时候,静态文件没法在网页访问到,于是查阅了很多资料,包括各种教程与错误的解决,应该看了几百个博客,所以下面我不单独列举这些资料了,只把我觉得重要的写下来。
·再次强调:
本人的这篇文章不是讲原理的,因为我也不懂,只是把我在学习及部署中的过程与遇到的问题做一个分享,流程不一定严格如此,仅供参考,部分步骤可换顺序。

整体结构:
【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目_第1张图片
部署流程:

  • 准备工作:准备工作
  • 部署项目:
    部署

    目录

    • 【部署项目】
      • 1. 安装项目依赖
      • 2. 测试项目(可能会碰到静态资源无法访问的问题)
      • 3. 安装、配置、测试uwsgi:
        • 安装:
        • 配置:
        • 测试:
      • 4. 修改配置文件,收集静态资源
      • 5. 安装、配置、测试nginx:
        • 安装:
        • 配置:
          • (1) 在项目根目录下,配置文件
          • (2) 启动服务
        • 测试:
      • 6. 一些注意点以及问题的解决方法
      • 7. 结语
    • 【参考资料】

【部署项目】

1. 安装项目依赖

根据之前做的准备工作,把项目上传到服务器以后还无法直接正常运行,项目所依赖的库需要进行安装,为了避免版本不兼容的情况,此处使用的是【准备工作】中导出的环境依赖文件requirements.txt,由于我在服务器没有创建虚拟环境,所以可以直接在项目根目录输入指令进行安装(自己对照文件挨个安装也行,但没多大必要):

pip install -r requirements.txt

2. 测试项目(可能会碰到静态资源无法访问的问题)

一般来说,项目在本地没有问题的话,在安装完依赖以后就可以运行起来的。进入项目根目录下,执行如下指令(一定注意!!下面用的端口是没被其他进程占用,并且在安全组中添加了该端口):

python manage.py runserver 0:8001
# 如果端口被占用,使用下列指令查看该端口被谁占用
# 可以选择使用其他端口,或者结束占用该端口的进程
ps -ef|grep 进程PID  #查看端口占用情况
kill -9 进程PID    #结束占用端口的进程

(如果碰到‘sqlite3库不存在的报错,可以参考:’【Python库—sqlite3】ModuleNotFoundError: No module named ‘_sqlite3‘)
大家在本地运行的时候应该已经用过这指令了,这里不再赘述。我的测试结果如下:
hello
【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目_第2张图片

上述结果也可以看到,静态资源的访问是无法访问的(如果你的settings.py里面的DEBUG设置为True则不会这样),其他正常,这就表明你的项目在服务器成功运行起来了。(搜到的资料说django框架仅在开发模式下提供静态文件服务:开启DEBUG模式时,django的内置服务器提供静态文件服务;关闭DEBUG模式后,django便不提供静态文件服务了。这个问题我当时没能解决,后来看到有人使用配置路由的方式解决,但是由于我后续使用uwsgi+nginx,所以也没测试这样的方法可不可行,仅给大家提供方向,有兴趣的可以尝试一下)

3. 安装、配置、测试uwsgi:

安装:

我知道的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是没有问题的,并且你的配置文件也是正确的:
【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目_第3张图片
我在第一次配置的时候,由于知识面不够广,一直以为是我的uwsgi配置错了,所以我一直在搜资料怎么正确配置uwsgi才能访问静态资源。部署完项目后,我回过头搜索资料,找到几个方法,下面提供一个简洁的,大家可以参考,但是由于后续会配置nginx,所以跳过这个调整也可。这种方法是在uwsgi.ini文件内增加一个配置(一定注意,第二个等号后面没有空格!!!):

# 为项目增加静态资源映射
static-map = /'浏览器访问的目录'='静态资源文件夹路径'
# 我写的是:  static-map = /static_new=/root/pycharm/static

这个映射表示:输入‘浏览器访问目录’后,自动去‘静态资源文件夹路径’下寻找文件:
【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目_第4张图片

4. 修改配置文件,收集静态资源

我看到有些资料讲,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
  • 需要注意,这个文件的绝对路径与之前的静态资源的绝对路径不能相同

5. 安装、配置、测试nginx:

这是我认为使用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端口):
【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目_第5张图片

配置:

配置nginx过程中我遇到了非常多的坑,一开始不了解nginx的基本原理,跟着各种教程乱配,以及软连接的创建,导致我没有备份nginx的原始配置文件就把它修改了,我不知道怎么改回去,其次是我创建了软连接(后面我使用了个人感觉比较安全的方法,但是有一点点麻烦,不过至少避免了乱创软连接导致的混乱),水平有限我也不知道原来指向哪里,所以没法修改回去,没办法我只能把nginx卸载重装了。
步骤:如果安装nginx与验证过程中没有出现错误,就直接按照下面的操作进行

(1) 在项目根目录下,配置文件

  • (1.1) 停止前面开启的uwsgi、nginx
uwsgi --stop uwsgi.pid
nginx -s stop
  • (1.2) 使用vim对uwsgi.ini做出修改:注释http和static-map这两行,添加:
socket = 0.0.0.0:8002  #复制时删掉注释;0.0.0.0表示所有IP,端口需要选用空闲端口
  • (1.3) 使用 vim my_nginx.conf 指令创建、编辑my_nginx.conf,内容如下。文件名随意,复制时删掉注释,建议先复制到本地,修改完成再在Xshell操作
    此处的配置的规则就是,将nginx -t指令得到的nginx的默认配置文件中的全部复制,粘贴到新建的文件中,删掉其中include开头 .conf结尾的行;并且将server{ }部分更改为下述内容(如果没有这个模块则直接将其添加到http{ }中即可)。
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/;
                }
        }
}

(2) 启动服务

  • (2.1) 启动uwsgi
uwsgi --ini uwsgi.ini
  • (2.2) 加载nginx配置文件,加载过一次即可(避免建立软连接,时间久了造成混乱;但也有人说这方法不靠谱,大家自行选择吧
# 此处的配置文件为1.3创建的文件;-c 表示加载配置文件启动
sudo nginx -c /root/test1/my_nginx.conf  
  • (2.3) 重新加载nginx
# 如果后续再次修改配置文件,可再次使用这个命令,如果报错,则使用2.2的指令重新加载一次
nginx -s reload

测试:

根据前面配置的端口、目录,在浏览器进行访问(关键是静态资源)
hello
【django云服务器部署流程(2)】django+uwsgi+nginx:部署项目_第6张图片

通过上图可以看到,项目已经按照前面的配置部署好了,同样是访问8001/static_new/1.jpg,结果与uwsgi配置静态资源映射时得到的结果不同,也表示项目的部署是OK的,至此,该项目在云服务器的部署已经完成。

6. 一些注意点以及问题的解决方法

  • 1.不管在配置哪一个模块,如果使用到端口,一定确保自己使用的端口是未占用的,如果需要在浏览器访问,则还需要在服务器的安全组内添加该端口。
  • 2.由于uwsgi与nginx之间使用socket进行通信,所以注释uwsgi.ini文件中的http,而配置socket,并且需要注意,此处的端口号一定要与nginx的配置文件中的端口相同。
  • 3.nginx配置文件中,如果不是root用户,会由于权限不够而导致浏览器访问静态资源时显示403 Forbidden。
  • 4.配置nginx配置文件时,location /static_new/写的是什么路径,在浏览器访问时就要用什么路径;alias /root/test1/static_new/中最后的/一定要加,不然浏览器会显示404 Not Found。(3和4的具体讲解在:【uwsgi+nginx部署django项目】nginx配置文件的一些问题)
  • 5.我个人认为,使用上述方式启用nginx服务,避免了对原始配置文件的修改,也避免了软连接的创建(主要是一开始我配置了软连接,但不理解,所以修改了一些文件并没有生效,没办法了我进行了重装),虽然看到有人讲这样不太好用,但是我并未碰到那种情况,有问题的话恳请大家指正。
  • 6.在nginx的原始配置文件中有许多include项,其中.conf表示加载了其他的配置文件,由于我自己写的配置文件的内容已经比较全了,而且为了避免多个配置文件之间的冲突,在新建的nginx配置文件中,将.conf结尾的行全部删掉。

7. 结语

以上就是部署项目的相关过程,希望这篇文章能给大家带来一些帮助,也希望大佬能不吝赐教,如果文中有问题感谢大家积极指证,非常感谢大家,有疑问可以提问~。
本篇文章的前一篇(准备工作):【django云服务器部署流程(1)】django+uwsgi+nginx:准备工作
新增(完整流程):【django云服务器部署】django+uwsgi+nginx 部署的完整流程

【参考资料】

  • 【教程】Nginx + uWsgi 部署 Django + Mezzanine 生产服务器 → B站视频讲解
  • django+uWSGI+nginx的工作原理流程与部署过程

你可能感兴趣的:(后端开发,Python,django,nginx,python,云服务器,华为)