Nginx¶
Установка¶
Конфиги¶
/etc/nginx/sites-available -- доступные конфиги
/etc/nginx/sites-enabled/ -- активированные конфиги
или:
/etc/nginx/conf.d -- для rockylinux
Пример /etc/nginx/nginx.conf
user nginx; # От какого Unix-пользователя запускать worker-процессы
worker_processes auto; # Кол-во worker'ов; auto = по числу CPU
pid /run/nginx.pid; # PID-файл master-процесса
error_log /var/log/nginx/error.log warn; # Глобальный лог ошибок и минимальный уровень
# Подключение динамических модулей, если дистрибутив их так ставит
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024; # Сколько соединений может держать один worker
multi_accept on; # Принимать сразу несколько новых соединений
use epoll; # Метод обработки соединений на Linux
}
http {
include /etc/nginx/mime.types; # MIME-типы файлов
default_type application/octet-stream; # Тип по умолчанию, если не распознан
# Формат access log
log_format main
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # Основной access log
error_log /var/log/nginx/error.log warn; # Лог ошибок на уровне http
sendfile on; # Быстрая отдача файлов через sendfile()
tcp_nopush on; # Оптимизация отправки больших ответов
tcp_nodelay on; # Уменьшение задержек для keepalive/малых пакетов
keepalive_timeout 65; # Время удержания keepalive-соединения
keepalive_requests 1000; # Сколько запросов разрешить в одном keepalive-соединении
types_hash_max_size 4096; # Размер hash-таблицы MIME-типов
server_tokens off; # Не светить версию nginx в ответах/ошибках
charset utf-8; # Кодировка по умолчанию, если нужна
client_max_body_size 20m; # Максимальный размер тела запроса (upload)
client_body_buffer_size 128k; # Буфер для тела запроса
client_header_buffer_size 1k; # Буфер под request headers
large_client_header_buffers 4 16k; # Крупные заголовки/длинные cookie
reset_timedout_connection on; # Жестче закрывать таймаутные соединения
send_timeout 60s; # Таймаут отправки ответа клиенту
client_body_timeout 60s; # Таймаут чтения body
client_header_timeout 60s; # Таймаут чтения заголовков
# Gzip-сжатие
gzip on; # Включить gzip
gzip_comp_level 5; # Уровень сжатия
gzip_min_length 1024; # Не сжимать слишком маленькие ответы
gzip_proxied any; # Сжимать и для proxy-ответов
gzip_vary on; # Добавлять Vary: Accept-Encoding
gzip_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript
image/svg+xml; # Какие типы сжимать
# Если nginx стоит за reverse proxy / балансировщиком
# set_real_ip_from 10.0.0.0/8; # Доверенная сеть прокси
# real_ip_header X-Forwarded-For;# Откуда брать реальный IP клиента
# real_ip_recursive on; # Корректно обрабатывать цепочку прокси
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s; # Лимит запросов
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m; # Лимит соединений
# Cache path пример
# proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m
# max_size=1g inactive=60m use_temp_path=off;
# Upstream-группа backend'ов
upstream app_backend {
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; # Первый backend
# server 127.0.0.1:3001 backup; # Резервный backend
keepalive 32; # Keepalive к backend'ам
}
# Подключить все отдельные сайты
include /etc/nginx/conf.d/*.conf;
}
Пример /etc/nginx/conf.d/example.com
# /etc/nginx/conf.d/example.com.conf
server {
listen 80; # Слушать IPv4 на 80 порту
listen [::]:80; # Слушать IPv6 на 80 порту
server_name example.com www.example.com; # Имена хоста
access_log /var/log/nginx/example.com.access.log main; # Лог доступа сайта
error_log /var/log/nginx/example.com.error.log warn; # Лог ошибок сайта
return 301 https://example.com$request_uri; # Перенаправить HTTP -> HTTPS
}
server {
listen 443 ssl http2; # HTTPS + HTTP/2
listen [::]:443 ssl http2; # HTTPS + HTTP/2 по IPv6
server_name example.com www.example.com; # Домен и алиасы
root /var/www/example.com/public; # Корень сайта
index index.html index.htm index.php; # Индексные файлы
access_log /var/log/nginx/example.com.access.log main; # Access log
error_log /var/log/nginx/example.com.error.log warn; # Error log
# TLS / SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # Сертификат
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # Приватный ключ
ssl_session_timeout 1d; # Время жизни SSL-сессии
ssl_session_cache shared:SSL:10m; # Кэш SSL-сессий
ssl_session_tickets off; # Обычно выключают для безопасности
ssl_protocols TLSv1.2 TLSv1.3; # Разрешенные версии TLS
ssl_prefer_server_ciphers off; # Для современных настроек обычно off
# HSTS включай только когда точно уверен в HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Базовые security headers
add_header X-Frame-Options "SAMEORIGIN" always; # Защита от clickjacking
add_header X-Content-Type-Options "nosniff" always; # Не угадывать MIME
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Размер загрузок
client_max_body_size 20m; # Ограничение upload
# Если сайт статический
location / {
try_files $uri $uri/ /index.html; # Сначала файл/каталог, иначе index.html
}
# Кэширование статических файлов
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp|woff|woff2)$ {
expires 30d; # Кэш на 30 дней
access_log off; # Не логировать каждый статический файл
add_header Cache-Control "public, max-age=2592000, immutable";
}
# Скрыть чувствительные файлы
location ~ /\.(?!well-known).* {
deny all; # Запретить доступ к dotfiles
}
# Пример ACME challenge под certbot
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt; # Где лежат challenge-файлы
default_type "text/plain";
}
# Пример proxy на backend-приложение
location /app/ {
proxy_pass http://app_backend/; # Передать запрос в upstream
proxy_http_version 1.1; # HTTP/1.1 к backend
proxy_set_header Host $host; # Передать исходный Host
proxy_set_header X-Real-IP $remote_addr; # Реальный IP клиента
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Цепочка proxy IP
proxy_set_header X-Forwarded-Proto $scheme; # http/https
proxy_set_header Connection ""; # Для keepalive/proxy
proxy_read_timeout 60s; # Таймаут чтения от backend
proxy_connect_timeout 5s; # Таймаут коннекта к backend
proxy_send_timeout 60s; # Таймаут отправки в backend
# limit_req zone=req_limit_per_ip burst=20 nodelay; # Пример rate limit
# proxy_cache mycache; # Пример кэша proxy
# proxy_cache_valid 200 10m; # Кэш 200-ответов
}
# Кастомные страницы ошибок
error_page 404 /404.html; # Страница 404
location = /404.html {
internal; # Нельзя открыть напрямую извне
}
error_page 500 502 503 504 /50x.html; # Страница ошибок backend/сервера
location = /50x.html {
internal;
}
}
для debian-based:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
sudo nginx -t
sudo systemctl reload nginx
Сертификаты¶
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
sudo systemctl enable --now certbot-renew.timer
Load Balancer¶
http {
upstream api_backend {
server 127.0.0.1:8001 max_fails=3 fail_timeout=30s; # backend 1
server 127.0.0.1:8002 max_fails=3 fail_timeout=30s; # backend 2
keepalive 32; # keepalive к backend
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://api_backend; # отправить в upstream
proxy_http_version 1.1; # HTTP/1.1 к backend
proxy_set_header Host $host; # передать Host
proxy_set_header X-Real-IP $remote_addr; # IP клиента
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # цепочка IP
proxy_set_header X-Forwarded-Proto $scheme; # http/https
proxy_set_header Connection ""; # нормально для keepalive
proxy_connect_timeout 5s; # таймаут соединения к backend
proxy_read_timeout 60s; # таймаут чтения ответа
proxy_send_timeout 60s; # таймаут отправки запроса
}
}
}
round robin -- По умолчанию
least_conn -- Подходит, если запросы сильно отличаются по длительности.
upstream api_backend {
least_conn; # меньше активных соединений -> выше шанс получить запрос
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
ip_hash -- Подходит, если нужна “липкость” по IP клиента.
upstream api_backend {
ip_hash; # один клиентский IP старается ходить в один backend
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
hash -- Подходит, если маршрутизация должна зависеть от ключа.