148 lines
7.8 KiB
Plaintext
148 lines
7.8 KiB
Plaintext
# config/nginx/oknardia-app--external-nginx.conf
|
||
# ==============================================================================
|
||
# КОНФИГУРАЦИОННЫЙ ФАЙЛ NGINX (Reverse Proxy для Docker + Production)
|
||
# ==============================================================================
|
||
#
|
||
# ИНФОРМАЦИЯ:
|
||
# 1. Этот файл используется как шаблон при деплое
|
||
# 2. При первом деплое пути `/home/user/path-to-oknardia-app` заменяются на реальный путь через sed
|
||
# 3. Сгенерированный конфиг скопируется в `/etc/nginx/sites-available/oknardia`
|
||
# 4. Последующие деплои ОБНОВЛЯЮТ этот файл автоматически (sed + копирование)
|
||
#
|
||
# АРХИТЕКТУРА:
|
||
# - Nginx (порты 80/443) <-> Gunicorn контейнер (localhost:8000)
|
||
# - Медиа файлы отдаются из `/home/user/path-to-oknardia-app/media/` напрямую
|
||
# - Ошибки 5xx берутся из `media/_error` (копируются контейнером при старте)
|
||
# - Sitemap.xml отдается через Django/WhiteNoise (в media/_serv_sitemap/)
|
||
# - Static файлы (/static/) тоже отдаются через Django/WhiteNoise
|
||
|
||
# 1. Описываем, где живет наш Django в Docker
|
||
upstream oknardia-django {
|
||
# Мы пробрасываем порт 8050 из контейнера наружу (в docker-compose.yml имя сервиса 'web', контейнер 'oknardia-backend')
|
||
server 127.0.0.1:8060;
|
||
keepalive_requests 200;
|
||
}
|
||
|
||
# 2. Конфигурируем сервер
|
||
server {
|
||
server_name tmp.oknardia.ru; # Основное доменное имя
|
||
|
||
# Слушаем 80 порт (Certbot потом добавит сюда редирект на 443 и настройки SSL)
|
||
listen 80;
|
||
listen [::]:80;
|
||
|
||
charset utf-8;
|
||
client_max_body_size 10M; # Разрешаем загрузку не слишком больших картинок
|
||
|
||
# Логи (пути могут отличаться в зависимости от настроек сервера, здесь стандартные для Ubuntu)
|
||
access_log /var/log/nginx/oknardia.access.log;
|
||
error_log /var/log/nginx/oknardia.error.log;
|
||
|
||
# --- GZIP (Сжатие) ---
|
||
# Очень важно для динамического HTML от Django, который Gunicorn отдает несжатым.
|
||
gzip on;
|
||
gzip_vary on; # Добавляет заголовок Vary: Accept-Encoding
|
||
gzip_proxied any; # Сжимать ответы, даже если мы за прокси
|
||
gzip_comp_level 6; # Оптимальный баланс скорость/сжатие
|
||
gzip_min_length 1000; # Не сжимать совсем мелочь
|
||
# Типы файлов для сжатия (HTML сжимается автоматически, его писать не нужно)
|
||
gzip_types
|
||
text/plain
|
||
text/css
|
||
text/xml
|
||
text/javascript
|
||
application/javascript
|
||
application/json
|
||
application/xml
|
||
application/xml+rss
|
||
image/svg+xml
|
||
image/x-icon
|
||
application/vnd.ms-fontobject
|
||
font/woff
|
||
font/woff2;
|
||
|
||
# --- МЕДИА ФАЙЛЫ (Загруженный контент) ---
|
||
# Nginx отдает их напрямую с диска хоста, не дергая Docker.
|
||
# Сюда входит: загруженные картинки, документы, свитмапы, ошибки 5xx
|
||
# Путь должен совпадать с тем, где лежит volume на хост-машине.
|
||
location /media/ {
|
||
alias /home/user/path-to-oknardia-app/media/;
|
||
expires 30d; # Кешируем картинки на месяц
|
||
add_header Cache-Control "public, no-transform";
|
||
}
|
||
|
||
# --- SITEMAP.XML ---
|
||
# Sitemap хранится в media/_serv_sitemap/ но должен быть доступен из корня
|
||
# для поисковиков (они ищут http://example.com/sitemap.xml)
|
||
location = /sitemap.xml {
|
||
alias /home/user/path-to-oknardia-app/media/_serv_sitemap/sitemap.xml;
|
||
expires 7d; # Кешируем на неделю (редко меняется)
|
||
add_header Cache-Control "public";
|
||
}
|
||
|
||
# --- СТРАНИЦЫ ОШИБОК (Custom Error Pages) ---
|
||
# Если Django упал (502) или сработал тайм-аут (504), Nginx должен отдать статический HTML.
|
||
# Эти файлы копируются в `media/_error` при старте контейнера Docker.
|
||
#
|
||
# ВАЖНО: error_page директива перехватывает ошибки от апстрима (Gunicorn).
|
||
error_page 500 /500.html;
|
||
error_page 502 /502.html;
|
||
error_page 503 /503.html;
|
||
error_page 504 /504.html;
|
||
|
||
location = /500.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /502.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /503.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /504.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
|
||
error_page 400 /400.html;
|
||
error_page 401 /401.html;
|
||
error_page 403 /403.html;
|
||
error_page 404 /404.html;
|
||
error_page 413 /413.html;
|
||
error_page 429 /429.html;
|
||
|
||
location = /400.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /401.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /403.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /404.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /413.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
location = /429.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
|
||
error_page 405 406 407 408 409 410 411 412 414 415 416 417 418 421 422 423 424 425 426 428 431 451 /under_reconstruction.html;
|
||
location = /under_reconstruction.html { root /home/user/path-to-oknardia-app/media/_error; internal; }
|
||
|
||
# --- ВСЁ ОСТАЛЬНОЕ (Django + WhiteNoise) ---
|
||
# Статика (/static/), robots.txt, favicon.ico и сам сайт обрабатываются внутри контейнера.
|
||
# Nginx просто прокидывает запрос внутрь.
|
||
location / {
|
||
proxy_pass http://oknardia-django;
|
||
|
||
# Передаем правильные заголовки, чтобы Django знал реальный IP и протокол
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
|
||
# Если нужно чтобы Django обрабатывал и HTTP, и HTTPS, то можно раскомментировать эту строку
|
||
# и передавать реальный протокол от клиента
|
||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
||
# Явно указываем https, потому что клиент всегда приходит по HTTPS к Nginx
|
||
# Даже если внутри контейнера это HTTP на 127.0.0.1:8050, для Django это должно быть HTTPS
|
||
proxy_set_header X-Forwarded-Proto https;
|
||
|
||
# Тайм-ауты (важно для долгих операций, если они есть)
|
||
proxy_read_timeout 180s;
|
||
proxy_connect_timeout 180s;
|
||
}
|
||
}
|
||
|
||
# 3. Редирект с www на основной домен (SEO best practice)
|
||
server {
|
||
server_name www.tmp.oknardia.ru;
|
||
listen 80;
|
||
listen [::]:80;
|
||
return 301 $scheme://tmp.oknardia.ru$request_uri;
|
||
}
|
||
|