# ============================================================================== # ЭТАЛОННЫЙ КОНФИГУРАЦИОННЫЙ ФАЙЛ NGINX (Reverse Proxy для Docker) # ============================================================================== # # ВНИМАНИЕ: # Этот файл является шаблоном. При первом деплое он копируется в `/home/user/app/dq-site/config/nginx/dq-app--external-nginx.conf`, # а затем (уже руками) через силинк в `/etc/nginx/sites-available/` и активируется. # При последующих деплоях он НЕ ПЕРЕЗАПИСЫВАЕТСЯ автоматически, чтобы не затереть SSL-сертификаты и ручные правки. # # Если вы изменили этот файл в репозитории и хотите применить изменения на проде: # вам нужно обновить файл в `/home/user/app/dq-site/config/nginx/dq-app--external-nginx.conf` вручную (diff + copy). # # Так же (рядом) будет создан образец этого файла `nginx_dq.conf.example`, который будет обновляться при деплоях # из репозитория, чтобы вы могли видеть, что изменилось и при необходимости перенести эти изменения на прод. # # Предполагаемая структура на сервере: # /home/user/app/dq-site/ # ├── docker-compose.yml # ├── .env # ├── media/ <-- Сюда Nginx смотрит напрямую (Docker volume) # └── ... # 1. Описываем, где живет наш Django в Docker upstream dq-django { # Мы пробрасываем порт 8000 из контейнера наружу (в docker-compose.yml: ports: - "8000:8000") server 127.0.0.1:8000; keepalive_requests 200; } # 2. Конфигурируем сервер server { server_name dq.cube2.ru dq2.cube2.ru; # Основное доменное имя # Слушаем 80 порт (Certbot потом добавит сюда редирект на 443 и настройки SSL) listen 80; charset utf-8; client_max_body_size 10M; # Разрешаем загрузку не слишком больших картинок # Логи (пути могут отличаться в зависимости от настроек сервера, здесь стандартные для Ubuntu) access_log /var/log/nginx/dq.access.log; error_log /var/log/nginx/dq.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. # Путь должен совпадать с тем, где лежит volume на хост-машине. # ВАЖНО: Убедитесь, что пользователь nginx (www-data) имеет права на чтение этой папки! # ТРЕБУЕТСЯ ЗАМЕНА ПРИ ДЕПЛОЕ: /home/user/app/dq-site -> ваш реальный путь location /media/ { alias /home/user/app/dq-site/media/; expires 30d; # Кешируем картинки на месяц add_header Cache-Control "public, no-transform"; } # --- СТРАНИЦЫ ОШИБОК (Custom Error Pages) --- # Если Django упал (502) или файл из media не найден Nginx-ом (404), показываем наши красивые заглушки. # Файлы копируются в media/errors при старте контейнера. # ТРЕБУЕТСЯ ЗАМЕНА ПРИ ДЕПЛОЕ: /home/user/app/dq-site -> ваш реальный путь error_page 404 /404.html; error_page 500 502 503 504 /500.html; location = /404.html { root /home/user/app/dq-site/media/errors; internal; } location = /500.html { root /home/user/app/dq-site/media/errors; internal; } # --- ВСЁ ОСТАЛЬНОЕ (Django + WhiteNoise) --- # Статика (/static/), robots.txt, favicon.ico и сам сайт обрабатываются внутри контейнера. # Nginx просто прокидывает запрос внутрь. location / { proxy_pass http://dq-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; proxy_set_header X-Forwarded-Proto $scheme; # Тайм-ауты (важно для долгих операций, если они есть) proxy_read_timeout 180s; proxy_connect_timeout 180s; } } # 3. Редирект с www на без-www (SEO best practice) server { server_name www.dq.cube2.ru www.dq2.cube2.ru; listen 80; return 301 $scheme://dq.cube2.ru$request_uri; # Всегда редиректим на основной бой (или можно на текущий хост через if) }