title: centos中部署django项目 #标题tags: #标签
date: 2022-04-15
categories: python # 分类

记录下在centos中部署django项目。安装的python3版本建议和本地开发的版本一致。

安装python3环境

设置字符集

  1. $ cat >> /etc/profile << EOF
  2. export LANG=zh_CN.UTF-8
  3. export LANGUAGE=zh_CN.UTF-8
  4. EOF
  5. source /etc/profile

下载安装python3.8.9

  1. # 安装依赖
  2. $ yum -y install wget zlib-devel bzip2-devel openssl-devel \
  3. ncurses-devel sqlite-devel readline-devel \
  4. tk-devel gdbm-devel db4-devel libpcap-devel \
  5. xz-devel libffi-devel expat-develgdbm-devel \
  6. mysql-devellibffi-devel
  7. # 下载并编译安装python环境
  8. $ wget https://www.python.org/ftp/python/3.8.9/Python-3.8.9.tgz
  9. $ tar zxf Python-3.8.9.tgz && cd Python-3.8.9;mkdir /apps/usr/ -p
  10. # 编译并安装
  11. $ ./configure prefix=/apps/usr/python38
  12. $ make && make install
  13. # 配置环境变量
  14. $ cat >> /etc/profile << "EOF"
  15. PATH=/apps/usr/python38/bin:$PATH
  16. EOF
  17. source /etc/profile
  18. python3 -V # 输出 Python 3.8.9

创建项目虚拟环境(可选)

至于虚拟环境的配置为可选配置(主要是为了避免版本冲突),如果不懂虚拟环境的使用,可以参考博文:centos配置python3虚拟环境,好,这里就不说废话,直接开始配置。

  1. # 配置pip源
  2. $ cat >> /etc/pip.conf << EOF
  3. [global]
  4. index-url = https://mirrors.aliyun.com/pypi/simple/
  5. EOF
  6. # 安装虚拟环境所需的包
  7. pip3 install virtualenv virtualenvwrapper
  8. # 配置虚拟环境相关变量
  9. $ cat >> /etc/profile << "EOF"
  10. WORKON_HOME=/data/envdir
  11. VIRTUALENVWRAPPER_PYTHON=/apps/usr/python38/bin/python3
  12. source /apps/usr/python38/bin/virtualenvwrapper.sh
  13. EOF
  14. source /etc/profile
  15. # 创建并进入虚拟环境 django0(后续的操作就在django0虚拟环境中进行)
  16. mkvirtualenv django0

安装项目所需模块

注意,所有pip安装操作,均在虚拟环境django0中进行安装。

  1. # 安装uwsgi
  2. $ pip3 install uwsgi
  3. # 安装从你本地开发环境导出的模块及对应版本
  4. # 本地导出参考命令:pip3 freeze > requirement.txt,导出后上传至服务器进行安装
  5. $ pip3 install -r requirement.txt

创建测试项目并启动(可选)

  1. # 创建项目
  2. $ django-admin startproject mysite2
  3. cd mysite2/
  4. # 配置项目允许所有地址访问
  5. $ vim mysite2/settings.py
  6. ALLOWED_HOSTS = ["*"] # 设置为 * 号
  7. # 启动项目
  8. python3 manage.py runserver 0.0.0.0:8082

启动报错

如果在启动项目时,报错如下:

            # ...........
File "/data/envdir/django0/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 67, in check_sqlite_version
    raise ImproperlyConfigured('SQLite 3.8.3 or later is required (found %s).' % Database.sqlite_version)
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).

那么需要按照下面的步骤进行解决:

# 下载最新sqlite版本
$ wget https://www.sqlite.org/2022/sqlite-autoconf-3380200.tar.gz --no-check-certificate
# 解压后编译安装
$ tar zxf sqlite-autoconf-3380200.tar.gz && cd sqlite-autoconf-3380200 && ./configure
$ make && make install
$ /usr/local/bin/sqlite3 --version     # 确认新版本
# 确认旧版本并移除
$ /usr/bin/sqlite3 --version
mv /usr/bin/sqlite3{,_old}

# 配置新版本的软连接并确认
ln -sf /usr/local/bin/sqlite3 /usr/bin/sqlite3
sqlite3 --version

# 配置环境变量
cat >> /etc/profile << "EOF"
export LD_LIBRARY_PATH="/usr/local/lib"
EOF
source /etc/profile

# 查看版本
# export LD_LIBRARY_PATH="/usr/local/lib"
$ python3  -c 'import sqlite3;print(sqlite3.sqlite_version)'
3.38.2

进行完sqlite升级操作后,需要将虚拟环境删除再新建虚拟环境,然后启动项目,但此时我这里启动还是报一样的错,还得按照如下方式解决(每新建一个虚拟环境就得改一下base.py文件,或者直接修改python3中的python38/site-packages/django/db/backends/sqlite3/base.py,而不是修改虚拟环境中的):

$ pip3 install pysqlite3 pysqlite3-binary

# 我这里修改的是这个,你需要对实际报错的末尾输出的文件进行修改
$ vim /data/envdir/django0/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py
# from sqlite3 import dbapi2 as Database # 注释这条
from pysqlite3 import dbapi2 as Database # 导入pysqlite3

都修改后,即可再次启动项目并访问了。

访问8082端口,看到页面如下则表示django环境配置正常:

centos中部署django项目 - 图1

上传项目

将你本地开发的项目,上传至服务器,上传后的目录层级如下:

$ tree -L 1 /data/supercrm
/data/supercrm         # 项目根目录
├── manage.py
├── rbac       # 项目应用
├── sales       # 项目应用
├── static_file           # 静态文件
└── supercrm          # 包含项目配置、urls.py、wsgi.py等

# 指定收集的静态文件目录(不可与现有目录冲突,我这里是配置了到项目根目录下的static目录)
$ cat >> /data/supercrm/supercrm/settings.py << EOF
STATIC_ROOT = os.path.join(BASE_DIR,'static')
EOF

# 收集静态文件
$ cd /data/supercrm/
$ python3 manage.py collectstatic

# 确认静态文件已生成
$ ls /data/supercrm/static
admin  bootstrap-3.3.7-dist  dist  font  jquery.js  plugins

注意:如果是上生产环境,还需要修改/data/supercrm/supercrm/settings.py文件中的数据库连接地址及DEBUG = False

配置并启动uwsgi

$ cat /etc/uwsgi.ini
[uwsgi]
# uwsgi支持三种方式启动,分别是http、socket监听端口、socket套接字
# 这里先写下http,后面会有其他几种方式的配置
http =:8080
# 项目根路径
chdir=/data/supercrm
# uwsgi的文件(基于项目根路径写的相对路径)
wsgi-file=supercrm/wsgi.py
# 虚拟环境(为项目创建的虚拟环境)
virtualenv=/data/envdir/django0
# 进程个数
processes=2
# 线程个数
threads=2
# 后台启动,指定日志的输出
daemonize=/data/supercrm/supercrm.log
# 清除临时文件
vacuum=true
# 热加载项目
py-autoreload=1


# 启动uwsgi(可以自己将其设置为开机自启动,这里不配置了)
$ uwsgi --ini /etc/uwsgi.ini       # 只有在虚拟环境中才有uwsgi命令

# 确定端口在监听
$ ss -lntp | grep 8080
LISTEN     0      100          *:8080                     *:*                   users:(("uwsgi",pid=7568,fd=4),("uwsgi",pid=7562,fd=4))

安装并配置nginx

启动django项目,一般会通过nginx来进行反向代理,以及提供静态文件的访问。为了方便,这里直接yum安装即可。

$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
$ yum -y install nginx


# 配置反向代理uwsgi
$ vim  /etc/nginx/nginx.conf
# 在server字段中添加对应的location规则
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;

        # 添加静态文件的规则
        location  /static {
            root /data/supercrm;        
        }
        # 添加反向代理uwsgi的规则
        location / {
            proxy_pass http://127.0.0.1:8080;
        }

                # ....................


# 启动nginx
$ nginx
# 确定端口在监听
$ ss -lntp | grep 80
LISTEN     0      511          *:80                       *:*                   users:(("nginx",pid=7530,fd=6),("nginx",pid=7529,fd=6),("nginx",pid=7528,fd=6))
LISTEN     0      511         :::80                      :::*                   users:(("nginx",pid=7530,fd=7),("nginx",pid=7529,fd=7),("nginx",pid=7528,fd=7))

访问测试

可以通过nginx监听的端口正常访问到你的项目,则表明配置完成。如下:

centos中部署django项目 - 图2

uwsgi监听的三种方式

在上面的部署使用的是以http端口进行监听的,就不在这里说了,具体实现上面已经配置过了,这里说下通过socket的方式进行监听,以及如何与nginx进行连通。

指定socket监听端口

$ vim /etc/uwsgi.ini 
#http =:8080     # 注释http监听配置
socket = :8008          # socket监听本地8008

$ ps -ef | grep uwsgi | grep -v grep  | awk '{print $2}' | xargs kill -9

# 启动uwsgi
$ uwsgi --ini /etc/uwsgi.ini 
$ ss -lntp | grep 8008         # 确定端口在监听
LISTEN     0      100          *:8008                     *:*                   users:(("uwsgi",pid=70200,fd=3),("uwsgi",pid=70199,fd=3),("uwsgi",pid=70018,fd=3))


$ vim /etc/nginx/nginx.conf       # 修改nginx配置
        include uwsgi_params;           # 加载当前目录下的uwsgi_params文件
        location  /static {       # 静态资源访问的location无需改动
            root /data/supercrm;
        }
        location / {
            uwsgi_pass 127.0.0.1:8008;           # 这里的ip不要加http了,不是用http实现了。
        }



# 重载nginx
$ nginx -s reload

至此,配置完成,访问测试即可。

指定socket文件

socket也可以直接配置为一个文件路径,如下:

$ vim /etc/uwsgi.ini 
# 注释原来的两种监听方式,新增socket并指定一个文件
#http =:8080
#socket = :8008
socket=/data/supercrm/supercrm.sock

# 重启生效
$ ps -ef | grep uwsgi | grep -v grep  | awk '{print $2}' | xargs kill -9
$ uwsgi --ini /etc/uwsgi.ini 
# 确定socket文件已存在
$ ll /data/supercrm/supercrm.sock
srwxrwxrwx 1 root root 0 4月  15 23:55 /data/supercrm/supercrm.sock


# 修改nginx配置
$ vim /etc/nginx/nginx.conf   
        include uwsgi_params;           # 加载当前目录下的uwsgi_params文件
        location  /static {       # 静态资源访问的location无需改动
            root /data/supercrm;
        }
        location / {
            uwsgi_pass unix://data/supercrm/supercrm.sock;           # 这里需要指定为socket文件了
        }

# 重载nginx
$ nginx -s reload

至此,配置完成,访问测试即可。

三种不同的uwsgi启动方式如何选择

上面我们uwsgi有三种不同的监听方式,那么怎么选择呢?可以参考如下:

  • 要使用uwsgi_pass,而不是proxy_pass;
  • nginx和uwsgi在同一台服务器,使用socket文件的方式,节省建立TCP连接的时间;
  • nginx和uwsgi不在同一台节点,使用socket监听端口的方式,需要建立三次握手。