LinuxRuLinux без лишней теории
Веб-сервер

Установка и настройка nginx на Ubuntu и Debian: от первого сайта до reverse proxy

Редакция LinuxRu8 мин чтенияИнструкции

Установка nginx на Ubuntu и Debian занимает одну команду: sudo apt install nginx, после чего служба сразу работает на 80 порту. Дальше вы создаёте server-блок в sites-available, включаете его ссылкой в sites-enabled и проверяете конфиг через nginx -t. Ниже готовые конфиги для статического сайта и reverse proxy, а также разбор ошибок 502 и 403 по строкам error.log.

Установка и настройка nginx на Ubuntu и Debian: от первого сайта до reverse proxy
Фото: NOIRLab/NSF/AURA/T. Slovinský, CC BY 4.0, Wikimedia Commons
Содержание
  1. Установка
  2. Где конфиги
  3. Статический сайт
  4. Несколько сайтов
  5. Reverse proxy
  6. Логи
  7. 502 и 403
  8. HTTPS и защита
  9. Частые вопросы

Установка nginx на Ubuntu, Debian и других дистрибутивах

В Ubuntu 26.04 LTS и Debian 13 nginx есть в основном репозитории, отдельный PPA не нужен. Пакет из дистрибутива получает исправления безопасности вместе с системой, поэтому для большинства серверов это лучший выбор.

sudo apt update
sudo apt install nginx
nginx -v
systemctl status nginx

После установки служба уже запущена и добавлена в автозагрузку. Откройте в браузере IP сервера: должна появиться страница "Welcome to nginx". Если страница не открывается, а systemctl status показывает active, почти наверняка порт закрыт файрволом. В Ubuntu с UFW достаточно одной команды, подробнее в статье про настройку UFW:

sudo ufw allow 'Nginx Full'
sudo ufw status

На октябрь 2026 года на nginx.org стабильная ветка 1.30.x и mainline 1.31.x, в Debian 13 стоит 1.26.3 с бэкпортами исправлений. Для сайта и reverse proxy этого хватает.

ДистрибутивУстановкаГде лежат сайтыПользователь
Ubuntu 26.04, Debian 13sudo apt install nginxsites-available и sites-enabledwww-data
Fedora 44sudo dnf install nginx/etc/nginx/conf.d/*.confnginx
Arch Linuxsudo pacman -S nginx или nginx-mainlineвсё в nginx.conf, include добавляете самиhttp
Репозиторий nginx.orgapt или dnf после подключения репозитория/etc/nginx/conf.d/*.confnginx

В Fedora и Arch служба после установки не запускается сама:

sudo systemctl enable --now nginx
# Fedora: открыть HTTP и HTTPS в firewalld
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload

Официальный репозиторий nginx.org

Если нужна свежая стабильная ветка на Ubuntu, подключите репозиторий разработчиков. Команды взяты из инструкции на nginx.org, для mainline замените в адресе packages/ubuntu на packages/mainline/ubuntu:

sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx

Учтите, что пакет с nginx.org не создаёт каталоги sites-available и sites-enabled и работает от пользователя nginx. Инструкции, написанные под пакет Ubuntu, придётся адаптировать под /etc/nginx/conf.d/.

Как устроены конфиги и что делать после каждой правки

Главный файл /etc/nginx/nginx.conf задаёт общие настройки: число воркеров, формат логов, gzip. Сайты описываются отдельными блоками server, которые подключаются через include. В Debian и Ubuntu схема такая: файл сайта лежит в sites-available, а включается символической ссылкой в sites-enabled. Выключить сайт значит удалить ссылку, сам конфиг остаётся.

  • /etc/nginx/nginx.conf - глобальные параметры и блок http;
  • /etc/nginx/sites-available/ - конфиги сайтов (Debian, Ubuntu);
  • /etc/nginx/conf.d/ - фрагменты, которые подключаются автоматически;
  • /var/log/nginx/ - access.log и error.log.

После любой правки сначала проверка синтаксиса, потом мягкая перезагрузка. Команда reload перечитывает конфиг без обрыва текущих соединений, а если в конфиге ошибка, старые воркеры продолжают работать.

sudo nginx -t
sudo systemctl reload nginx
# полный итоговый конфиг со всеми include, удобно для поиска дублей
sudo nginx -T | less

Про состояние службы и автозапуск подробно написано в статье о systemctl.

Первый server-блок: статический сайт за пять минут

Возьмём домен example.ru, который уже указывает A-записью на IP сервера. Создаём каталог, кладём тестовую страницу и отдаём права пользователю, от которого работает nginx:

sudo mkdir -p /var/www/example.ru/html
echo '<h1>example.ru работает</h1>' | sudo tee /var/www/example.ru/html/index.html
sudo chown -R www-data:www-data /var/www/example.ru

Файл /etc/nginx/sites-available/example.ru:

server {
    listen 80;
    listen [::]:80;
    server_name example.ru www.example.ru;

    root /var/www/example.ru/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    access_log /var/log/nginx/example.ru.access.log;
    error_log  /var/log/nginx/example.ru.error.log;
}

Включаем сайт и убираем стандартную заглушку, чтобы она не перехватывала запросы:

sudo ln -s /etc/nginx/sites-available/example.ru /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx

Проверить сайт можно ещё до того, как DNS обновится, подставив заголовок Host вручную:

curl -I -H 'Host: example.ru' http://127.0.0.1/

Для одностраничных приложений на React или Vue последний аргумент try_files меняют на /index.html, чтобы маршруты фронтенда не давали 404.

Несколько доменов на одном IP и сервер по умолчанию

nginx выбирает server-блок по заголовку Host. Если ни один server_name не совпал, запрос уходит серверу по умолчанию: блоку с default_server или, если такого нет, первому подключённому. Отсюда частая жалоба "открываю один домен, а показывается другой сайт".

Явный сервер по умолчанию, который закрывает соединение для неизвестных имён и прямых заходов по IP:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444;
}

Каждый следующий сайт делается так же: свой файл в sites-available, свой root и свой server_name.

Nginx reverse proxy: приложение на порту за доменом

Типичная задача: приложение на Node.js, Python или в Docker слушает 127.0.0.1:3000, а наружу нужно отдать его по домену на 80 и 443 порту. nginx принимает запрос и передаёт его дальше через proxy_pass.

server {
    listen 80;
    server_name app.example.ru;

    client_max_body_size 50m;

    location / {
        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;

        # WebSocket: чаты, панели, Home Assistant, code-server
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_read_timeout 120s;
    }
}

Заголовки X-Forwarded-* передают бэкенду настоящий IP клиента и схему HTTPS. Без них некоторые панели уходят в бесконечный редирект.

Слеш в конце proxy_pass

Самая частая ловушка при проксировании подпути. Сравните два варианта для location /api/:

  • proxy_pass http://127.0.0.1:3000; - запрос /api/users уйдёт на бэкенд как /api/users;
  • proxy_pass http://127.0.0.1:3000/; - префикс /api/ отрезается, бэкенд получит /users.

Если приложение запущено в контейнере, публикуйте порт только на localhost (127.0.0.1:3000:3000 в compose), иначе Docker откроет его наружу в обход файрвола. Как ставить сам Docker, описано в статье про установку Docker.

Логи nginx: где смотреть причину ошибки

Код ответа виден в access.log, а объяснение почти всегда лежит в error.log. Держите оба открытыми, когда воспроизводите проблему:

sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log
# ошибки запуска самой службы
sudo journalctl -u nginx -b --no-pager | tail -50

Если информации мало, временно поднимите уровень для одного сайта: error_log /var/log/nginx/example.ru.error.log info;. Уровень debug работает, только если nginx собран с отладкой, и пишет очень много, на боевом сервере его не держат.

Ошибки 502, 504, 403 и 413: причины и исправление

502 Bad Gateway

nginx не смог получить ответ от бэкенда. В error.log ищите строку с upstream:

  • connect() failed (111: Connection refused) - приложение не запущено или слушает другой порт. Проверьте ss -tlnp | grep 3000, команды разобраны в статье про открытые порты;
  • connect() to unix:/run/php/php8.4-fpm.sock failed (2: No such file or directory) - неверный путь к сокету PHP-FPM, версия PHP в конфиге не совпадает с установленной;
  • (13: Permission denied) while connecting to upstream на Fedora - это SELinux запрещает nginx исходящие соединения. Лечится командой sudo setsebool -P httpd_can_network_connect 1;

504 Gateway Timeout

Бэкенд не ответил за 60 секунд. Для долгих выгрузок увеличьте proxy_read_timeout в нужном location.

403 Forbidden

  • directory index of "/var/www/site/" is forbidden - в каталоге нет index.html, а листинг выключен. Положите индексный файл или проверьте директиву index;
  • open() "..." failed (13: Permission denied) - пользователь www-data не может дойти до файла. Права нужны не только на файл, но и на каждый каталог по пути. Посмотреть всю цепочку разом: namei -l /var/www/site/html/index.html. Частый случай: сайт лежит в /home/user, у которого права 700. Основы в статье про chmod и chown;
  • на Fedora файлы в нестандартном каталоге не имеют метки SELinux: sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?", затем sudo restorecon -Rv /srv/www.

413 Request Entity Too Large

Загружаемый файл больше лимита, по умолчанию это 1 МБ. Добавьте client_max_body_size 50m; в server или location и перезагрузите конфиг.

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

Сообщение bind() to 0.0.0.0:80 failed (98: Address already in use) значит, что порт занят, чаще всего Apache. Узнайте, кто держит порт: sudo ss -tlnp | grep ':80 ', и остановите лишнюю службу.

HTTPS и минимальная защита сервера

Следующий шаг после рабочего server-блока - бесплатный сертификат. Certbot сам найдёт блок по server_name, получит сертификат и добавит редирект с HTTP. Пошагово это разобрано в статье про Certbot и Let's Encrypt, а короткий путь на Ubuntu выглядит так:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.ru -d www.example.ru

Несколько строк, которые стоит добавить в блок http файла nginx.conf сразу:

server_tokens off;          # не показывать версию nginx в ошибках и заголовках
client_max_body_size 20m;   # разумный лимит загрузки
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;

Порт приложения за прокси снаружи закрывайте: слушать он должен только 127.0.0.1. Файрвол оставляет открытыми 22, 80 и 443. Админку ограничьте по IP директивами allow и deny all.

Привычка, которая экономит часы: перед правкой копируйте файл сайта рядом, например sudo cp example.ru example.ru.bak в sites-available, а не в sites-enabled. Копия в sites-enabled будет подключена как второй сайт с тем же server_name, и nginx выдаст предупреждение conflicting server name.

Значения по умолчанию для каждой директивы есть в документации nginx на русском.

Частые вопросы

Чем reload отличается от restart в nginx?

reload перечитывает конфигурацию без обрыва соединений, а при ошибке в конфиге старая версия продолжает работать. restart останавливает и запускает службу заново, это нужно редко.

Почему вместо моего сайта открывается другой?

Запрос не совпал ни с одним server_name и ушёл серверу по умолчанию. Проверьте написание домена, наличие ссылки в sites-enabled и задайте явный блок с default_server.

Где в Fedora каталог sites-available?

Его нет. В Fedora и в пакете с nginx.org сайты кладут в /etc/nginx/conf.d/ файлами с расширением .conf, они подключаются автоматически.

Что делать, если nginx пишет 502 Bad Gateway?

Откройте error.log и найдите строку с upstream. Чаще всего бэкенд не запущен или слушает другой порт, на Fedora причиной бывает SELinux, который включается командой setsebool -P httpd_can_network_connect 1.

Можно ли поставить nginx рядом с Apache?

Да, но только на разных портах. Обычно nginx слушает 80 и 443 и проксирует запросы на Apache, который переводят на 8080.

Документация и источники

Читайте также

Команды проверены на актуальных версиях дистрибутивов на момент обновления. Перед изменением системных настроек сделайте резервную копию.