Skip to main content

Nginx Web Server

Базовое управление Nginx

Проверка состояния

# Статус службы
sudo systemctl status nginx

# Запуск
sudo systemctl start nginx

# Остановка
sudo systemctl stop nginx

# Перезагрузка конфигурации (без разрыва соединений)
sudo systemctl reload nginx

# Полный перезапуск
sudo systemctl restart nginx

Проверка конфигурации

# Проверка синтаксиса конфигов
sudo nginx -t

# Подробная проверка
sudo nginx -T

# Вывод версии и параметров компиляции
nginx -V

Структура конфигурации

/etc/nginx/
├── nginx.conf # Главный конфиг
├── conf.d/ # Дополнительные конфиги
├── sites-available/ # Доступные виртуальные хосты
├── sites-enabled/ # Активные хосты (симлинки)
├── modules-available/ # Доступные модули
├── modules-enabled/ # Активные модули
├── snippets/ # Переиспользуемые блоки конфигов
├── mime.types # MIME-типы
└── proxy_params # Параметры проксирования

Основные директории

# Корневая директория веб-сервера (по умолчанию)
/var/www/html/

# Альтернативные корневые директории
/var/www/site1/public/
/var/www/site2/public/

# Логи Nginx
/var/log/nginx/
├── access.log # Логи доступа
├── error.log # Логи ошибок
└── site1.access.log # Логи отдельных сайтов

# PID-файл
/var/run/nginx.pid

Создание виртуального хоста

1. Создание конфига

sudo nano /etc/nginx/sites-available/my-site.conf

2. Базовый конфиг виртуального хоста

server {
# Порт и адрес прослушивания
listen 80;
listen [::]:80;

# Доменные имена
server_name mysite.local www.mysite.local;

# Корневая директория сайта
root /var/www/mysite/public;

# Индексные файлы
index index.html index.htm index.php;

# Логи
access_log /var/log/nginx/mysite.access.log;
error_log /var/log/nginx/mysite.error.log;

# Основная location директория
location / {
try_files $uri $uri/ =404;
}

# Обработка PHP
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

# Статические файлы с кэшированием
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}

# Запрет доступа к скрытым файлам
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}

3. Активация сайта

# Создать симлинк в sites-enabled
sudo ln -s /etc/nginx/sites-available/my-site.conf /etc/nginx/sites-enabled/

# Или через более явную команду
sudo systemctl enable nginx-site-my-site

# Отключить сайт
sudo rm /etc/nginx/sites-enabled/my-site.conf
# или
sudo unlink /etc/nginx/sites-enabled/my-site.conf

# Проверить конфигурацию и перезагрузить
sudo nginx -t
sudo systemctl reload nginx

Работа с модулями

Проверка установленных модулей

# Вывести все загруженные модули
nginx -V 2>&1 | grep --color -o "with-http_[a-z_]*_module"

# Проверить конкретный модуль в конфиге
sudo nginx -T 2>/dev/null | grep "load_module"

Основные модули (уже встроены)

  • http_gzip_module — сжатие gzip
  • http_ssl_module — поддержка HTTPS
  • http_rewrite_module — перезапись URL
  • http_proxy_module — проксирование
  • http_fastcgi_module — работа с PHP-FPM
  • http_headers_module — управление заголовками

Настройка PHP через PHP-FPM

Конфигурация PHP-FPM пула

# Проверить статус PHP-FPM
sudo systemctl status php8.1-fpm

# Просмотреть пулы
ls /etc/php/8.1/fpm/pool.d/

# Настроить пул
sudo nano /etc/php/8.1/fpm/pool.d/mysite.conf

Пример конфига PHP-FPM пула

[mysite]
user = www-data
group = www-data

listen = /run/php/php8.1-fpm-mysite.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8

php_admin_value[upload_max_filesize] = 10M
php_admin_value[post_max_size] = 10M

Конфиг Nginx для PHP-FPM

location ~ \.php$ {
# Быстрый 404 для несуществующих PHP файлов
try_files $uri =404;

# Разделитель пути и query string
fastcgi_split_path_info ^(.+\.php)(/.+)$;

# Параметры PHP
fastcgi_pass unix:/run/php/php8.1-fpm-mysite.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

# Стандартные параметры
include fastcgi_params;

# Таймауты
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
}

Обратное проксирование (Reverse Proxy)

Проксирование на локальное приложение

server {
listen 80;
server_name app.local;

location / {
# Прокси на Node.js приложение
proxy_pass http://127.0.0.1:3000;

# Передача оригинальных заголовков
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_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}

# WebSocket поддержка
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Балансировка нагрузки между серверами

upstream backend {
# Алгоритм балансировки
least_conn; # или ip_hash, hash

# Серверы бэкенда
server 192.168.0.101:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.0.102:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.0.103:8080 backup; # Резервный сервер
}

server {
listen 80;
server_name api.local;

location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}

Безопасность Nginx

Базовые настройки безопасности

# В основном конфиге или конкретном server блоке
server_tokens off; # Скрыть версию Nginx
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";

# Ограничение методов HTTP
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}

# Защита от ботов
if ($http_user_agent ~* (bot|crawler|spider)) {
return 403;
}

Ограничение доступа по IP

# Разрешить только определенные IP
location /admin {
allow 192.168.0.0/24;
allow 127.0.0.1;
deny all;

try_files $uri $uri/ =404;
}

# Базовая HTTP авторизация
location /secure {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}

Создание файла .htpasswd

# Установка утилиты
sudo apt install apache2-utils

# Создание файла с пользователем
sudo htpasswd -c /etc/nginx/.htpasswd username

# Добавление еще одного пользователя
sudo htpasswd /etc/nginx/.htpasswd anotheruser

Оптимизация производительности

Настройка кэширования

# Кэширование статических файлов
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}

# Кэширование прокси
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g
inactive=60m use_temp_path=off;

location /api/ {
proxy_cache my_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}

Сжатие gzip

gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;

Лимиты запросов

# Ограничение частоты запросов
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

location /login {
limit_req zone=one burst=20 nodelay;
proxy_pass http://backend;
}

# Ограничение скорости скачивания
location /downloads/ {
limit_rate 500k; # 500 КБ/с
limit_rate_after 10m; # После 10 МБ
}

Мониторинг и логи

Просмотр логов в реальном времени

# Все логи доступа
sudo tail -f /var/log/nginx/access.log

# Логи ошибок
sudo tail -f /var/log/nginx/error.log

# Конкретный виртуальный хост
sudo tail -f /var/log/nginx/mysite.access.log

# Фильтр по IP
sudo tail -f /var/log/nginx/access.log | grep "192.168.0.100"

# Поиск ошибок 404
sudo tail -f /var/log/nginx/access.log | grep " 404 "

Статус Nginx

# Конфиг для страницы статуса
server {
listen 127.0.0.1:8080;
server_name localhost;

location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}

Проверить статус:

curl http://127.0.0.1:8080/nginx_status

Мониторинг производительности

# Активные соединения
sudo netstat -anp | grep :80 | wc -l

# Использование памяти Nginx
ps aux | grep nginx | awk '{sum+=$6} END {print sum/1024 " MB"}'

# Статус worker процессов
sudo kill -USR1 $(cat /var/run/nginx.pid) # Переоткрыть логи
sudo kill -USR2 $(cat /var/run/nginx.pid) # Переключить лог-файлы

Решение проблем

Ошибка "nginx: [emerg] bind() to 0.0.0.0:80 failed"

# Проверить, какой процесс использует порт
sudo lsof -i :80
sudo ss -tulpn | grep :80

# Если Apache мешает
sudo systemctl stop apache2
sudo systemctl disable apache2

Ошибка "Permission denied"

# Проверить права на директории
sudo chown -R www-data:www-data /var/www/mysite
sudo chmod -R 755 /var/www/mysite

# Права на сокет PHP-FPM
sudo chown www-data:www-data /run/php/php8.1-fpm.sock
sudo chmod 660 /run/php/php8.1-fpm.sock

Nginx не запускается

# Проверить синтаксис конфигов
sudo nginx -t

# Посмотреть подробные ошибки
sudo journalctl -xe | grep nginx
sudo tail -n 50 /var/log/nginx/error.log

# Проверить занятость портов
sudo netstat -tlnp | grep -E ":80|:443"

PHP не обрабатывается

# Проверить статус PHP-FPM
sudo systemctl status php8.1-fpm

# Проверить сокет
ls -la /run/php/php8.1-fpm.sock

# Тестовый PHP файл
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/test.php

Полезные команды для разработки

Тестирование конфигурации

# Проверить конкретный конфиг
sudo nginx -t -c /etc/nginx/sites-available/my-site.conf

# Показать полную конфигурацию
sudo nginx -T

# Перезагрузить только если конфиг валиден
sudo nginx -t && sudo systemctl reload nginx

Отладка запросов

# Логирование в реальном времени с фильтрацией
sudo tail -f /var/log/nginx/access.log | awk '{print $1, $7, $9}'

# Мониторинг медленных запросов
sudo tail -f /var/log/nginx/access.log | grep " [0-9]\.[0-9][0-9][0-9] "

# Тестовые запросы с таймингом
time curl -I http://192.168.0.103/

Быстрое создание тестового сайта

# Создать директорию
sudo mkdir -p /var/www/test/{public,logs,backup}

# Создать index.html
echo "<h1>Test Site</h1><p>$(date)</p>" | sudo tee /var/www/test/public/index.html

# Копировать дефолтный конфиг
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/test.conf

# Редактировать конфиг
sudo sed -i 's|/var/www/html|/var/www/test/public|g' /etc/nginx/sites-available/test.conf
sudo sed -i 's|server_name _;|server_name test.local;|g' /etc/nginx/sites-available/test.conf

# Активировать
sudo ln -s /etc/nginx/sites-available/test.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Конфигурация для продакшена

Оптимизация worker процессов

# В /etc/nginx/nginx.conf
worker_processes auto; # Автоматически по количеству ядер
worker_rlimit_nofile 65535;

events {
worker_connections 4096;
multi_accept on;
use epoll; # Для Linux
}

http {
# Таймауты
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;

# Буферы
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;

# Файловый дескриптор кэш
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
}

Настройка HTTPS с Let's Encrypt

# Установка Certbot
sudo apt install certbot python3-certbot-nginx

# Получение сертификата
sudo certbot --nginx -d mysite.local -d www.mysite.local

# Автоматическое обновление
sudo certbot renew --dry-run

Конфиг Nginx для HTTPS:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mysite.local;

# Сертификаты Let's Encrypt
ssl_certificate /etc/letsencrypt/live/mysite.local/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.local/privkey.pem;

# Настройки SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;

# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;

# Остальная конфигурация...
}

# Редирект HTTP → HTTPS
server {
listen 80;
listen [::]:80;
server_name mysite.local www.mysite.local;
return 301 https://$server_name$request_uri;
}

Ссылки на документацию