虽然网上有很多这方面部署材料,但很多材料内容并不完善。即便搜索网上大量的部署材料,还是花了我好几天的时间才搞出来。部署步骤太复杂了,尤其uwsgi,感觉是反人类的设计。
言归正传,我的部署版本分别如下:
Nginx:nginx-1.16.0-1.el7.ngx.x86_64
uwsgi:2.0.18
django:2.2.3

uwsgi相关操作步骤

uwsgi安装

pip3 install uwsgi

安装好uwsgi后,在服务器上通过如下命令,启动服务。客户端在游览器上输入服务器IP地址,加上8001端口号,测试uwsgi是否正常工作

uwsgi --chdir /var/django/school --http :8001  --module school.wsgi:application
# /var/django/school:为django项目的路径(要使用绝对路径)
# 8001:为uwsgi开启服务的端口号
# school.wsgi:application:为与django的settings.py同级的wsgi文件路径

测试没问题后,再往下操作。

uwsgi.ini文件配置:
注意:
1 chdir、pidfile、socket不能加备注,如:# ,否则服务启动时会报错;
2 chdir要写绝对路径,指的路径为django项目目录路径,即manage.py所在的目录路径;
3 module要写相对路径,即wsgi.py文件的相对路径;
4 在django与manage.py同级目录,新建uwsgi.ini(名字可以任意取)。

[uwsgi]
chdir=/var/django/school
# home=/home/mysite_env            # optional path to a virtualenv
module=school.wsgi:application
master=True
processes=4                # number of worker processes
harakiri=30                # respawn processes taking more than 20 seconds
post-buffering=65535           # harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers
max-requests=5000          # respawn processes after serving 5000 requests
vacuum=True                # clear environment on exit
socket=127.0.0.1:8001
pidfile=school-uwsgi-master.pid
daemonize=/var/log/nginx/uwsgi.log
disable-logging=true
log-maxsize=10000000
logdate=true

以下参数,建议只在开发时使用。当/var/django/school目录下的任何py文件改变时,自动重启uwsgi。否则,都要手工重启uwsgi服务。

py-auto-reload = 1          # auto restart uwsgi when *.py in/var/django/school was changed.

启动停止重启
通过以上代码配置,uWSGI启动后会在相同目录下生成一个 school-uwsgi-master.pid 的文件,里面只有一行内容是 uWSGI 的主进程的进程号。
启动:
uwsgi --ini uwsgi.ini
重启:
uwsgi --reload school-uwsgi-master.pid
停止:
uwsgi --stop school-uwsgi-master.pid

如果uwsgi服务启动异常,就无法通过上述方式停止uwsgi进程,要用下面的方式:
#查找主进程,然后杀掉。
netstat -antp | grep uwsgi
#kill pid会发送SIGTERM,只会导致重启,而不是结束掉。需要发送SIGINT或SIGQUIT才可以
kill -s SIGINT 3929

查询进程与端口:
ps aux | grep uwsgi
netstat -antp | grep uwsgi # 可以看到主进程PID。

logging参数解释:
daemonize:使进程在后台运行,并将日志打到指定的日志文件或者udp服务器

disable-logging:不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中(Django里使用print命令,打印出来的信息,还是会记录到日志文件里)。如果不加这一条,那么你的日志中会大量出现这种记录:
[pid: 347|app: 0|req: 106/367] 117.116.122.172 () {52 vars in 961 bytes} [Thu Jul 7 19:20:56 2016] POST /post => generated 65 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 88 bytes (1 switches on core 0)

log-maxsize:以固定的文件大小(单位KB),切割日志文件。 例如:log-maxsize=10000000 就是10M一个日志文件。
logdate or log-date:在每一个日志行中都打印时间信息。你可以传入一个strftime()格式的参数,来格式化时间的格式。

其它参数解释:
master = true
#启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。

chdir = /web/www/mysite
#在app加载前切换到当前目录, 指定运行目录

module = mysite.wsgi
#加载一个WSGI模块,这里加载mysite/wsgi.py这个模块

py-autoreload=1
#监控python模块mtime来触发重载 (只在开发时使用)

lazy-apps=true
#在每个worker而不是master中加载应用

socket=/test/myapp.sock
#指定socket文件,也可以指定为127.0.0.1:9000,这样就会监听到网络套接字

processes=2 #启动2个工作进程,生成指定数目的worker/进程

buffer-size=32768
#设置用于uwsgi包解析的内部缓存区大小为64k。默认是4k。

vacuum=true #当服务器退出的时候自动删除unix socket文件和pid文件。
listen=120 #设置socket的监听队列大小(默认:100)

pidfile=/var/run/uwsgi.pid #指定pid文件

enable-threads=true
#允许用内嵌的语言启动线程。这将允许你在app程序中产生一个子线程

reload-mercy=8
#设置在平滑的重启(直到接收到的请求处理完才重启)一个工作子进程中,等待这个工作结束的最长秒数。这个配置会使在平滑地重启工作子进程中,如果工作进程结束时间超过了8秒就会被强行结束(忽略之前已经接收到的请求而直接结束)

max-requests=5000
#为每个工作进程设置请求数的上限。当一个工作进程处理的请求数达到这个值,那么该工作进程就会被回收重用(重启)。你可以使用这个选项来默默地对抗内存泄漏

limit-as=256
#通过使用POSIX/UNIX的setrlimit()函数来限制每个uWSGI进程的虚拟内存使用数。这个配置会限制uWSGI的进程占用虚拟内存不超过256M。如果虚拟内存已经达到256M,并继续申请虚拟内存则会使程序报内存错误,本次的http请求将返回500错误。

harakiri=60
#一个请求花费的时间超过了这个harakiri超时时间,那么这个请求都会被丢弃,并且当前处理这个请求的工作进程会被回收再利用(即重启)

设置成开机自启动:

vi /etc/rc.d/rc.local
uwsgi --ini /var/django/school/uwsgi.ini# 在centos7中,/etc/rc.d/rc.local的权限被降低了,所以需要执行如下命令赋予其可执行权限
chmod +x /etc/rc.d/rc.local

排错:
当访问django站点时,uwsgi后台报错如下:
no python application found, check your startup logs for errors

经过测试,一般是django启动时出现问题,仔细看uwsgi日志的启动信息,一般可以看到python3或django的错误信息。解决错误信息后,杀掉主进程再启动服务,方法如下:
#查找主进程,然后杀掉。
netstat -antp | grep uwsgi
#kill pid会发送SIGTERM,只会导致重启,而不是结束掉。需要发送SIGINT或SIGQUIT才可以
kill -s SIGINT 3929
#注:如果uwsgi启动正常时,通过这种方式无法杀掉进程,要用:uwsgi --stop school-uwsgi-master.pid

#也可以查看uwsgi.log日志,找出主进程。如果杀掉子进程,主进程会重启该子进程。例如下面uwsgi.log日志显示,杀掉子进程后,又重启了该子进程。
Thu Jul 11 23:15:42 2019 - spawned uWSGI master process (pid: 3903)
Thu Jul 11 23:15:42 2019 - spawned uWSGI worker 1 (pid: 3904, cores: 1)
Thu Jul 11 23:15:42 2019 - spawned uWSGI worker 2 (pid: 3905, cores: 1)
Thu Jul 11 23:15:42 2019 - spawned uWSGI worker 3 (pid: 3906, cores: 1)
Thu Jul 11 23:15:42 2019 - spawned uWSGI worker 4 (pid: 3907, cores: 1)
Thu Jul 11 23:18:02 2019 - DAMN ! worker 4 (pid: 3907) died ? trying respawn …
Thu Jul 11 23:18:02 2019 - Respawned uWSGI worker 4 (new pid: 3914)

Nginx相关操作

采用YUM安装nginx
1、添加源

sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

2、安装Nginx
通过yum search nginx看看是否已经添加源成功。如果成功则执行下列命令安装Nginx。

sudo yum install -y nginx

3、启动Nginx并设置开机自动运行

sudo systemctl start nginx.service
sudo systemctl enable nginx.service

在nginx.conf里,部分代码解释:
include /etc/nginx/conf.d/.conf;
include /etc/nginx/sites-enabled/
;

增加nginx虚拟主机配置文件(conf.d)
在/etc/nginx/conf.d/,建立对应的域名配置文件,比如 /etc/nginx/conf.d/123.com.conf
需要注意,不同的虚拟主机配置文件,里面的端口号(listen 8000)不能重叠。

include /etc/nginx/sites-enabled/*;
#通过yum安装nginx/1.16.0,在nginx.conf没发现这段代码。在没有这条代码情况下,不需要从conf.d的文件创建快捷方式到sites-enabled。
#但可以手工在nginx里添加这条代码,并在/etc/nginx 目录下,创建一个sites-enabled。
sites-enabled是激活并使用的server配置(从conf.d的文件创建快捷方式到sites-enabled)
sudo ln -s /etc/nginx/conf.d/mysite_nginx.conf /etc/nginx/sites-enabled/

error_log /var/log/nginx/error.log warn;
#存放访问错误日志的路径

检查nginx配置文件语法是否有问题
nginx -t

配置Django的虚拟主机:
1 进入/etc/nginx/conf.d文件夹,重命名default.conf文件

mv default.conf default.conf_backup

2 vi school.conf

# the upstream component nginx needs to connect to
upstream django {# server unix:///path/to/your/mysite/mysite.sock; # for a file socketserver 127.0.0.1:8001; # for a web port socket (we'll use this first)
}# configuration of the server
server {# the port your site will be served onlisten      80;# the domain name it will serve forserver_name Myschool; # substitute your machine's IP address or FQDNcharset     utf-8;# max upload sizeclient_max_body_size 75M;   # adjust to taste# Django medialocation /media  {alias /var/django/school/media;  # your Django project's media files - amend as required}location /static {alias /var/django/school/static; # your Django project's static files - amend as required}# Finally, send all non-media requests to the Django server.location / {uwsgi_pass  django;include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed}
}

特别注意:
1: uwsgi_pass一定要跟uwsgi_conf.ini中写的地址完全一致,uwsgi_pass也可以直接写:uwsgi_pass 127.0.0.1:8001。
2: uwsgi_params在nginx.conf同级文件夹下自带,
3: 如果nginx.conf文件里有“include /etc/nginx/sites-enabled/
;”代码,那么需要从conf.d的文件创建快捷方式到sites-enabled
Symlink to this file from /etc/nginx/sites-enabled so nginx can see it:
sudo ln -s /etc/nginx/conf.d/school.conf /etc/nginx/sites-enabled/*

Django部署配置清单
1: settings.py

# 关闭Debug和允许所有主机访问Django
DEBUG = False
ALLOWED_HOSTS = ['*']

2: 处理Django静态文件
收集静态文件

# 如果DEBUG=True   -> 使用项目目录下static内的静态文件
# 如果DEBUG=False  -> 使用STATIC_ROOT指定目录下的静态文件
# 这里的'/static/',决定url路径地址,比如写成'bruce',打开的地址就变成http://127.0.0.1:8000/bruce/css/CSSHome.css
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")# 设置静态文件查找目录
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),
)# 如果是home路径下则需要先设置目录权限
# 在模板中使用 fileObj.fileFieldName.url 代表网络可访问的资源路径
MEDIA_URL = '/media/'  # 代表访问media的url路径,例如 127.0.0.1/media/1.png
# 无论是否debug,都会访问此路径下的media资源(包括上传和访问)
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

收集所有静态文件到static_root指定目录:

python3 manage.py collectstatic

此时,依然无法访问static的文件,打开/var/log/nginx/error.log,发现大量日志为:failed (13: Permission denied)
可采用如下2中方法解决:
(1) 使用root账号运行nginx(不推荐):
修改nginx.conf,将头部的user nginx;改为如下:
user root;
如果不修改,静态文件会因为权限问题,导致访问被拒绝。

(2)chmod或chown:
对static和media所有文件夹和文件,授予755的权限;或者将所有文件夹和文件的归属者,改为nginx.

3 favicon.ico
将favicon.ico文件,放在manage.py同级目录里。

4: 设置上传文件目录的权限
如有配置文件上传功能,须确保文件目录的权限,任何人都可以上传文件。

5: 404\505错误页面
在/school/templates目录下,自定义404\505错误页面。比如添加:404.html

Django安全优化部署:
经过测试,这种安全优化部署需要登入系统后,环境变量才生效,所以并不好用,不推荐使用。

当部署Django等业务系统时,settings.py等文件里涉及数据库等密码信息,当部署的文件内容比较敏感时,将敏感信息放在环境变量里.然后使用python3的os.environ,调用环境变量,存放进settings.py对应的代码里.

注意:必须要通过输入用户名和密码登录(包括SSH);或不登入系统,但使用su命令切换用户,相应的环境变量才生效。所以当服务器重启后,在未登入情况下,环境变量是不生效的(因此有服务程序调用环境变量,这里需要注意).

所以,当使用环境变量来保存隐私信息时,就不能设置uwsgi服务自启动了。否则,会因为服务器重启,未登入系统,导致环境变量未生效,从而导致uwsgi启动失败。

注:settings.py里的SECRET_KEY作用,用来数据传输时,比如cookie传输时用来加密解密。
可以手工生成SECRET_KEY:

python3 manage.py shell
from django.core.management import utils
utils.get_random_secret_key()

将settings.py里的SECRET_KEY和mysql 以及redis的密码,配置在环境变量里
环境变量配置:

vi /etc/profile.d/django.sh
export SECRET_KEY='saah&kg@-sfmon_%h179e@den*jzya^@z_3*u5q^cwp9&+v^in'
export MYSQL_KEY='XXXXX'
export REDIS_KEY='XXXXX'

保存后,使用如下命令,是变量生效:

source /etc/profile

验证环境变量配置:

echo $MYSQL_KEY

在settings.py里,使用os.environ[“变量名”]调用

ENV_SECRET_KEY = os.environ['SECRET_KEY']
SECRET_KEY = ENV_SECRET_KEYENV_MYSQL_KEY = os.environ['MYSQL_KEY']
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql',# 'ENGINE': 'django.db.backends.sqlite3',# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),'NAME': 'schoolDB','USER': 'django','PASSWORD': ENV_MYSQL_KEY,'HOST': '192.168.0.100','PORT': '3306',}
}ENV_REDIS_KEY = os.environ['REDIS_KEY']
SESSION_REDIS = {'host': '192.168.0.100','port': 6379,'db': 1,'password': ENV_REDIS_KEY,'prefix': 'session','socket_timeout': 10}

nginx uwsgi django部署相关推荐

  1. nginx+uWSGI + django部署项目

    项目部署 nginx+uWSGI + django 1. WSGI WSGI是Web服务器网关接口.它是一个规范,描述了Web服务器(返回静态资源的就是web服务器,Nginx)如何与Web应用程序( ...

  2. Centos 6.5部署nginx+uwsgi+django

    Centos 6.5部署nginx+uwsgi+django 一.安装python3,系统默认是python2.6 1.安装依赖软件 yum -y install sqlite-devel yum - ...

  3. django+nginx+uwsgi项目部署文档整理

    django+nginx+uwsgi项目部署文档整理 参考文章:https://blog.csdn.net/qq_42314550/article/details/81805328 一.python安 ...

  4. ubuntu NGINX uwsgi https 部署Django 遇到的问题

    搞了3天终于把Django成功部署到Ubuntu,记录一下: 引用来自泡泡茶壶: Ubuntu下的Nginx + Uwsgi + Django项目部署详细流程 前提说明: Django作为小程序的后端 ...

  5. nginx+uwsgi+django环境部署部署

    首科常昊技术部 Django框架部署文档: 硬件环境:阿里云ecs服务器8核心.16GB.10Mbps 环境结构:nginx+uwsgi+django 所需软件:python-3.6.1.pip3.6 ...

  6. Docker部署Angular+Nginx+uwsgi+Django项目

    Docker部署Angular+Nginx+uwsgi+Django项目 0.前言 在开发部署时,容易遇到服务器环境不一致,多台服务重复部署操作过于繁杂的情况.这时可以采用Docker来提供一套统一的 ...

  7. Nginx+uWSGI+Django方法部署Django程序

    在这种方式中,我们的通常做法是,将nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求.nginx把所有静态请求自己来处理(这是NGINX的强项).然后,NGINX将所有非静态请求通过u ...

  8. Nginx+uWSGI+Django原理

    Python的Web开发中,如果使用Django框架,那么较为成熟稳定的服务器架构一般是Nginx+uWSGI+Django.而为什么一定要三个结合在一起呢?直接使用Django的runserver来 ...

  9. Ubuntu Nginx uwsgi django 初试

    /*************************************************************************************** Ubuntu Ngin ...

最新文章

  1. 你真的看懂招聘要求了?
  2. linux摄像头 sdl,Linux音视频(SDL与YUV)
  3. 关于HTML下overflow-y:auto无效、清除HTML默认边距、解决去除手机访问网页时的左右多余空白的三个方法汇总
  4. [痛并快乐着 国外开发者总结欧美游戏坑钱指南] 讀後感想
  5. Eucalyptus系统部署
  6. SharePoint 2013 场解决方案包含第三方程序集
  7. 电子商务应用课程知识整理 第四章-搜索引擎
  8. Qt工作笔记-QGraphicsProxyWidget放自定义界面实现拖动
  9. 【转】Windows系统中ckplayer视频边下边放,视频转码mp4及last atom in file was not a moov atom问题...
  10. oracle 主键_mysql 组合索引带主键ID的问题
  11. 一次性插入上万条数据的写法
  12. 单位启用人脸识别考勤
  13. Word中 Visio 图片到 LaTeX PDF
  14. 基于WF4的新平台-流程格式转换架构
  15. RJ45墙上网线插座的线序与接法
  16. 2020-10-13 Comsol学习1
  17. JS实现中文转拼音首字母和五笔简码
  18. 数据结构(一):数组
  19. python如何提问并回答_如何提问 - nashviller - 博客园
  20. 云更新网吧系统服务器,网吧云更新系统使用图文教程

热门文章

  1. 阻止创建“迅雷下载“目录
  2. 用matlab批量修改图片名称
  3. php把十二生肖排列,12生肖怎么排 十二生肖如何排序
  4. 土地利用规划之平时作业二
  5. 设置Chrome忽略网站证书错误
  6. mysql占用内存过高_MySQL内存消耗过高问题处理
  7. 语音入口大战升级,Echo音箱还不是杀手锏,等所有汽车都用上Alexa就不一样了
  8. 第一节课-第二周:神经网络的编程基础(Basics of Neural Network programming)
  9. 精品咖啡知识不能不知道的8个地方
  10. 大学英语六级历年真题Word,PDF,和音频 下载