Я пытаюсь развернуть свое приложение Django с Nginx и Gunicorn, следуя этому руководству, но я изменил некоторые шаги, чтобы использовать Conda вместо ViritualEnv.
Настройка выглядит так:
- Nginx отвечает моим приложением Vue
- Запросы от Vue отправляются на api.example.com
- Nginx слушает api.example.com и направляет запросы в unix-сокет Gunicorn
Вещи, которые я проверил:
- Я вижу запросы Vue в
access.log
. - Я также могу видеть эти запросы в
journalctl -f -u gunicorn
, вsupervisor.log
и в журнале access.log. - Когда мое приложение Django запускается, оно создает файл журнала, поэтому я вижу, что Gunicorn запускает его. Но Django не отвечает на запросы из сокета unix.
- Я вижу ответ от Django, когда вхожу по ssh и запускаю следующую команду:
curl --no-buffer -XGET --unix-socket /var/www/example/run/gunicorn.sock http://localhost/about
. Эта команда дает ответ только тогда, когда любой из моихALLOWED_HOSTS
используется вместоlocalhost
. - Мои конфигурации Nginx, Supervisor и Gunicorn используют полный путь к
gunicorn.sock
.
Должен ли я увидеть, что Django работает на порту 8000 или что-то еще, если я сделаю что-то вроде nmap localhost
? Я видел еще одну публикацию, в которой упоминалось, что Nginx должен указывать на порт 8000 и что Gunicorn должен быть запущен либо с:
gunicorn --bind 0.0.0.0:8000 <djangoapp>.wsgi --daemon
gunicorn <djangoapp>.wsgi:application --bind <IP>:8000 --daemon
gunicorn <djangoapp>.wsgi:application --bind=unix:/var/www/example/run/gunicorn.sock
Но разве раскрытие порта 8000 не уничтожает цель использования Nginx в качестве обратного прокси и unix-сокета Gunicorn? Разве экспонирование 8000 не увеличивает площадь для векторов атаки? Или лучше всего выставить порт 8000? Я немного сбит с толку, почему я должен использовать оба порта и Nginx, и Gunicorn.
Моя основная проблема: почему я могу получать ответы от Django через сокет unix с помощью curl, но не через запросы от Vue? Почему запросы Vue не поступают из Gunicorn в Django через сокет unix?
Я действительно застрял. Какие-либо предложения?
Конфигурация Frontend 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
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
#!/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
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"
[*]
и debug = True и посмотрим, поможет ли это ... если да, то ваш nginx не возвращает правильные хосты в django. Посмотрите, установлено ли дляUSE_X_FORWARDED_HOST
значение "Ложь". 08.09.2020DEBUG=True
иALLOWED_HOSTS=['*']
. Я должен был делать звездочку без кавычек или с кавычками? Тоже не ставил изначальноUSE_X_FORWARDED_HOST
. 08.09.2020