ServerAID
Найти гайд, команду, тег… ⌘ K
Серверный стек

Установка nginx на Ubuntu 24.04: пакет, виртуальные хосты, HTTPS и PHP

Ставим nginx на Ubuntu, разбираемся в структуре каталогов sites-available/sites-enabled, поднимаем первый виртуальный хост и включаем HTTPS. Отдельно — когда стоит взять свежую версию из репозитория nginx.org вместо архива Ubuntu и как подключить PHP-FPM.

nginx ставится на Ubuntu одной командой, но между «пакет установлен» и «сайт открывается по HTTPS» лежит ещё несколько шагов, которые обычно и вызывают вопросы. Проходим весь путь: установка, структура конфигов, первый виртуальный хост, сертификат и PHP.

Ставим пакет

В архиве Ubuntu 24.04 лежит стабильная версия nginx, собранная с нужным набором модулей и интегрированная с systemd, AppArmor и logrotate. Для большинства задач это правильный выбор — обновления приходят с системными, ничего дополнительно подключать не нужно.

sudo apt update
sudo apt install -y nginx

Сразу после установки сервис запущен и добавлен в автозагрузку:

systemctl is-active nginx     # active
systemctl is-enabled nginx    # enabled
nginx -v                      # версия

Проверяем, что сервер отвечает:

curl -I http://localhost

Ответ HTTP/1.1 200 OK и заголовок Server: nginx/1.24.0 означают, что всё поднялось. В браузере на этом этапе видна дефолтная страница «Welcome to nginx!».

Открываем порты в UFW

Если UFW включён, снаружи сайт не откроется, пока порты не разрешены. Пакет nginx регистрирует готовые профили:

sudo ufw app list

Доступны три:

  • Nginx HTTP — только порт 80;
  • Nginx HTTPS — только 443;
  • Nginx Full — оба.

Пока сертификата нет, достаточно HTTP; после выпуска сертификата профиль меняем на полный:

sudo ufw allow 'Nginx Full'
sudo ufw status

Если nginx работает как контейнер, а не как пакет, помните: Docker публикует порты в обход UFW — механика разобрана в статье про установку Docker.

Разбираемся в структуре конфигов

Конфигурация в Ubuntu разложена по каталогам, и это отличается от сборки с nginx.org, где всё лежит в conf.d.

Путь Что там
/etc/nginx/nginx.conf Главный файл: воркеры, логи, gzip, подключение остальных
/etc/nginx/sites-available/ Конфиги всех сайтов — и включённых, и выключенных
/etc/nginx/sites-enabled/ Симлинки на активные сайты, только они читаются
/etc/nginx/conf.d/ Общие фрагменты конфигурации
/etc/nginx/snippets/ Переиспользуемые куски: параметры SSL, fastcgi
/var/www/html/ Корень дефолтного сайта
/var/log/nginx/ access.log и error.log

Схема с двумя каталогами удобна тем, что сайт отключается без удаления конфига — достаточно снять симлинк из sites-enabled.

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

Создаём каталог под сайт и тестовую страницу:

sudo mkdir -p /var/www/example.com/html
echo '<h1>example.com works</h1>' | sudo tee /var/www/example.com/html/index.html
sudo chown -R www-data:www-data /var/www/example.com

Владельцем делаем www-data — под этим пользователем работают рабочие процессы nginx. Про смену владельца подробно — в статье про chown.

Пишем конфиг /etc/nginx/sites-available/example.com:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;
    root /var/www/example.com/html;
    index index.html;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

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

try_files $uri $uri/ =404 — базовая строка: nginx пробует отдать файл, потом каталог, а если ничего нет, честно возвращает 404 вместо листинга каталога.

Включаем сайт и выключаем дефолтный:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default

Проверяем конфиг перед перезагрузкой

Обязательный шаг, который экономит нервы:

sudo nginx -t

Вывод syntax is ok и test is successful означает, что конфиг синтаксически верен и все указанные файлы существуют. При ошибке nginx покажет файл и номер строки.

Применяем:

sudo systemctl reload nginx

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

Если reload не сработал, а nginx -t проходит, смотрим, что случилось:

sudo systemctl status nginx
sudo journalctl -u nginx -n 30 --no-pager

Включаем HTTPS

Сертификат Let's Encrypt выпускается за одну команду, если домен уже указывает на этот сервер:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Плагин --nginx сам находит нужный server-блок, добавляет директивы listen 443 ssl, пути к сертификату и редирект с HTTP. Обновление сертификата ставится systemd-таймером автоматически, проверить можно так:

systemctl list-timers | grep certbot
sudo certbot renew --dry-run

Подробный разбор выпуска и продления — в статье про Let's Encrypt и certbot на Ubuntu. После выпуска не забудьте открыть 443: sudo ufw allow 'Nginx Full'.

Подключаем PHP-FPM

Для сайтов на PHP nginx сам код не выполняет — он передаёт запрос процессу PHP-FPM через сокет.

sudo apt install -y php-fpm
systemctl is-active php8.3-fpm

Версия в имени сервиса зависит от релиза Ubuntu: в 24.04 это PHP 8.3, в 22.04 — 8.1. Уточнить точное имя сокета:

ls /run/php/

Добавляем в server-блок обработку .php и правим index:

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com/html;
    index index.php index.html;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Проверяем и перезагружаем:

sudo nginx -t && sudo systemctl reload nginx
echo '<?php phpinfo();' | sudo tee /var/www/example.com/html/info.php
curl -s http://localhost/info.php | head -5

Убедившись, что PHP отрабатывает, файл info.php сразу удаляем — он раскрывает версии, пути и настройки сервера:

sudo rm /var/www/example.com/html/info.php

Блок location ~ /\.ht { deny all; } закрывает доступ к .htaccess-файлам, если они остались от переезда с Apache: nginx их не обрабатывает, но и отдавать содержимое наружу не должен.

Когда нужна версия с nginx.org

Пакет из архива Ubuntu заморожен на версии, вышедшей к релизу дистрибутива. Если нужны свежие возможности — новые директивы, поддержка HTTP/3 — подключается официальный репозиторий nginx:

sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl -fsSL https://nginx.org/keys/nginx_signing.key \
  | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg

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 -y nginx

Учтите разницу: сборка с nginx.org не создаёт sites-available/sites-enabled — она подключает только /etc/nginx/conf.d/*.conf. Привычную схему можно воссоздать вручную, добавив в nginx.conf строку include /etc/nginx/sites-enabled/*;.

Для замены nginx на nginx-extras (дополнительные модули из архива Ubuntu) отдельный репозиторий не нужен — пакет есть в стандартном.

Диагностика: что смотреть при ошибках

sudo tail -f /var/log/nginx/error.log       # ошибки в реальном времени
sudo tail -f /var/log/nginx/access.log      # входящие запросы
sudo ss -tulpn | grep nginx                 # какие порты слушает
sudo nginx -T | less                        # итоговый конфиг целиком

nginx -T (заглавная T) выводит собранную конфигурацию со всеми include — удобно, когда непонятно, откуда прилетела директива.

Типичные ошибки в error.log:

  • bind() to 0.0.0.0:80 failed (98: Address already in use) — порт занят другим сервисом, чаще всего Apache. Проверить: sudo ss -tulpn | grep :80;
  • Permission denied при доступе к файлам сайта — права или владелец каталога, лечится chown -R www-data:www-data;
  • upstream timed out — приложение за проксёй не отвечает, смотреть надо его логи, а не nginx.

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

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

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

restart останавливает сервис целиком и поднимает заново — это короткий, но реальный даунтайм. На проде используйте reload, а restart только при изменении systemd-юнита или параметров запуска.

Где лежат конфиги nginx в Ubuntu?

Главный файл — /etc/nginx/nginx.conf. Конфиги сайтов — в /etc/nginx/sites-available/, а активны только те, на которые есть симлинк в /etc/nginx/sites-enabled/.

Логи по умолчанию пишутся в /var/log/nginx/access.log и error.log. Корень дефолтного сайта — /var/www/html.

Почему после установки открывается страница «Welcome to nginx»?

Это дефолтный сайт из /etc/nginx/sites-enabled/default. Он ловит все запросы, для которых не нашлось подходящего server_name.

После создания своего виртуального хоста дефолтный симлинк удаляют: sudo rm /etc/nginx/sites-enabled/default. Сам конфиг остаётся в sites-available и при необходимости включается обратно.

Как проверить конфиг nginx перед применением?

Командой sudo nginx -t. Она проверяет синтаксис и существование файлов, на которые ссылается конфиг, и печатает точное место ошибки.

Полезная привычка — объединять проверку и применение в одну строку: sudo nginx -t && sudo systemctl reload nginx. При ошибке конфигурация просто не применится, и работающий сайт не сломается.

Нужен ли Apache, если стоит nginx?

Нет, это взаимозаменяемые веб-серверы, и одновременно они за порт 80 не уживутся. Если Apache приехал зависимостью и не нужен, снимите его: sudo apt purge apache2.

Связка «nginx впереди, Apache сзади» встречается на легаси-хостингах, но для нового проекта проще nginx + PHP-FPM.

Что запомнить

  • sudo apt install nginx даёт стабильную версию, интегрированную с systemd, AppArmor и logrotate — этого хватает большинству проектов.
  • Сайты живут в sites-available, активируются симлинком в sites-enabled; отключение — снятие симлинка, а не удаление конфига.
  • Перед каждым применением — nginx -t, применять через reload, а не restart.
  • UFW-профиль Nginx Full открывает 80 и 443; до выпуска сертификата достаточно Nginx HTTP.
  • PHP выполняет не nginx, а PHP-FPM: запросы к .php передаются в сокет /run/php/phpX.Y-fpm.sock.

Похожие материалы

Серверный стек

Установка Nextcloud на Ubuntu Server: nginx, PostgreSQL и HTTPS

Поднимаем своё облако на Ubuntu Server 24.04: nginx с PHP-FPM, база в PostgreSQL, сертификат Let's Encrypt и права на каталог данных. Разбираем полный конфиг nginx под Nextcloud, обязательный cron для фоновых задач и настройки, без которых установка ругается на предупреждения безопасности.

Редакция
Серверный стек

Установка PostgreSQL на Ubuntu 24.04: кластер, роли, pg_hba.conf и доступ по сети

Ставим PostgreSQL из архива Ubuntu или из репозитория PGDG, создаём базу и пользователя, разбираемся с методами аутентификации в pg_hba.conf и аккуратно открываем доступ по сети. Плюс бэкап через pg_dump и типовые ошибки подключения.

Редакция
Серверный стек

Установка Docker на Ubuntu 24.04: официальный репозиторий, проверка, настройка

Ставим Docker Engine из официального репозитория Docker, а не из архива Ubuntu — там пакет отстаёт на месяцы и не содержит compose-плагина. Разбираем полную последовательность: ключ, репозиторий, установка, запуск без sudo, ограничение размера логов и главную ловушку Ubuntu — Docker публикует порты в обход UFW.

Редакция
Серверный стек на Ubuntu: nginx, БД, Docker
Серверный стек

Серверный стек на Ubuntu: nginx, БД, Docker

Этот раздел про инфраструктуру, на которой живёт типичное веб-приложение: фронт-прокси, база данных, контейнеры, кэш. Здесь карта стека и порядок, в котором его обычно поднимают на Ubuntu Server.

Михаил Орлов