+-
nginx和uwsgi部署Django项目
首页 专栏 nginx 文章详情
1
头图

nginx和uwsgi部署Django项目

三省吾身 发布于 4 月 26 日

一、防火墙和端口设置

开启防火墙:systemctl start firewalld 关闭防火墙:systemctl stop firewalld 查看防火墙状态:systemctl status firewalld 重启防火墙:systemctl restart firewalld 设置开机自启:systemctl enable nginx firewalld 查看开放端口列表:firewall-cmd --list-ports

开放指定的端口:firewall-cmd --zone=public --add-port=端口号/tcp --permanent

需要注意的是:开放端口之后需要重启防火墙才能生效

二、项目环境安装

依赖安装

yum install python3-devel zlib-devel mysql-devel libffi-devel bzip2-devel openssl-devel java wget gcc

安装nginx

yum install nginx

安装redis和mysql

yum install mysql-server yum install redis

安装python进程管理工具supervisor

yum install supervisor

设置开机启动

systemctl enable redis mysqld nginx supervisord

注意:

mysql安装之后默认不会启动,需要使用systemctl start mysqld.service来启动,或者mysqld.service替换为mysqld 设置开机自启动时是mysqld和supervisord,不是mysql和supervisor

安装python3.7

下载源码包:wget https://www.python.org/ftp/py... 解压:tar -xf Python-3.7.8rc1.tar.xz 在/usr/local下新建python3目录,用于安装python3.7.8 进入python3.7.8源码包安装:./configure --prefix=/usr/local/python3 --enable-optimizations 执行命令:make && make install,吐过上一步添加了--enable-optimizations,这一步会比较耗时间,这个参数可以不加

把python3和pip3软连接到/usr/bin上:

软连接python3:ln /usr/local/python3/bin/python3 /usr/bin/python3 软连接pip3:ln /usr/local/python3/bin/pip3 /usr/bin/pip3
问题:使用pip3 install -r requirements.txt安装依赖时,报错:Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-ifh_bc24/cryptography/
解决方法:命令行pip3 install --upgrade setuptools,然后重试

三、Django部署中nginx设置

nginx配置文件

# For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user root; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/nginx/README.dynamic. #include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; upstream uwsgi_backend { # http请求转发配置 server localhost:8888; } upstream channels-backend { # websocket请求转发配置 server localhost:8000; } server { listen 80 default_server; listen [::]:80 default_server; server_name www.ejpro.top; # 显示在浏览器上的名称 charset utf-8; client_max_body_size 75M; #客户端请求体最大的限制 # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; ##### 静态文件设置 location /static/ { root /home/tourism; # static文件所在的目录路径 } location /media/ { root /home/tourism; # media文件所在的目录路径 } #### 动态转发请求 location / { uwsgi_pass 127.0.0.1:8001; include /etc/nginx/uwsgi_params; # 指向的是nginx,Django本身没有该文件 } } }

注意事项:

注释掉include /usr/share/nginx/modules/*.conf,如果不注释这行nginx会默认使用/etc/nginx/nginx.conf.default文件,注释掉后nginx就会使用nginx.conf的配置

静态文件路径配置,static和media的配置路径都只能写到上一层,不能包含static和media这一层,这一点必须要注意,否则会出现如下错误:

[error] 14635#0: *49 open() "/home/tourism/static/static/admin/simpleui-x/particles/particles.js" # 多写了一层static 动态请求中需要注意的是:uwsgi_params路径在/etc/nginx下,Django本身没有该文件

四、uwsgi.ini配置

配置文件

[uwsgi] # Django manage.py 所在文件夹路径 #Django项目源码目录 chdir = /home/tourism # Django系统的uwsgi,如果不记得可以从settings.py文件中WSGI_APPLICATION查看 module = project.wsgi:application # 启用master进程管理 master = true # 绑定的 UNIX socket socket = 127.0.0.1:8888 # uwsgi的进程数 processes = 4 # 重启进行耗时超过30秒就关闭 harakiri = 30 # 最大请求处理数,之后重新生成进程 max-requests = 5000 # 退出时清理环境 vacuum = true # socket socket = 127.0.0.1:8001 # uid uid = 1000 # gid gid = 2000 # pidfile路径 pidfile = /home/tourism/deploy/sub/master.pid # deamonize日志文件路径 deamonize = /home/tourism/deploy/sub/tourism.log # 当服务器关闭或退出时是否清除pidfile和deamonize文件 vacuum=True static-map = /static = /home/tourism/static 如果部署上线后项目在虚拟环境中,还需要另外配置home参数,即python的虚拟环境。如果没有虚拟环境,不需要配置该项 需要配置static-map = /static = /home/tourism/static

六、nginx配置SSL使用https

到云平台申请域名和SSL证书,企业用户付费可以得到纯IP绑定的SSL证书,个人用户不支持,所以域名是必须的,各个平台上都有免费的个人证书,本次使用的是华为云 域名申请后,需要把域名解析到ECS云服务器上,填写公网IP 到SSL证书管理页面下载SSL证书到本地,找到Nginx结尾的包,把里边crt和key结尾的两个文件改一个名字,改名这一步不是必须的。 在云服务器上的/etc/nginx目录下新建cert文件夹用于存放nginx的SSL证书,通过SFTP把本地的两个证书上传到云服务器中/etc/nginx/cert目录。

配置nginx.conf文件

user root; worker_processes auto; error_log /var/log/nginx/error.log; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; upstream uwsgi_backend { # http请求转发配置 server localhost:8888; } upstream channels-backend { # websocket请求转发配置 server localhost:8000; } server { listen 80; server_name SSL证书绑定的域名; rewrite ^/(.*) https://$server_name$1 permanent; #当使用的是http时跳转到Https } server { listen 443; charset utf-8; client_max_body_size 75M; #客户端请求体最大的限制 ssl on; server_name SSL证书绑定的域名; ssl_certificate /etc/nginx/cert/server.crt; #替换成您的证书文件的路径。 ssl_certificate_key /etc/nginx/cert/server.key; #替换成您的私钥文件的路径。 ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; #加密套件。 ssl_prefer_server_ciphers on; ##### 静态文件设置 location /static/ { root /home/tourism; # static文件所在的目录路径 } location /media/ { root /home/tourism; # media文件所在的目录路径 } #### 动态转发请求 location / { uwsgi_pass 127.0.0.1:8001; include /etc/nginx/uwsgi_params; # 指向的是nginx,Django本身没有该文件 } } }

第一个server是设置http服务的,严格来说,如果使用https加密服务,那么不用再设置http这种不安全的传输服务。要是必须使用的话,可以设置访问http服务时定向跳转到https服务。这一个设置也是可以省略的。

server { listen 80; server_name SSL证书绑定的域名; rewrite ^/(.*) https://$server_name$1 permanent; #当使用的是http时跳转到Https } 在云服务器的安全规则中设置允许443端口访问的规则 在云服务器上命令行开启443端口访问

重启nginx服务

nginx -s reload # 重新加载nginx配置文件 nginx -t # 查看nginx是否正常 systemctl restart nginx # 重启nginx服务

到这一步就可以通过https服务成功访问域名了。

七、小坑

问题一:部署上线后静态文件加载不了

解决办法:

nginx中把第一行 user nginx改成user root,提高权限 nginx中的static和media配置路径,路径不能包括static和media 配置Django项目和静态资源文件路径,需要特别注意的是:如果media和static目录下还有子目录,只设置这两个目录的权限会报权限禁止的错误,需要要使用chmod 777 子目录命令对所有子目录进行权限的设置。 在uwsgi.ini中添加static-map = /static = static的绝对路径 收集静态文件:python3 manage.py collectstatic 注意查看settings.py文件中的static和media路径配置是否正确 问题二:使用firewall-cmd --list-ports查看端口时报错ModuleNotFoundError: No module named 'six'

解决办法:命令行输入

cp /usr/local/lib/python3.6/site-packages/six.py /usr/lib/python3.6/site-packages/
nginx uwsgi django
阅读 131 更新于 4 月 28 日
举报
赞1 收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
Django项目开发
关注专栏
avatar
三省吾身
6 声望
0 粉丝
关注作者
0 条评论
得票数 最新
提交评论
avatar
三省吾身
6 声望
0 粉丝
关注作者
宣传栏
目录

一、防火墙和端口设置

开启防火墙:systemctl start firewalld 关闭防火墙:systemctl stop firewalld 查看防火墙状态:systemctl status firewalld 重启防火墙:systemctl restart firewalld 设置开机自启:systemctl enable nginx firewalld 查看开放端口列表:firewall-cmd --list-ports

开放指定的端口:firewall-cmd --zone=public --add-port=端口号/tcp --permanent

需要注意的是:开放端口之后需要重启防火墙才能生效

二、项目环境安装

依赖安装

yum install python3-devel zlib-devel mysql-devel libffi-devel bzip2-devel openssl-devel java wget gcc

安装nginx

yum install nginx

安装redis和mysql

yum install mysql-server yum install redis

安装python进程管理工具supervisor

yum install supervisor

设置开机启动

systemctl enable redis mysqld nginx supervisord

注意:

mysql安装之后默认不会启动,需要使用systemctl start mysqld.service来启动,或者mysqld.service替换为mysqld 设置开机自启动时是mysqld和supervisord,不是mysql和supervisor

安装python3.7

下载源码包:wget https://www.python.org/ftp/py... 解压:tar -xf Python-3.7.8rc1.tar.xz 在/usr/local下新建python3目录,用于安装python3.7.8 进入python3.7.8源码包安装:./configure --prefix=/usr/local/python3 --enable-optimizations 执行命令:make && make install,吐过上一步添加了--enable-optimizations,这一步会比较耗时间,这个参数可以不加

把python3和pip3软连接到/usr/bin上:

软连接python3:ln /usr/local/python3/bin/python3 /usr/bin/python3 软连接pip3:ln /usr/local/python3/bin/pip3 /usr/bin/pip3
问题:使用pip3 install -r requirements.txt安装依赖时,报错:Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-ifh_bc24/cryptography/
解决方法:命令行pip3 install --upgrade setuptools,然后重试

三、Django部署中nginx设置

nginx配置文件

# For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user root; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/nginx/README.dynamic. #include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; upstream uwsgi_backend { # http请求转发配置 server localhost:8888; } upstream channels-backend { # websocket请求转发配置 server localhost:8000; } server { listen 80 default_server; listen [::]:80 default_server; server_name www.ejpro.top; # 显示在浏览器上的名称 charset utf-8; client_max_body_size 75M; #客户端请求体最大的限制 # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; ##### 静态文件设置 location /static/ { root /home/tourism; # static文件所在的目录路径 } location /media/ { root /home/tourism; # media文件所在的目录路径 } #### 动态转发请求 location / { uwsgi_pass 127.0.0.1:8001; include /etc/nginx/uwsgi_params; # 指向的是nginx,Django本身没有该文件 } } }

注意事项:

注释掉include /usr/share/nginx/modules/*.conf,如果不注释这行nginx会默认使用/etc/nginx/nginx.conf.default文件,注释掉后nginx就会使用nginx.conf的配置

静态文件路径配置,static和media的配置路径都只能写到上一层,不能包含static和media这一层,这一点必须要注意,否则会出现如下错误:

[error] 14635#0: *49 open() "/home/tourism/static/static/admin/simpleui-x/particles/particles.js" # 多写了一层static 动态请求中需要注意的是:uwsgi_params路径在/etc/nginx下,Django本身没有该文件

四、uwsgi.ini配置

配置文件

[uwsgi] # Django manage.py 所在文件夹路径 #Django项目源码目录 chdir = /home/tourism # Django系统的uwsgi,如果不记得可以从settings.py文件中WSGI_APPLICATION查看 module = project.wsgi:application # 启用master进程管理 master = true # 绑定的 UNIX socket socket = 127.0.0.1:8888 # uwsgi的进程数 processes = 4 # 重启进行耗时超过30秒就关闭 harakiri = 30 # 最大请求处理数,之后重新生成进程 max-requests = 5000 # 退出时清理环境 vacuum = true # socket socket = 127.0.0.1:8001 # uid uid = 1000 # gid gid = 2000 # pidfile路径 pidfile = /home/tourism/deploy/sub/master.pid # deamonize日志文件路径 deamonize = /home/tourism/deploy/sub/tourism.log # 当服务器关闭或退出时是否清除pidfile和deamonize文件 vacuum=True static-map = /static = /home/tourism/static 如果部署上线后项目在虚拟环境中,还需要另外配置home参数,即python的虚拟环境。如果没有虚拟环境,不需要配置该项 需要配置static-map = /static = /home/tourism/static

六、nginx配置SSL使用https

到云平台申请域名和SSL证书,企业用户付费可以得到纯IP绑定的SSL证书,个人用户不支持,所以域名是必须的,各个平台上都有免费的个人证书,本次使用的是华为云 域名申请后,需要把域名解析到ECS云服务器上,填写公网IP 到SSL证书管理页面下载SSL证书到本地,找到Nginx结尾的包,把里边crt和key结尾的两个文件改一个名字,改名这一步不是必须的。 在云服务器上的/etc/nginx目录下新建cert文件夹用于存放nginx的SSL证书,通过SFTP把本地的两个证书上传到云服务器中/etc/nginx/cert目录。

配置nginx.conf文件

user root; worker_processes auto; error_log /var/log/nginx/error.log; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; upstream uwsgi_backend { # http请求转发配置 server localhost:8888; } upstream channels-backend { # websocket请求转发配置 server localhost:8000; } server { listen 80; server_name SSL证书绑定的域名; rewrite ^/(.*) https://$server_name$1 permanent; #当使用的是http时跳转到Https } server { listen 443; charset utf-8; client_max_body_size 75M; #客户端请求体最大的限制 ssl on; server_name SSL证书绑定的域名; ssl_certificate /etc/nginx/cert/server.crt; #替换成您的证书文件的路径。 ssl_certificate_key /etc/nginx/cert/server.key; #替换成您的私钥文件的路径。 ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; #加密套件。 ssl_prefer_server_ciphers on; ##### 静态文件设置 location /static/ { root /home/tourism; # static文件所在的目录路径 } location /media/ { root /home/tourism; # media文件所在的目录路径 } #### 动态转发请求 location / { uwsgi_pass 127.0.0.1:8001; include /etc/nginx/uwsgi_params; # 指向的是nginx,Django本身没有该文件 } } }

第一个server是设置http服务的,严格来说,如果使用https加密服务,那么不用再设置http这种不安全的传输服务。要是必须使用的话,可以设置访问http服务时定向跳转到https服务。这一个设置也是可以省略的。

server { listen 80; server_name SSL证书绑定的域名; rewrite ^/(.*) https://$server_name$1 permanent; #当使用的是http时跳转到Https } 在云服务器的安全规则中设置允许443端口访问的规则 在云服务器上命令行开启443端口访问

重启nginx服务

nginx -s reload # 重新加载nginx配置文件 nginx -t # 查看nginx是否正常 systemctl restart nginx # 重启nginx服务

到这一步就可以通过https服务成功访问域名了。

七、小坑

问题一:部署上线后静态文件加载不了

解决办法:

nginx中把第一行 user nginx改成user root,提高权限 nginx中的static和media配置路径,路径不能包括static和media 配置Django项目和静态资源文件路径,需要特别注意的是:如果media和static目录下还有子目录,只设置这两个目录的权限会报权限禁止的错误,需要要使用chmod 777 子目录命令对所有子目录进行权限的设置。 在uwsgi.ini中添加static-map = /static = static的绝对路径 收集静态文件:python3 manage.py collectstatic 注意查看settings.py文件中的static和media路径配置是否正确 问题二:使用firewall-cmd --list-ports查看端口时报错ModuleNotFoundError: No module named 'six'

解决办法:命令行输入

cp /usr/local/lib/python3.6/site-packages/six.py /usr/lib/python3.6/site-packages/