title: centos中部署django项目 #标题tags: #标签
date: 2022-04-15
categories: python # 分类
记录下在centos中部署django项目。安装的python3版本建议和本地开发的版本一致。
安装python3环境
设置字符集
$ cat >> /etc/profile << EOF
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN.UTF-8
EOF
source /etc/profile
下载安装python3.8.9
# 安装依赖
$ yum -y install wget zlib-devel bzip2-devel openssl-devel \
ncurses-devel sqlite-devel readline-devel \
tk-devel gdbm-devel db4-devel libpcap-devel \
xz-devel libffi-devel expat-develgdbm-devel \
mysql-devellibffi-devel
# 下载并编译安装python环境
$ wget https://www.python.org/ftp/python/3.8.9/Python-3.8.9.tgz
$ tar zxf Python-3.8.9.tgz && cd Python-3.8.9;mkdir /apps/usr/ -p
# 编译并安装
$ ./configure prefix=/apps/usr/python38
$ make && make install
# 配置环境变量
$ cat >> /etc/profile << "EOF"
PATH=/apps/usr/python38/bin:$PATH
EOF
source /etc/profile
python3 -V # 输出 Python 3.8.9
创建项目虚拟环境(可选)
至于虚拟环境的配置为可选配置(主要是为了避免版本冲突),如果不懂虚拟环境的使用,可以参考博文:centos配置python3虚拟环境,好,这里就不说废话,直接开始配置。
# 配置pip源
$ cat >> /etc/pip.conf << EOF
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
EOF
# 安装虚拟环境所需的包
pip3 install virtualenv virtualenvwrapper
# 配置虚拟环境相关变量
$ cat >> /etc/profile << "EOF"
WORKON_HOME=/data/envdir
VIRTUALENVWRAPPER_PYTHON=/apps/usr/python38/bin/python3
source /apps/usr/python38/bin/virtualenvwrapper.sh
EOF
source /etc/profile
# 创建并进入虚拟环境 django0(后续的操作就在django0虚拟环境中进行)
mkvirtualenv django0
安装项目所需模块
注意,所有pip安装操作,均在虚拟环境django0中进行安装。
# 安装uwsgi
$ pip3 install uwsgi
# 安装从你本地开发环境导出的模块及对应版本
# 本地导出参考命令:pip3 freeze > requirement.txt,导出后上传至服务器进行安装
$ pip3 install -r requirement.txt
创建测试项目并启动(可选)
# 创建项目
$ django-admin startproject mysite2
cd mysite2/
# 配置项目允许所有地址访问
$ vim mysite2/settings.py
ALLOWED_HOSTS = ["*"] # 设置为 * 号
# 启动项目
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环境配置正常:
上传项目
将你本地开发的项目,上传至服务器,上传后的目录层级如下:
$ 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监听的端口正常访问到你的项目,则表明配置完成。如下:
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监听端口的方式,需要建立三次握手。