linux+nginx+uwsgi部署django应用

14 篇文章 0 订阅
9 篇文章 1 订阅
本文详述了如何部署Django项目,包括安装Python、MySQL、Nginx和uWSGI,以及配置虚拟环境、测试uWSGI、管理静态文件和使用uwsgi.ini配置文件启动项目。重点讲解了uWSGI的命令行启动和配置文件启动方法,同时介绍了如何通过Nginx处理静态文件和SSL证书配置。
摘要由CSDN通过智能技术生成

概要

uWSGI是一个用于构建、部署和管理Python Web应用程序的软件工具。它是一个Web服务器网关接口(WSGI)服务器,WSGI是Python应用程序与Web服务器之间的标准接口。

uWSGI 提供了一个统一的接口,使得不同的Web服务器(如Nginx、Apache等)能够与Python应用程序进行通信。它还支持多种协议,包括HTTP、FastCGI等。django应用主要是通过uwsgi来实现和web应用这里是nginx的通信。
在这里插入图片描述

安装python3

https://blog.csdn.net/gsl371/article/details/106708232

安装mysql

见其它文章,推荐使用PostgreSQL
https://blog.csdn.net/gsl371/article/details/78726715

安装nginx

见其它文章
https://blog.csdn.net/gsl371/article/details/93175608

安装virtualenvwrapper

见其它文章
https://blog.csdn.net/gsl371/article/details/117917857

安装uwsgi

在建好的虚拟环境中执行以下安装。ubuntu最新版安装没问题,centos由于不再更新,可能安装中会需要一些依赖。
这个最好用普通用户装。

(djproject) [root@testapi ~]# pip install uwsgi
Collecting uwsgi
  Using cached uWSGI-2.0.19.1.tar.gz (803 kB)
Building wheels for collected packages: uwsgi
  Building wheel for uwsgi (setup.py) ... done
  Created wheel for uwsgi: filename=uWSGI-2.0.19.1-cp36-cp36m-linux_x86_64.whl size=473555 sha256=de8440ec75b75aac34f004e3a78380637770c01aee835948d27cbb4ba07a095f
  Stored in directory: /root/.cache/pip/wheels/3a/7a/c1/492f02e0cde1e39f8b75c79dc5ef3b7e2c93b02e3a7eaabe0c
Successfully built uwsgi
Installing collected packages: uwsgi
Successfully installed uwsgi-2.0.19.1

测试uwsgi

使用测试文件

测试uwsgi,创建test.py文件:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

通过uwsgi运行该文件。

fnngj@ubuntu:~/pydj$ uwsgi --http :8001 --wsgi-file test.py

在这里插入图片描述

管理静态文件

(e.g. images, JavaScript, CSS)
web站点一般包含有若干静态文件,如 images, JavaScript, or CSS。在Django中,我们称之为“static files”。 Django提供了django.contrib.staticfiles 来帮助管理它们。
这一步一般在开发阶段都需要事先完成的。

配置静态文件

  • 确认django.contrib.staticfiles已经包含在在配置文件的 INSTALLED_APPS.

在这里插入图片描述

  • 在配置文件中定义 STATIC_URL, 如下:
STATIC_URL = '/static/'
  • 在模板中使用静态模板标签来表示静态文件的相对路径url。
{% load static %}
<img src="{% static 'my_app/example.jpg' %}" alt="My image">
  • 将你的静态文件保存至程序中名为 static 的目录中。例如 my_app/static/my_app/example.jpg。

你的工程可能包含未与任何应用绑定的静态资源。除了在 apps 中使用 static/ 目录,你可以在配置文件中定义一个目录列表 (STATICFILES_DIRS) ,Django 会从中寻找静态文件。例子:

STATICFILES_DIRS = [
    BASE_DIR / "static",
    '/var/www/static/',
]

部署静态文件

django.contrib.staticfiles 提供了一个便利的管理命令,用于将静态文件收集至独立目录,方便你为它们提供服务。

将 STATIC_ROOT 配置成你喜欢的目录,在这个目录提供服务,例如:

STATIC_ROOT = "/static/"

注意:STATIC_ROOT和STATIC_URL不是一个概念,最好指定到不同的位置,前者为部署阶段,静态文件的汇总目录;后者为开发阶段指定的存放静态文件的标签。
运行 collectstatic 管理命令:

$ python manage.py collectstatic

这一步一般在项目迁移前做,和项目一起打包迁移到生产服务器;也可以在项目迁移后,runserver运行没问题后来做,直接把静态文件搜集到指定的目录去。
这将会把静态目录下的所有文件拷贝至 STATIC_ROOT 目录。
在这里插入图片描述
这样就会在项目的根建立一个文件夹/wwwroot/static/;把所有的应用和管理应用的静态文件拷贝到这个文件夹。
在这里插入图片描述

选一个 Web 服务器为这些文件提供服务。 一般可以用nginx来处理,速度比较快。如下文所述。

迁移项目文件

在原来项目中导出依赖

pip freeze >requerments.txt

把原来的项目文件夹打包压缩,并传递到centos7上准备作为项目根目录的文件夹,这里为/home,也可以重新建个文件夹/data/wwwroot/
在centos上安装解压缩工具。

安装zip

yum install -y unzip zip

把压缩的文件目录传到指定位置解压

nuzip 压缩包名称.zip

安装项目原来的依赖

在新的项目环境中安装依赖

pip install -r requirements.txt

(djproject) [root@testapi hotlineapi]# pip list
Package             Version
------------------- --------
asgiref             3.3.4
Django              3.2.3
django-cors-headers 3.7.0
django-tinymce      3.3.0
djangorestframework 3.12.4
Pillow              8.2.0
pip                 21.1.2
PyMySQL             1.0.2
pytz                2021.1
setuptools          57.0.0
sqlparse            0.4.1
typing-extensions   3.10.0.0
uWSGI               2.0.19.1
wheel               0.36.2

确认项目使用manage.py启动能正常运行

python manage.py runserver 0.0.0.0:9000

用uwsgi启动项目

一、uwsgi 命令行启动项目

查看项目,对项目路径必须清楚那些文件在哪里路径下,否则使用uwsgi启动设置参数,容易出错,以本项目为例,项目根目录路径为:/home/mysite,项目根目录内容:

在这里插入图片描述

其中非常关键的wsgi入口,在mysite目录下,也就是django项目总settings.py所在的目录,mysite目录下的wsgi.py,将在之后的uwsgi启动中使用

在这里插入图片描述

wsgi.py代码逻辑:

"""
WSGI config for mysite project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings.dev")     #配置文件位置

application = get_wsgi_application()    

dey.py 的位置
在这里插入图片描述
dev.py 内容

from .base import *    #导入基本配置文件

# SECURITY WARNING: don't run with debug turned on in production!
#DEBUG = True        #调试阶段
DEBUG = False        #生产阶段,这个非常重要,要不然会把报错信息返回到客户端浏览器,非常不安全。

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '123456'

# SECURITY WARNING: define the correct hosts in production!
# ALLOWED_HOSTS = ['生产阶段域名']
ALLOWED_HOSTS = ['*']         # 测试阶段

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'


try:
    from .local import *
except ImportError:
    pass

使用uwsgi启动项目并测试是否成功运行django项目,通过连接mysite/wsgi.py实现web server和application通信

这里有两种启动方式:

A、不带静态文件启动,静态文件将无法加载,页面不正常显示

–chdir /home/mysite django项目根路径

wsgi-file mysite/wsgi.py django项目settings.py所在目录下的 wsgi.py文件


uwsgi --http 0.0.0.0:8000 --chdir  /home/gsl/mysite --wsgi-file mysite/wsgi.py --master --processes 4 --threads 2

B、带静态文件启动,也就是网页打开后,页面能正常显示

如果使用nginx来处理静态文件,这步骤可以忽略。如果前面运行 collectstatic 管理命令收集过静态文件到指定目录,静态文件映射路径就是这个搜集的路径。
–chdir /home/mysite django项目根路径
wsgi-file mysite/wsgi.py django项目settings.py所在目录下的 wsgi.py文件
–static-map /static=static文件所在路径,即收集静态文件所到的目录。
–static-map /media =media文件所在路径,即项目根目录的’media’目录或在其他位置定义的media目录。

注意:这里仅是指static、media目录,根目录下还有其他blog,account,templates目录等,可能也有人会问,是不是都需要把这些目录都要一一加入–static-map里面,答案是不需要,因为这些都不是django application对应的“static”目录(已在settins设定,并可以让其他views索引到static目录),如果使用-static-map=/static=templates,uwsgi将无法找到相关静态文件

uwsgi --http 0.0.0.0:8000 --chdir /home/gsl/mysite --wsgi-file mysite/wsgi.py --static-map /static=/home/gsl/mysite/static --master --processes 4 --threads 2  

二、使用uwsgi.ini配置文件启动项目

以上两种启动直接在命令加入环境参数,比较繁琐,可通过在配置文件中放置这些环境参数,方便启动,在manage.py 同目录下新建一个置uwsgi.ini配置文件,也可以单独放在一个目录中方便管理

A、配置文件

uwsgi.ini文件,配置如下

#添加配置选择
[uwsgi]
# 配置和nginx连接的socket连接
http=0.0.0.0:8000   #socker默认字节32,本例为http请求会不足,需调整,直接用http参数,
#socket=0.0.0.0:8000 如果是和nginx配合使用则需要用socket,这个需要注意下。
#配置项目路径,项目的所在目录
chdir=/home/gsl/mysite/
#配置wsgi接口模块文件路径,也就是wsgi.py这个文件所在的目录名
# wsgi-file=mysite/wsgi.py
# 指定项目的application,区别于启动命令--wsgi-filemysite/wsgi.py 两种都可以用。
module=mysite.wsgi:application
#配置启动的进程数
processes=4
#配置每个进程的线程数
threads=2
#配置启动管理主进程
master=True
#配置存放主进程的进程号文件
pidfile=uwsgi.pid
#配置dump日志记录
daemonize=uwsgi.log
#配置静态文件映射位置
static-map = /static=/home/gsl/mysite/static
static-map = /media=/home/gsl/mysite/media


B、基于配置文件uwsgi启动项目

(py36) [root@nn uwsgi_conf]# uwsgi --ini uwsgi.ini 
# 启动后打印的信息,可以看到static静态文件和media媒体资源目录被uWSGI索引

[uWSGI] getting INI configuration from uwsgi.ini
[uwsgi-static] added mapping for /static => /home/gsl/mysite/static
[uwsgi-static] added mapping for /media => /home/gsl/mysite/media

C、查看启动日志

# 运行后,自动参数日志、进程,建议自行查看日志文件内容,了解更多uwsgi
(py36) [root@nn uwsgi_conf]# ls
uwsgi.ini  uwsgi.log  uwsgi.pid 
(py36) [root@nn uwsgi_conf]# tail uwsgi.log
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x5642caa3e410 pid: 9550 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 9550)
spawned uWSGI worker 1 (pid: 9551, cores: 2)
spawned uWSGI worker 2 (pid: 9552, cores: 2)
spawned uWSGI worker 3 (pid: 9553, cores: 2)
spawned uWSGI worker 4 (pid: 9554, cores: 2)
spawned uWSGI http 1 (pid: 9557)

D、停止uwsgi


# 停止uwsgi服务
(py36) [root@nn uwsgi_conf]# uwsgi --stop uwsgi.pid

这步骤没问题,可跳到nginx启动

E、更多配置文件项参考

# uwsig使用配置文件启动
[uwsgi]
# 项目所在的根目录
chdir=/opt/mywebapp/
# 指定项目的application,区别于启动命令--wsgi-filemysite/wsgi.py
module=mysite.wsgi:application
#the local unix socket file than commnuincate to Nginx
# 指定sock的文件路径,这个sock文件会在nginx的uwsgi_pass配置,用来nginx与uwsgi通信       
# 支持ip+port模式以及socket file模式
#socket=%(chdir)/uwsgi_conf/uwsgi.sock
socket=127.0.0.1:9001
# 进程个数       
processes = 8
# 每个进程worker数
workers=5
procname-prefix-spaced=mywebapp                # uwsgi的进程名称前缀
py-autoreload=1                              # py文件修改,自动加载

# 指定IP端口,web访问入口
http=0.0.0.0:9000

# 指定多个静态文件:static目录和media目录,也可以不用指定该静态文件,在nginx中配置静态文件目录
# uwsgi有自己的配置语法,详细可参考官网,无需写绝对路径,可以用循环、判断等高级配置语法
for =static media
static-map=/static=%(chdir)/%(_)
endfor =

# 启动uwsgi的用户名和用户组
uid=root
gid=root

# 启用主进程
master=true
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true

# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置一个超时,用于中断那些超过服务器请求上限的额外请求
harakiri=30
# 设置缓冲
post-buffering=4096

# 设置日志目录
daemonize=%(chdir)/uwsgi_conf/uwsgi.log
# uWSGI进程号存放
pidfile=%(chdir)/uwsgi_conf/uwsgi.pid
#monitor uwsgi status  通过该端口可以监控 uwsgi 的负载情况
# 支持ip+port模式以及socket file模式
# stats=%(chdir)/uwsgi_conf/uwsgi.status 
stats = 127.0.0.1:9001

使用nginx启动uwsgi

配置nginx

nginx配置文件路径

然后我们需要去找到nginx的配置文件。
在这里插入图片描述
在这里插入图片描述
备份下nginx.conf到nginx.conf.bak
然后打开nginx.conf,把原来的内容删除,直接加入以下内容:

配置nginx进程用户权限

在 Linux 系统中,Nginx 默认以 nobody 用户启动。如果需要更改 Nginx 启动用户,可以通过修改 Nginx 配置文件中的 user 指令来实现。

具体步骤如下:

打开 Nginx 配置文件,可以使用以下命令打开默认配置文件:

sudo vi /etc/nginx/nginx.conf

2.找到 user 指令所在的行,通常位于配置文件的开头部分,如下所示:

user  nobody;

3.将 nobody 修改为其他用户名,如 www-data,如下所示:

user  www-data;

4.保存并关闭文件。

5.使用以下命令重新加载 Nginx 配置文件:

sudo nginx -s reload

这样就可以使用指定的用户www-data启动 Nginx 了。需要注意的是,修改 Nginx 启动用户可能会影响到访问权限等问题,因此需要谨慎操作。

root@gslserver:/home/gsl/mysite# chown -R www-data:www-data /home/gsl/mysite/static
root@gslserver:/home/gsl/mysite# chown -R www-data:www-data /home/gsl/mysite/media

#限制用户对目录和文件的访问权限
sudo chmod -R 755 `find ./static -type d` 		#限制目录
sudo chmod -R 644 `find ./static -type f`		#限制文件

sudo chmod -R 755 `find ./media -type d`
sudo chmod -R 644 `find ./media -type f`

以上一直没搞清楚为啥还是没有权限,直接用root用户启动进程了,有时间再看看,如下:

配置文件

user root; #指定nginx进程以root用户运行,保证nginx能获得静态文件夹权限
#user www-data;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 80;
        server_name  www.example.cn; #改为自己的域名,没域名修改为127.0.0.1:80
        ssl_certificate /home/gsl/mysite/www.example.cn_bundle.crt; #证书
        ssl_certificate_key /home/gsl/mysite/www.example.cn.key;    #私钥

        charset utf-8;

        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8000;  #端口要和uwsgi里配置的一样,用来和uwsgi通信
           uwsgi_param UWSGI_SCRIPT mysite.wsgi;  #wsgi.py所在的目录名+.wsgi
           uwsgi_param UWSGI_CHDIR /home/gsl/mysite/; #项目路径
        }
        location /static/ {
        alias /home/gsl/mysite/static/; #css等静态资源路径
        }
        location /media/ {
        alias /home/gsl/mysite/media/; #图片类静态资源路径
        }
    }
}

其中静态文件和媒体文件的路径要和上文搜集时定义的路径一直
重新加载下nginx,看项目是否正常

systemctl restart nginx

终端没有任何提示就证明nginx启动成功。
看项目是否能正常打开。
如果样式不对,查看样式文件路径是否正确;如果图片找不到,查看图片文件路径是否正确。

配置nginx ssl证书

前提是Nginx安装成功和SSL证书已经获取。

在我们下载的证书文件中有一个Nginx的文件夹,这里面的两个文件都是需要的一个是证书,一个是私钥。我们需要把这个两个文件上传到 linux 服务器中,推荐放到/etc/ssl/目录下

nginx配置文件路径

vim /etc/nginx/nginx.conf

增加一个server节点处理443端口,80监听的server端口做跳转;

user root; #指定nginx进程以root用户运行,保证nginx能获得静态文件夹权限
#user www-data;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server{
        listen 80;
        server_name www.example.cn;
        rewrite ^/(.*)$ https://www.example.cn:443/$1 permanent;
    }
    server {
        listen 443 ssl;
        #listen 80;
        server_name  www.gsl371.cn; #改为自己的域名,没域名修改为127.0.0.1:80
        ssl_certificate /home/gsl/mysite/www.example.cn_bundle.crt; #证书
        ssl_certificate_key /home/gsl/mysite/www.example.cn.key;    #私钥
        charset utf-8;
        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8000;  #端口要和uwsgi里配置的一样,用来和uwsgi通信
           uwsgi_param UWSGI_SCRIPT mysite.wsgi;  #wsgi.py所在的目录名+.wsgi
           uwsgi_param UWSGI_CHDIR /home/gsl/mysite/; #项目路径
        }
        location /static/ {
        alias /home/gsl/mysite/static/; #css等静态资源路径
        }
        location /media/ {
        alias /home/gsl/mysite/media/; #图片类静态资源路径
        }
    }
}

错误

重启,如果正常,说明原来已经加载了ssl模块,如果报错

nginx:[emerg]unknown directive ssl,就是这个错误提示

因为我们配置这个SSL证书需要引用到nginx的中SSL这模块,然而我们一开始编译的Nginx的时候并没有把SSL模块一起编译进去,所以导致这个错误的出现。
重新编译下nginx即可

./configure --with-http_ssl_module
make

备份原来的nginx

cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

将新的 nginx 覆盖旧安装目录

cp objs/nginx /usr/local/nginx/sbin/nginx

如果报错,刚用执行下面的命令覆盖

cp -rfp objs/nginx /usr/local/nginx/sbin/nginx
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值