Установка 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.