Files
2026-hypn0-site/config/nginx/hypn0-app--external-nginx.conf
2026-09-20 22:30:13 +03:00

160 lines
9.5 KiB
Plaintext

# config/nginx/hypn0-app--external-nginx.conf
# ==============================================================================
# ЭТАЛОННЫЙ КОНФИГУРАЦИОННЫЙ ФАЙЛ NGINX (Reverse Proxy для Docker)
# ==============================================================================
#
# ВНИМАНИЕ:
# Этот файл является шаблоном. При первом деплое он копируется в `/home/user/app/hypn0-site/config/nginx/hypn0-app--external-nginx.conf`,
# а затем (уже руками) через силинк в `/etc/nginx/sites-available/` и активируется.
# При последующих деплоях он НЕ ПЕРЕЗАПИСЫВАЕТСЯ автоматически, чтобы не затереть SSL-сертификаты и ручные правки.
#
# Если вы изменили этот файл в репозитории и хотите применить изменения на проде:
# вам нужно обновить файл в `/home/user/app/hypn0-site/config/nginx/hypn0-app--external-nginx.conf` вручную (diff + copy).
#
# Так же (рядом) будет создан образец этого файла `nginx_hypn0.conf.example`, который будет обновляться при деплоях
# из репозитория, чтобы вы могли видеть, что изменилось и при необходимости перенести эти изменения на прод.
#
# Предполагаемая структура на сервере:
# /home/user/app/hypn0-site/
# ├── docker-compose.yml
# ├── .env
# ├── media/ <-- Сюда Nginx смотрит напрямую (Docker volume)
# └── ...
# 1. Описываем, где живет наш Django в Docker
upstream hypn0-django {
# Мы пробрасываем порт 8042 из контейнера наружу (в docker-compose.yml имя сервиса 'web', контейнер 'hypn0-backend')
server 127.0.0.1:8042;
keepalive_requests 200;
}
# 2. Конфигурируем сервер
server {
server_name hypn0.xyz; # Основное доменное имя
# Слушаем 80 порт (Certbot потом добавит сюда редирект на 443 и настройки SSL)
listen 80;
listen [::]:80;
charset utf-8;
client_max_body_size 10M; # Разрешаем загрузку не слишком больших картинок
# --- СЕТЕВЫЕ ОПТИМИЗАЦИИ И ЗАЩИТА ОТ ТАЙМАУТОВ ЧЕРЕЗ VPN (MTU/MSS) ---
tcp_nopush on; # Отправляет заголовки и начало файла в одном TCP-пакете
tcp_nodelay on; # Отключает задержку Nagle для быстрых интерактивных ответов
ssl_buffer_size 4k; # Уменьшенный буфер TLS: решает зависания пакетов в VPN/WireGuard туннелях
# Логи (пути могут отличаться в зависимости от настроек сервера, здесь стандартные для Ubuntu)
access_log /var/log/nginx/hypn0.access.log;
error_log /var/log/nginx/hypn0.error.log;
# --- GZIP (Сжатие) ---
# Очень важно для динамического HTML от Django, который Gunicorn отдает несжатым.
gzip on;
gzip_vary on; # Добавляет заголовок Vary: Accept-Encoding
gzip_proxied any; # Сжимать ответы, даже если мы за прокси
gzip_comp_level 6; # Оптимальный баланс скорость/сжатие
gzip_min_length 256; # Сжимать ответы от 256 байт
# Типы файлов для сжатия (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.
# Путь должен совпадать с тем, где лежит volume на хост-машине.
# ВАЖНО: Убедитесь, что пользователь nginx (www-data) имеет права на чтение этой папки!
# ТРЕБУЕТСЯ ЗАМЕНА ПРИ ДЕПЛОЕ: /home/user/app/hypn0-site -> ваш реальный путь
location /media/ {
alias /home/user/app/hypn0-site/media/;
expires 30d; # Кешируем картинки на месяц
add_header Cache-Control "public, no-transform";
}
# --- СТРАНИЦЫ ОШИБОК (Custom Error Pages) ---
# Если Django упал (502) или сработал тайм-аут (504), Nginx должен отдать статический HTML.
# Эти файлы должны лежать в папке, доступной Nginx (например, в `media/_error`).
#
# ВАЖНО:
# 1. Файлы 50x.html (500, 502, 503, 504) копируются в `media/_error` при старте контейнера (см. docker-compose.prod-test.yml -> command).
# 2. 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/app/hypn0-site/media/_error; internal; }
location = /502.html { root /home/user/app/hypn0-site/media/_error; internal; }
location = /503.html { root /home/user/app/hypn0-site/media/_error; internal; }
location = /504.html { root /home/user/app/hypn0-site/media/_error; internal; }
# 404 (и другие) тоже нужно кастомизировать... обычно Django сам отдает 404.
# Но, например, Nginx отдаст 404 при ошике доступа к media-файлам (они храняться на хосте, а не в контейнере)
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/app/hypn0-site/media/_error; internal; }
location = /401.html { root /home/user/app/hypn0-site/media/_error; internal; }
location = /403.html { root /home/user/app/hypn0-site/media/_error; internal; }
location = /404.html { root /home/user/app/hypn0-site/media/_error; internal; }
location = /413.html { root /home/user/app/hypn0-site/media/_error; internal; }
location = /429.html { root /home/user/app/hypn0-site/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/app/hypn0-site/media/_error; internal; }
# --- ВСЁ ОСТАЛЬНОЕ (Django + WhiteNoise) ---
# Статика (/static/), robots.txt, favicon.ico и сам сайт обрабатываются внутри контейнера.
# Nginx просто прокидывает запрос внутрь.
location / {
proxy_pass http://hypn0-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:8042, для Django это должно быть HTTPS
proxy_set_header X-Forwarded-Proto https;
# --- БУФЕРИЗАЦИЯ В ПАМЯТИ (RAM) ---
# Позволяет отдавать большие страницы (80+ КБ) целиком из RAM без записи во временные файлы /var/lib/nginx/proxy
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 8 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
# Тайм-ауты (важно для долгих операций, если они есть)
proxy_read_timeout 180s;
proxy_connect_timeout 180s;
}
}
# 3. Редирект с www на без-www (SEO best practice)
# server {
# server_name www.hypn0.ru;
# listen 80;
# return 301 $scheme://hypn0.ru$request_uri; # Всегда редиректим на основной домен
# }