Centos7 + Python3.7 + Django2/3 + Nginx1.6.1 + uwsgi2.0.18 配置

谷明科技,专注于大数据和人工智能领域的创新者

本文主要是针对 Django 项目的生产部署操作

网络客户端 <-> 网站服务器(nginx) <-> the socket <-> uwsgi <-> Django

这里,uwsgi 是与 Django 交互的一种 python 标准,而 nginx 和 uwsgi 之间的交互方式是以 socket 包的方式进行的

前提:

  • 已经安装了 python 3.7 版本
  • 已经安装了 django 版本可以在 django 2.0 - 3.0
  • 已经有一个可以正常运行的 django 项目,我们这里假设我们用的 django 教程里的项目 mysite. 
  • 已经安装了 Nginx1.6.1, 没有安装的可以翻看之前的教程。

说明下,我们下面会频繁提到几个名词,提前备注下

  • 系统环境: 以 root 用户进入的系统环境
  • 虚拟环境:是用 virtualenv 搭建并已经激活的环境
  • 项目目录虚拟环境中有 manage.py 的目录,是绝对路径
  • IP: 你的服务器的访问 ip,如果是云服务器的话,就是外网 ip

1. 在虚拟环境中安装 uwsgi 

注意,这里强烈推荐用 pip 安装,否则后续会遇到一些问题。

pip install uwsgi
which uwsgi

看下路径是不是指向虚拟环境的

2. 在虚拟环境中测试并配置 uwsgi

测试:

项目目录下,新建一个 test.py 文件。

# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2

uwsgi --http :8000 --wsgi-file test.py

这里的 8000 端口应该是可用而且空闲的,所谓可用是指 阿里云 或者 腾讯云 的该端口安全组是已经配置了的,具体不懂的可以百度,所谓空闲的,是指该端口没有被占用,具体查询方法为如下:

netstat -nltp | grep 8000

打开 http://IP:8000 是否能看到 “hello world” 的输出,如果是,说明如下通信链路是通的

客户端 <-> uWSGI <-> Python

如果不能看到,再看下上面的内容,是不是遗忘了一些步骤或者配置有问题

3. 虚拟环境中测试 django 项目的 uwsgi 通信

首先,看下你的 django 项目是不是可以跑通

python manage.py runserver 0.0.0.0:8000

然后打开 http://IP:8000/admin 是否可以看到你的 django 登录界面,如果可以的话,说明项目没问题。

然后输入

uwsgi --http :8000 --module mysite.wsgi

这里的 mysite 是 django 项目的名字,如果你的项目名字是其他的,这里对应修改一下,我们本篇都会以 mysite 作为默认的项目名

然后打开 http://IP:8000/admin 是否可以看到你的 django 登录界面,如果可以的话,说明如下的网络通信没有问题

客户端 <-> uWSGI <-> Django

4. 系统环境中测试 nginx

这里我们默认 nginx 已经安装完成而且安装方式是 yum 安装

打开 http://IP:80 是否可以看到 nginx 的欢迎界面,如果可以说明以下通信链路是没问题

客户端 <-> nginx 服务器

如果有问题,可以看下 /var/log/nginx/error.log 日志,如果是端口被占用,直接停掉对应的进程然后重新启动 nginx

nginx -s reload

打开 nginx 路径,如果不知道可以打 nginx -t 或者 whereis nginx 

我这边的 nginx 的路径是 /etc/nginx,里面的文件架构是

nginx
-- conf.d
   fastcgi_params
   nginx.conf
   uwsgi_params
   ...

这里的 conf.d 就是 nginx 配置文件的目录,下一步我们会用到。

同时,因为我们需要在项目中使用到 uwsgi_params 文件,所以把这个文件复制到项目目录中,并且文件的拥有者是开发者而不是 root。

5. 虚拟环境中配置 nginx

在项目目录下,新建一个 mysite_nginx.conf 文件,并填入以下信息

# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # socket 的网络端口
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name IP; # 服务器IP
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # 可以自己调整

    # Django media
    location /media  {
        alias 项目目录/media;  # 媒体文件路径
    }

    location /static {
        alias 项目目录/static; # 静态文件路径
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     项目目录/uwsgi_params; # 项目的 uwsgi_params 文件
    }
}

然后做一个指向该配置文件的软链接

ln -s 项目目录/mysite_nginx.conf /etc/nginx/conf.d/

6. 虚拟环境中部署静态文件

首先,修改一下 django 项目的配置文件(项目目录/setting.py

将其中的 debug = True 改为 debug = False

然后在文件末尾添加如下一行

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATIC_URL = '/static/'

同时需要对 mysite 文件夹下面的 urls.py 文件做一个简单的修改

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

同时,需要对访问的ip和域名地址做一个设置,否则会造成 connection refused 这样的问题,这里我的例子是这样:

ALLOWED_HOSTS = ['127.0.0.1', '外网IP','www.guming-tech.com']

然后在你的项目目录中添加2个子目录

/media/
/static/ 

分别存放媒体文件和静态文件,然后输入以下命令

python manage.py collectstatic

然后放一张图片在 media 目录下,什么图片都可以,我们这里假设图片为 show.png

接下来,切入到系统环境中,然后重启 nginx

nginx -s reload

然后访问 http://IP:8000/media/show.png, 如果图片能够显示,则说明 nginx 的项目配置是没有问题的

7. 虚拟环境中测试 nginx,uwgsi 和 python 之间的 socket 端口通信

输入以下命令

uwsgi --socket :8001 --wsgi-file test.py

这里的 8001 端口是基于第5步中对 nginx 项目配置文件的配置,忘记的可以重新翻看下

然后打开 http://IP:8000 是否可以看到 “hello world”,如果可以的话,说明如下的通信链路是没有问题的

客户端 <-> nginx 服务器 <-> the socket <-> uWSGI <-> Python

8. 虚拟环境中测试 nginx,uwgsi 和 python 之间的 unix socket 通信

上一步我们使用了TCP的 socket 的端口通信,这个是比较简单的,但是在实际的网站中,更好的解决方案是 unix socket 方法,具体设置方法如下:

编辑 mysite_nginx.conf 对文件的头部部分做一些修改

server unix://项目目录/mysite.sock; # socket 文件,自动生成
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)

切换到系统环境中,重启 nginx

然后输入

uwsgi --socket mysite.sock --wsgi-file test.py

然后打开 http://IP:8000 应该可以看到 “hello world”,如果有 permission error 的话,试下如下2种方法

uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664

我这边是对第一种方法有效

9. 虚拟环境中测试 nginx,uwgsi 和 django 项目之间的完整通信

这次试下如下的命令

uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666

然后打开  http://IP:8000/admin 是不是可以看到 django 的登录界面了

10. 虚拟环境中使用 ini 配置文件

在项目目录下新建一个 mysite_uwsgi.ini 文件,并放入以下内容

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = 项目目录
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path),这个是你使用 virtualenv 建立的项目的绝对路径,但不是项目路径,一般是项目目录的上层路径
home            = 项目目录的上层路径

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = 项目路径/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = false

然后输入

uwsgi --ini mysite_uwsgi.ini

然后打开  http://IP:8000/admin 应该还是可以通信

11. 系统环境下安装 uwsgi

依然是用 pip 安装 uwsgi

pip install uwsgi

然后在系统环境中进入到项目目录,输入

uwsgi --ini mysite_uwsgi.ini

然后打开  http://IP:8000/admin 应该还是可以通信

12. Emperor 模式下的配置

uwsgi 可以在 “Emperor” 皇帝模式下工作,即可以监视所有的 uwsgi 配置文件

mkdir /etc/uwsgi
mkdir /etc/uwsgi/vassals
ln -s 项目目录/mysite_uwsgi.ini /etc/uwsgi/vassals/
uwsgi --emperor /etc/uwsgi/vassals --uid user --gid user-group

具体的 user 和 user-group 这里你可以自己选择,比方说对系统用户 django

groups django

输出 django 的用户组,填进去试试

13. 设置 uwsgi 系统自启动

这里我们选择推荐的 /etc/rc.local 进行编辑

然后加入如下的命令

uwsgi安装路径/uwsgi --emperor /etc/uwsgi/vassals --uid 用户 --gid 用户组 --daemonize /var/log/uwsgi-emperor.log

这里的 uwsgi安装路径可以通过以下的命令得到

which uwsgi

然后

source /etc/rc.local

需要提到的一点 /etc/rc.local 在centos7的版本里是只读的,所以我们需要给它加入一个可执行的权限,同时 /etc/rc.local 的服务名为 rc-local,所以我们这里将其设定为自启动

chmod +x /etc/rc.d/rc.local
systemctl enable rc-local

可以尝试重启下系统,看看服务是否自动打开

systemctl status rc-local

直接打开 http://IP:8000/admin 应该可以看到网站正常运行

部署完成

14. 项目的修改和重新加载

如果在项目中新增加了一个应用app,需要对项目进行重启,这时候我们需要对 uwsgi 的配置文件 mysite_uwsgi.ini 做一个修改。即添加一行

touch-reload = 项目路径/reload.ini

然后在项目目录中,输入以下命令

touch reload.ini

这时候不只要重新启动 nginx 还有 uwsgi(已经在rc-local中)

nginx -s reload
killall uwsgi
source /etc/rc.local

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章