使用Nginx部署Django

使用Nginx部署Django

参考文章链接

我的环境

conda 4.7.10、python 3.6.7、Django 3.0.3

安装uWSGI

pip install uwsgi
这里如果出现了问题,可以考虑如下解决办法:参考链接

apt-get install python3-dev
apt-get install gcc-4.7 ##卸载你的gcc版本,安装为4.7:
rm /usr/bin/gcc
ln -s /usr/bin/gcc-4.7 /usr/bin/gcc

最后重新运行安装命令pip install uwsgi

测试uWSGI是否正常工作

  • 新建一个test.py文件:touch test.py 若之后要删除则运行rm 文件名
    输入如下内容:
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2
  • 运行uWSGI:uwsgi --http :8080 --wsgi-file test.py
    可能会报错:
    uwsgi: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
    解决方法:参考链接
find / -name libpcre.so.* ##找到所有的系统中libpcre
ln -s /root/anaconda3/lib/libpcre.so.1 /lib ##创建libpcre.so.1软链到/lib下
which uwsgi ##测试一下是否好用了

这里有个坑,如果你的服务器是云服务器,例如我的是阿里云,一定要注意设置运行的端口要和云服务器控制台的安全组端口对应,否则可能无法正确地用http访问端口。
安全组配置示例

  • 浏览器键入http://example.com:8000出现Hello World说明运行成功。
    表示以下路径正常:the web client <-> uWSGI <-> Python
    ps.Ubuntu杀死指定进程的命令:kill -9 $(lsof -i tcp:8080 -t)

    从简单的test.py到Django项目

  • 新建一个Django项目并确保其能正确运行:如何新建参考这里
    ps.云服务器上记得要把Django项目的settings.py中的ALLOWED_HOSTS = [""]改为ALLOWED_HOSTS = ["*"],方便其他地址正常访问。
  • 改用uWSGI来运行:uwsgi --http :8000 --module mysite.wsgi
    如果能正常运行说明以下路径正常:the web client <-> uWSGI <-> Django
    通常我们不会让浏览器直接与uWSGI通信,那是web服务器的工作。

    安装Nginx

sudo apt-get install nginx
sudo /etc/init.d/nginx start ##启动nginx服务

通过浏览器访问80端口,你应该会从Nginx获得一个消息:”Welcome to nginx!”。
这说明以下路径正常:the web client <-> the web server

配置Nginx静态路径

  • 在Django目录下新建名为uwsgi_params的文件,文件内容从这里复制
  • 在Django目录下新建名为mysite_nginx.conf的文件,内容为:
upstream django {
    server 0.0.0.0:8081; #web socket
}
server {
    listen      8080; #nginx端口
    server_name xx.xx.xx.xx; #IP地址
    charset     utf-8;
    client_max_body_size 75M;
    location /media  {
        alias /path/to/your/mysite/media; #media文件路径
    }
    location /static {
        alias /path/to/your/mysite/static; #static文件路径
    }
    location / {
        uwsgi_pass  django;
        include     /path/to/your/mysite/uwsgi_params; #uwsgi_parms文件路径
    }
}
  • 将上述文件链接到/etc/nginx/sites-enabled中以便Nginx识别
    sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
  • 修改Django的settings.py文件,添加下述语句:
    STATIC_ROOT = os.path.join(BASE_DIR, "static/")
  • 运行如下命令:
    python manage.py collectstatic
  • 重启Nginx
    sudo /etc/init.d/nginx restart
  • 测试
    将测试图片test.jpg放入media文件夹中,访问xx.xx.xx.xx:8080/media/test.jpg如果能访问,说明nginx提供了正确的文件服务

    配置Nginx动态请求

    让Nginx对test.py应用说句”hello world”吧。
    uwsgi --socket :8081 --wsgi-file test.py
  • socket :8081:使用uWSGI协议,端口为8081,同时,已经配置了Nginx在那个端口与uWSGI通信,而对外使用8000端口。访问:xx.xx.xx.xx:8080/
    出现“hello world”说明以下路径正常:the web client <-> the web server <-> the socket <-> uWSGI <-> Python

    使用Unix socket而不是端口

    目前我们使用了简单的TCP socket,换成Unix socket所用的开销更小。
  • 编辑mysite_nginx.conf文件
    将第一句的server 0.0.0.0:8081; #web socket改为server unix:///path/to/your/mysite/mysite.sock;这里的/path/to/your/.....改成你自己的路径,mysite.sock是系统自动生成的,不用理会它。
  • 重启Nginx:sudo /etc/init.d/nginx restart
  • 再次运行uWSGI:uwsgi --socket mysite.sock --wsgi-file test.py
  • 在浏览器访问:xx.xx.xx.xx:8000/
    这里可能会出现502 Bad Gateway,原因是Nginx没有进入该目录的权限,故无法访问socket文件,其中一个解决方法是改变运行Nginx的用户身份,把/etc/nginx/nginx.conf 第一行的user www-data; 中的www-data 改成权限足够高的用户,重启Nginx。我直接改成root了,可以正常运行。

    使用uWSGI和Nginx运行Django应用

  • 输入以下命令运行Django应用
    uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664