本文介绍了使用Nginx,Gunicorn和Supervisor部署Django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过遵循教程,但是我修改了一些步骤,以便可以使用Conda代替ViritualEnv.

I'm trying to deploy my Django app with Nginx and Gunicorn by following this tutorial, but I modified some steps so I can use Conda instead of ViritualEnv.

设置如下:

  1. Nginx用我的Vue应用程序回复
  2. 来自Vue的请求发送到api.example.com
  3. Nginx监听api.example.com并将请求定向到Gunicorn的Unix套接字

我检查过的东西:

  1. 我可以在Nginx的 access.log 中看到Vue请求.
  2. 我还可以在 supervisor.log 中使用 journalctl -f -u gunicorn 和gunicorn的access.log
  3. 查看那些请求.
  4. 当我的Django应用启动时,它会创建一个日志文件,因此我可以看到Gunicorn启动了它.但是Django没有响应来自unix套接字的请求.
  5. 当我ssh并运行以下命令时,我可以看到Django的响应: curl --no-buffer -XGET --unix-socket/var/www/example/run/gunicorn.sock http://localhost/about .仅当使用我的任何 ALLOWED_HOSTS 代替 localhost 时,此命令才会给出响应.
  6. 我的Nginx,Supervisor和Gunicorn配置都使用 gunicorn.sock 的完整路径.
  1. I can see the Vue requests in Nginx's access.log.
  2. I can also see those requests with journalctl -f -u gunicorn, in the supervisor.log, and gunicorn's access.log
  3. When my Django app starts, it's creates a log file, so I can see that Gunicorn starts it. But Django is not responding to requests from the unix socket.
  4. I can see a response from Django when I ssh in and run the following command:curl --no-buffer -XGET --unix-socket /var/www/example/run/gunicorn.sock http://localhost/about. This command only gives a response when any of my ALLOWED_HOSTS are used in place of localhost.
  5. My Nginx, Supervisor and Gunicorn configurations all use the full path to gunicorn.sock.

如果我执行 nmap localhost 之类的命令,我应该看到Django在8000端口上运行吗?我看到另一个帖子提到Nginx应该指向端口8000,并且应该运行gunicorn或:

Should I see Django running on port 8000 or anything if I do something like nmap localhost?I saw another post mention that Nginx should point to port 8000 and that gunicorn should be run with either:

  1. gunicorn --bind 0.0.0.0:8000< djangoapp> .wsgi --daemon
  2. gunicorn< djangoapp> .wsgi:application --bind< IP>:8000 --daemon
  3. gunicorn< djangoapp> .wsgi:application --bind = unix:/var/www/example/run/gunicorn.sock

但是,暴露端口8000不会破坏使用Nginx作为反向代理和Gunicorn的unix套接字的目的吗?暴露8000也不会增加攻击媒介的表面积吗?还是公开端口8000的最佳实践?我有些困惑,为什么我既要同时使用该端口,又要同时使用Nginx和Gunicorn.

But doesn't exposing port 8000 defeat the purpose of using Nginx as a reverse proxy and Gunicorn's unix socket? Doesn't exposing 8000 also increase the surface area for attack vectors? Or is it best practice to expose port 8000? I'm a bit confused why I would use both expose that port and use both Nginx and Gunicorn.

我的主要问题:为什么我可以通过带有curl的unix套接字从Django获得响应,而不能通过Vue的请求获得响应?为什么Vue的请求没有通过unix套接字从Gunicorn到Django?

My main problem: Why can I get responses from Django via the unix socket with curl, but not via requests from Vue? Why aren't Vue's requests making it from Gunicorn to Django via the unix socket?

我真的很困.有什么建议吗?

I'm really stuck. Any suggestions?

前端Nginx配置

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        # server_name example.com;
        # server_name myIP;
        root /var/www/example/frontend/dist;
        server_name example.com www.example.com;

        location =/robots.txt {
                root /opt/example;
        }

        location /thumbnail/ {
                alias /opt/example/static/img/thumbnail/;
        }

        location /bg/ {
                alias /opt/example/static/img/bg/;
        }

        location / {
                try_files $uri $uri/ /index.html;
        }
}

API Nginx配置

API Nginx config

upstream backend_server {
        server unix:/var/www/example/run/gunicorn.sock fail_timeout=0;
}

server {
        listen 80;
        server_name api.example.com
        client_max_body_size 4G;

        access_log /var/log/nginx/api-access.log;
        error_log /var/log/nginx/api-error.log;

        location / {
                include proxy_params;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_headers_hash_max_size 512;
                proxy_headers_hash_bucket_size 128;
                proxy_redirect off;
                if (!-f $request_filename) {
                        proxy_pass http://backend_server;
                }
        }
}

Gunicorn配置

Gunicorn config

#!/bin/bash

NAME="backend"
DJANGODIR=/var/www/example/backend
SOCKFILE=/var/www/example/run/gunicorn.sock
USER=django
GROUP=example
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=backend.settings
DJANGO_WSGI_MODULE=backend.wsgi
CONDA_SRC=/home/justin/anaconda3/etc/profile.d/conda.sh
GUNICORN=/home/justin/anaconda3/envs/production/bin/gunicorn

echo "starting backend"

cd $DJANGODIR
    source $CONDA_SRC
conda activate production
    export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
    export PYTHONPATH=$DJANGODIR:$PYTHONPATH

RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

exec $GUNICORN
 ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind=unix:$SOCKFILE \
  --log-level=debug \
  --log-file=- \
  --error-logfile=/var/www/example/backend/logs/gunicorn-error.log \
  --access-logfile=/var/www/example/backend/logs/gunicorn-access.log

独角兽access.log

Gunicorn access.log

- - [08/Sep/2020:01:51:24 -0400] "OPTIONS /c/about/ HTTP/1.0" 200 0 "http://example.com/c/about" "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Mobile Safari/537.36"
- - [08/Sep/2020:01:51:24 -0400] "POST /c/about/ HTTP/1.0" 400 143 "http://example.com/c/about" "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Mobile Safari/537.36"

推荐答案

neeraj9194 指出 400之后,我做了更多的搜索来寻找与Nginx,Gunicorn 400和Django有关的问题,并且遇到了很多类似的问题.看起来主要是Nginx问题.博客中的答案解决了我的问题.

After neeraj9194 pointed out the 400, I did more searching for issues relating to Nginx, Gunicorn 400 and Django and I came across a ton of similar issues. Looks like it's mainly an Nginx issue. The answer in this blog fixed my issue.

我将我的API Nginx配置中的 location 块替换为:

I replaced the location block in my API Nginx config with:

location / {
      proxy_set_header Host $host;
      proxy_pass http://backend_server;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_set_header X-Real-IP $remote_addr;
  }

这篇关于使用Nginx,Gunicorn和Supervisor部署Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-29 05:29