文章目录
概要
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