Настройка nginx для обычного сайта укладывается в один файл на 30–40 строк: описываете домен, путь к файлам, индексный файл, включаете сжатие и кэш статики, добавляете сертификат и редирект на HTTPS. Всё остальное — тонкая доводка под нагрузку. Ставится он на любой виртуальный сервер: тарифы, где nginx уже развёрнут или ставится одной командой, собраны в разделе VPS под nginx — там 44 провайдера и цены от 139 ₽/мес.
Материал для тех, кто впервые открыл конфиг и не понимает, что означают фигурные скобки и почему сайт отдаёт «Welcome to nginx» вместо своих страниц. Разберём структуру конфигурации и рабочий server-блок построчно. Дальше — директивы, которые чаще всего ломают сайт, порядок включения HTTPS и проверка изменений до перезапуска.
Что делает nginx и где физически лежат его конфиги
nginx — это веб-сервер: программа, которая слушает сетевой порт, принимает HTTP-запросы браузера и отдаёт в ответ файлы. Второй вариант — передать запрос дальше: в PHP-FPM (службу, которая выполняет PHP-код сайта) или в приложение на Node.js. Порт 80/TCP он занимает для обычного HTTP, порт 443/TCP — для HTTPS. Один процесс nginx спокойно обслуживает несколько десятков сайтов на одном сервере.
После установки на Debian или Ubuntu файлы раскладываются по трём местам. Главный файл — /etc/nginx/nginx.conf: в нём глобальные настройки, общие для всего сервера. Описания отдельных сайтов лежат в /etc/nginx/sites-available/ — по одному файлу на домен. Каталог /etc/nginx/sites-enabled/ содержит символические ссылки на те файлы, которые сейчас активны.
Такое разделение удобно: чтобы временно отключить сайт, файл с настройками не удаляют — убирают только ссылку. На CentOS и Rocky Linux каталогов sites-available нет, вместо них используется /etc/nginx/conf.d/, куда кладут файлы с расширением .conf. Логи по умолчанию пишутся в /var/log/nginx/access.log и /var/log/nginx/error.log — второй файл открывают первым, когда что-то не работает.
Как устроен конфиг: контексты, директивы и точка с запятой
Конфигурация nginx — это дерево вложенных блоков, которые называются контекстами. Верхний уровень — главный контекст, в нём задают, от какого пользователя работает сервер и сколько рабочих процессов запускать. Внутри него блок events отвечает за обработку соединений, блок http — за всё, что связано с веб-трафиком.
Внутри http живут блоки server — по одному на сайт. Внутри server находятся блоки location, которые описывают поведение для конкретных путей: отдельно для картинок, отдельно для PHP-скриптов, отдельно для всего остального. Правило наследования простое: настройка, заданная снаружи, действует внутри, пока её не переопределили.
Каждая строка-директива заканчивается точкой с запятой. Забытая точка с запятой — причина примерно половины ошибок запуска у новичков, и nginx честно сообщает номер строки. Комментарии начинаются с решётки. Регистр важен: gzip on; работает, GZIP On; — нет.
Ещё одна частая конструкция — директива include. Она подключает содержимое другого файла: строка include /etc/nginx/sites-enabled/*; в главном файле втягивает описания всех активных сайтов. Поэтому ошибка, о которой сообщает nginx, нередко живёт не в том файле, который вы правили.
Минимальный server-блок: домен, root и индексный файл
Файл сайта создают в /etc/nginx/sites-available/ и называют по домену, например example.ru. Директива listen указывает порт, server_name — домены, на которые отвечает этот блок, root — каталог с файлами сайта, index — какой файл отдавать при запросе каталога.
server {
listen 80;
server_name example.ru www.example.ru;
root /var/www/example.ru;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
Строка try_files $uri $uri/ =404; означает: сначала поискать файл с таким именем, потом каталог, а если ничего не нашлось — вернуть ошибку 404. Для сайтов на WordPress и других CMS с человекопонятными адресами последнюю часть меняют на /index.php?$args, иначе внутренние страницы будут отдавать 404.
Каталог root должен существовать и быть доступен на чтение пользователю www-data — от его имени работают рабочие процессы. Права 755 на каталоги и 644 на файлы закрывают вопрос: владелец может менять, остальные — только читать. Если сайт лежит в домашней папке пользователя, проверьте права и на неё саму: nginx проверяет права на весь путь целиком.

Включение сайта симлинком и проверка через nginx -t
Созданный файл сам по себе ничего не делает — nginx читает только каталог sites-enabled. Символическую ссылку (её же называют симлинком) создают командой ln -s /etc/nginx/sites-available/example.ru /etc/nginx/sites-enabled/: она указывает на исходный файл, но самого файла не копирует. Заодно стоит удалить ссылку default: именно она отдаёт страницу «Welcome to nginx» и перехватывает запросы к домену, для которого не нашлось своего блока.
Перед перезапуском конфиг проверяют командой nginx -t — она разбирает все файлы и печатает syntax is ok и test is successful либо точный путь и номер строки с ошибкой. Проверка занимает доли секунды и не трогает работающий сервер, поэтому её делают всегда, даже после правки одной строки.
Применяют изменения командой nginx -s reload. Она не убивает текущие соединения: старые рабочие процессы дорабатывают начатые запросы и завершаются, новые запросы уходят уже в процессы с новым конфигом. Полный restart нужен редко — например, после смены директивы listen на другой порт. На чистом сервере эти шаги удобно делать сразу после базовой подготовки системы, порядок которой описан в гайде как настроить VPS с нуля.
worker_processes и worker_connections: сколько запросов держит сервер
Директива worker_processes auto; в главном контексте говорит nginx запустить столько рабочих процессов, сколько у сервера ядер. На тарифе с 1 ядром процесс будет один, на 4 ядрах — четыре. Ручное завышение не ускоряет сайт: процессы начинают конкурировать за то же самое время процессора.
Внутри блока events задаётся worker_connections — сколько одновременных соединений держит один процесс. Значение по умолчанию 1024. Теоретический максимум для сервера считается умножением: 4 ядра × 1024 = 4096 одновременных соединений. Браузер обычно открывает 2–6 соединений на страницу, так что даже базовые 1024 покрывают сотни посетителей онлайн.
Упереться в лимит системы проще, чем в лимит nginx: процесс в Linux по умолчанию может держать открытыми 1024 файловых дескриптора — так называют любой открытый файл или соединение. Каждое соединение занимает один дескриптор. Потолок поднимает директива worker_rlimit_nofile 8192;. Трогать её есть смысл от нескольких тысяч посетителей в сутки.
| Директива | Контекст | По умолчанию | Рабочее значение |
|---|---|---|---|
| worker_processes | главный | 1 | auto (по числу ядер) |
| worker_connections | events | 1024 | 1024–4096 |
| client_max_body_size | http, server | 1 МБ | 16–64 МБ |
| keepalive_timeout | http | 75 с | 15–30 с |
| gzip_comp_level | http | 1 | 5 |
| server_tokens | http | on | off |

Ошибка 413 и client_max_body_size: почему не грузится файл
Директива client_max_body_size ограничивает размер тела запроса — то есть всего, что посетитель отправляет на сервер. По умолчанию это 1 МБ. Любая фотография с телефона весит больше, поэтому загрузка картинки в админку CMS обрывается с ошибкой 413 Request Entity Too Large — и это одна из самых частых жалоб после переезда на свой сервер.
Лечится строкой client_max_body_size 64m; внутри блока http или конкретного server. Значения 16 МБ хватает для обычного блога с фотографиями, 64 МБ — для каталога товаров, 256 МБ — если через сайт заливают видео или архивы. Ставить безлимит (0) не стоит: это открытая дверь для мусорных загрузок, которые забьют диск.
Вторая половина проблемы живёт не в nginx. Для сайтов на PHP тот же лимит дублируется в php.ini параметрами upload_max_filesize и post_max_size, а также max_execution_time — по умолчанию 30 секунд. Поднимать нужно все четыре значения согласованно, иначе файл пройдёт через веб-сервер и упрётся уже в интерпретатор.
Сжатие gzip: минус 60–80 % веса текстовых файлов
gzip сжимает ответ перед отправкой в браузер, а браузер распаковывает его на лету. Для HTML, CSS, JavaScript и JSON экономия составляет порядка 60–80 % объёма: страница на 300 КБ уезжает к посетителю как 70–90 КБ. Для JPEG, PNG и видео сжатие бесполезно — они уже сжаты, и повторная обработка только тратит процессор.
Минимальный набор строк для блока http: gzip on;, список типов в gzip_types, порог gzip_min_length 1024; и уровень gzip_comp_level 5;. Уровень задаётся от 1 до 9. Пятый — разумный баланс: относительно девятого он даёт примерно тот же результат по объёму при заметно меньшей нагрузке на процессор, что важно на тарифе с одним ядром.
Порог в 1024 байта отсекает мелочь: на ответе в 200 байт накладные расходы съедят выигрыш. Проверить сжатие можно командой curl -I -H "Accept-Encoding: gzip" https://example.ru — в ответе должен появиться заголовок Content-Encoding: gzip. Сжатие особенно заметно на медленных мобильных каналах, где каждые лишние 100 КБ добавляют секунду к загрузке.
Кэш статики: заголовок expires для картинок, CSS и скриптов
Браузерное кэширование — это указание браузеру сохранить файл у себя и не запрашивать его повторно указанный срок. Для логотипа, шрифтов и стилей это правильное поведение: они меняются раз в месяцы, а запрашиваются на каждой странице. Делается это отдельным блоком location с регулярным выражением — шаблоном, который перечисляет расширения файлов.
location ~* .(jpg|jpeg|png|webp|svg|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
}
Директива expires 30d; добавляет к ответу срок годности в 30 дней. Строка access_log off; отключает запись обращений к статике в журнал — на сайте с сотней картинок это сокращает лог в разы и снимает лишние операции записи на диск. Для файлов, которые не меняются никогда, ставят expires 365d;.
Обратная сторона: обновив CSS, вы не увидите изменений, пока не истечёт срок или не очистите кэш браузера. Стандартное решение — добавлять к адресу файла версию: style.css?v=12. Для страниц, генерируемых CMS, кэш в браузере не включают — иначе посетитель увидит вчерашнюю корзину. Что ещё можно ускорить на уровне сервера, разобрано в материале про оптимизацию VPS.
HTTPS и редирект: как закрыть сайт сертификатом
HTTPS шифрует трафик между браузером и сервером и давно стал условием для нормального ранжирования и доверия посетителей. Бесплатный сертификат от Let’s Encrypt выдаётся на 90 дней и обновляется автоматически — утилита certbot ставит задачу в планировщик и продлевает сертификат за 30 дней до окончания срока.
После выпуска сертификата у сайта становится два server-блока. Первый слушает порт 80 и делает единственную вещь — отдаёт постоянный редирект: return 301 https://$host$request_uri;. Второй слушает 443 с параметрами ssl и http2, содержит пути к файлам сертификата и ключа и всю остальную конфигурацию сайта.
Включённый HTTP/2 добавляется одним словом в строке listen 443 ssl http2; и заметно ускоряет страницы с большим числом мелких файлов: браузер тянет их по одному соединению вместо шести. Пошаговый выпуск сертификата с командами certbot расписан в отдельной инструкции — как установить SSL Let’s Encrypt.
Оба server-блока certbot дописывает сам и не трогает ваши настройки gzip и кэша. Продление проверяют командой certbot renew --dry-run: она имитирует обновление и показывает, сработает ли оно автоматически через 60 дней.
Настройка nginx с нуля: семь шагов по порядку
Ниже — последовательность для чистого сервера на Ubuntu 22.04 или 24.04. Каждый шаг проверяем перед переходом к следующему: так ошибку видно сразу. Домен к моменту старта должен указывать A-записью на IP сервера, иначе сертификат не выпустится.
- Поставить пакет:
apt update && apt install nginx— веб-сервер запустится на порту 80. - Открыть в файрволе порты 80 и 443, проверить по IP, что отдаётся страница-заглушка.
- Создать каталог
/var/www/example.ruи положить в него тестовыйindex.html. - Написать файл в
sites-availableс listen, server_name, root, index и блоком location. - Создать симлинк в
sites-enabled, удалить ссылкуdefault, выполнитьnginx -tиnginx -s reload. - Добавить в блок
httpgzip,client_max_body_size 64mи location для статики сexpires 30d. - Выпустить сертификат certbot и убедиться, что запрос по http отдаёт код 301 на https-адрес.
После седьмого шага сайт рабочий. Дальше идёт PHP-FPM или проксирование на приложение — в этой роли nginx работает как обратный прокси, передавая запросы внутреннему сервису на локальном порту.
Сколько ресурсов и денег нужно серверу под nginx
Сам nginx нетребователен: рабочий процесс занимает 2–10 МБ памяти, и на сайт-визитку хватает тарифа с 1 ядром и 1 ГБ RAM. Память съедает то, что стоит за ним: PHP-FPM на WordPress просит от 512 МБ, база MySQL — ещё 256–512 МБ. Отсюда правило: 2 ГБ RAM на один сайт с CMS, 4 ГБ — на три-четыре.
Тип диска важнее его объёма: на NVMe отдача статики и запросы к базе идут заметно быстрее, чем на HDD, а разница в цене тарифа редко превышает 100 ₽/мес. Стартовые цены провайдеров в разделе выглядят так.
| Провайдер | Цена от | Стартовая конфигурация | Тарифов |
|---|---|---|---|
| RuVDS | 139 ₽/мес | 1 ядро, 0,5 ГБ RAM, 10 ГБ HDD | 440 |
| Selectel | 200 ₽/мес | 1 ядро, 1 ГБ RAM, 10 ГБ NVMe | 69 |
| Aéza | 593 ₽/мес | 1 ядро, 2 ГБ RAM, 30 ГБ NVMe | 151 |
Данные проверены 03.09.2026.
Тариф за 139–200 ₽/мес подходит для лендинга и небольшого блога. Под интернет-магазин или сайт с 1000+ посетителей в сутки берут 2 ядра и 4 ГБ RAM — это диапазон 600–1200 ₽/мес. Подборка тарифов, отобранных именно под сайты, лежит в разделе VPS для сайтов.
Частые ошибки при настройке nginx
Большинство проблем повторяются от сервера к серверу и решаются за минуту, если знать, куда смотреть. Первым делом всегда открывают /var/log/nginx/error.log — там записана точная причина, а не общая формулировка из браузера. Ниже — ошибки, которые встречаются чаще остальных.
- Файл создан в
sites-available, но симлинк вsites-enabledне сделан — сайт отдаёт чужую страницу-заглушку. - Не удалён конфиг
default: он перехватывает запросы к любому домену, у которого нет своего server-блока. - Правки применили через
reloadбез предварительногоnginx -t— сервер остаётся на старом конфиге, а вы ищете ошибку в браузере. - Оставлен лимит
client_max_body_sizeв 1 МБ — загрузка любого фото падает с ошибкой 413. - Каталог сайта недоступен пользователю
www-data— в браузере ошибка 403, в логе строка Permission denied. - Порт 443 закрыт файрволом: сертификат выпущен, а сайт по HTTPS не открывается.
Отдельная категория — ошибка 502 Bad Gateway: nginx работает, но не достучался до бэкенда — программы, которая стоит за ним и готовит ответ. Причины три: не запущен PHP-FPM, неверный путь к сокету или приложение слушает другой порт.
Частые вопросы
Что выбрать новичку — nginx или Apache? Для типового сайта на CMS проще nginx: он экономнее расходует память на статике и держит больше одновременных соединений на том же железе. Apache гибче за счёт файлов .htaccess. Подробное сравнение — в материале nginx или Apache.
Нужно ли перезапускать сервер после каждой правки? Нет. Команда nginx -s reload перечитывает конфигурацию без разрыва открытых соединений — посетители ничего не заметят. Полный restart нужен только при смене портов в listen или после обновления пакета.
Почему после установки открывается страница «Welcome to nginx»? Работает конфиг по умолчанию: в sites-enabled лежит ссылка default. Удалите её, создайте свою и выполните nginx -t с последующим reload. Если страница осталась, проверьте в режиме инкогнито — дело в кэше браузера.
Сколько сайтов можно держать на одном сервере? Ограничение задаёт не nginx, а память под бэкенды: на 2 ГБ RAM живут 3–5 небольших сайтов на PHP, на 4 ГБ — до десяти. Каждому домену делают отдельный файл в sites-available.
Как проверить, что gzip действительно включился? Отправьте запрос командой curl -I -H "Accept-Encoding: gzip" https://example.ru и найдите в ответе строку Content-Encoding: gzip. Если её нет, проверьте, что тип файла перечислен в gzip_types, а размер ответа больше порога gzip_min_length — по умолчанию мы ставим 1024 байта.
Помогает ли nginx против наплыва запросов? Частично: директивы limit_req_zone и limit_conn ограничивают число запросов и соединений с одного адреса и гасят простой перебор. Против объёмной атаки нужна фильтрация на уровне канала — такие тарифы собраны в разделе защита от DDoS для nginx.
Что делать, если nginx -t ругается, а строку я не вижу? Команда печатает полный путь и номер строки, и ошибка часто оказывается в файле, подключённом через include. Чаще всего это пропущенная точка с запятой в конце предыдущей строки или лишняя скобка. Открывайте файл по указанному пути, а не тот, который правили последним.
Итог
Рабочая конфигурация собирается из шести вещей: server-блок с root и index, симлинк в sites-enabled, client_max_body_size вместо дефолтного 1 МБ, gzip пятого уровня, кэш статики на 30 дней и пара блоков под HTTPS с редиректом. Проверка nginx -t перед каждым reload экономит больше времени, чем любая другая привычка.
Для старта хватит тарифа с 1–2 ядрами и 2 ГБ RAM. Сравнить конфигурации, локации и цены 44 провайдеров можно в разделе VPS с nginx — фильтры по памяти, диску и стране включаются в один клик.