Создание виртуального хоста Nginx для отдельного домена
Пошаговая настройка отдельного server block в Nginx для собственного домена: каталог сайта, права, DNS, конфигурация и проверка.
Виртуальный хост Nginx, или server block, позволяет обслуживать отдельный сайт по собственному доменному имени.
В этой инструкции рассматривается только создание одного виртуального хоста для домена, подготовка каталога сайта, настройка DNS и проверка HTTP-доступа.
Проверено на: Ubuntu Server 24.04 LTS
Уровень сложности: начальный
Время выполнения: около 15 минут
Требуемый доступ: пользователь с правамиsudo
Что будет настроено
После выполнения инструкции:
- будет создан отдельный каталог сайта;
- будет создан тестовый
index.html; - будет создан отдельный server block;
- конфигурация будет включена через
sites-enabled; - будет проверена DNS-запись;
- будет выполнена проверка через
curl; - стандартный сайт Nginx будет отключён при необходимости.
Что потребуется
Подготовьте:
Домен: example.com
IP сервера: SERVER_IP
Используйте собственный домен и реальный IP сервера.
Также должен быть установлен и запущен Nginx.
Проверка:
systemctl status nginx --no-pager
Проверка DNS-записи
Для домена должна существовать A-запись:
example.com → SERVER_IP
При использовании IPv6 дополнительно создаётся AAAA-запись.
Проверьте DNS:
dig +short example.com
Если dig отсутствует:
sudo apt update
sudo apt install -y dnsutils
Проверьте через системный resolver:
getent hosts example.com
Ожидается IP сервера.
Проверка доступности сервера
С другой машины:
ping -c 3 SERVER_IP
Проверьте HTTP-порт:
curl -I http://SERVER_IP
Если сервер недоступен, сначала проверьте firewall, NAT и маршрутизацию.
Создание каталога сайта
Создайте отдельный каталог:
sudo mkdir -p /var/www/example.com/html
Проверьте:
ls -ld /var/www/example.com/html
Назначение владельца
Для ручного управления статическими файлами можно назначить владельцем административного пользователя:
sudo chown -R ADMIN_USER:ADMIN_USER /var/www/example.com
Замените:
ADMIN_USER
на имя своего пользователя.
Проверьте:
ls -ld /var/www/example.com
ls -ld /var/www/example.com/html
Настройка прав
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;
Для каталогов обычно используются права:
755
Для файлов:
644
Не назначайте права 777.
Создание тестовой страницы
cat >/var/www/example.com/html/index.html <<'EOF'
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>example.com</title>
</head>
<body>
<h1>example.com работает</h1>
<p>Виртуальный хост Nginx настроен успешно.</p>
</body>
</html>
EOF
Проверьте:
cat /var/www/example.com/html/index.html
Создание server block
Создайте файл:
sudo nano /etc/nginx/sites-available/example.com
Добавьте:
server {
listen 80;
listen [::]:80;
server_name 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;
}
}
Разбор конфигурации
listen
listen 80;
listen [::]:80;
Nginx принимает HTTP-запросы по IPv4 и IPv6.
server_name
server_name example.com;
Определяет доменное имя этого виртуального хоста.
root
root /var/www/example.com/html;
Указывает каталог файлов сайта.
index
index index.html;
Определяет стартовый файл.
try_files
try_files $uri $uri/ =404;
Nginx ищет запрошенный файл или каталог и возвращает 404, если объект не найден.
Поддержка www
Если сайт должен открываться также по адресу:
www.example.com
добавьте DNS-запись:
www.example.com → SERVER_IP
И измените:
server_name example.com www.example.com;
Перенаправление www на основной домен лучше настраивать в отдельной статье.
Включение виртуального хоста
Создайте символическую ссылку:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
Проверьте:
ls -l /etc/nginx/sites-enabled/
Защита от повторного создания ссылки
Если ссылка уже существует, команда завершится ошибкой.
Проверка:
test -L /etc/nginx/sites-enabled/example.com && echo "Сайт уже включён" || echo "Ссылка отсутствует"
Проверка конфигурации
sudo nginx -t
Ожидаемый результат:
syntax is ok
test is successful
До успешной проверки не выполняйте reload.
Применение конфигурации
sudo systemctl reload nginx
Проверьте:
systemctl status nginx --no-pager
Проверка до обновления DNS
Даже если DNS ещё не распространился, виртуальный хост можно проверить через заголовок Host.
curl -I -H 'Host: example.com' http://127.0.0.1
Проверка содержимого:
curl -H 'Host: example.com' http://127.0.0.1
Должен вернуться созданный index.html.
Проверка через resolve
Можно принудительно связать домен с IP:
curl -I --resolve example.com:80:SERVER_IP http://example.com
Такой тест не зависит от текущего DNS-кэша.
Проверка после обновления DNS
curl -I http://example.com
Ожидаемый ответ:
HTTP/1.1 200 OK
Server: nginx
Проверка страницы:
curl http://example.com
Проверка в браузере
Откройте:
http://example.com
Должна отобразиться тестовая страница.
Если браузер показывает другой сайт, проверьте DNS и активные server block.
Отключение стандартного сайта
Стандартная конфигурация может перехватывать запросы по IP или неизвестному Host.
Проверьте:
ls -l /etc/nginx/sites-enabled/default
Отключите:
sudo rm -f /etc/nginx/sites-enabled/default
Проверьте конфигурацию:
sudo nginx -t
Примените:
sudo systemctl reload nginx
Файл в sites-available при этом сохраняется.
Проверка активных server block
sudo nginx -T |
grep -nE 'server_name|root |listen '
Проверка конкретного домена:
sudo nginx -T |
grep -n 'example.com'
Проверка журнала доступа
sudo tail -50 /var/log/nginx/example.com.access.log
Создайте запрос:
curl http://example.com >/dev/null
Повторно:
sudo tail -5 /var/log/nginx/example.com.access.log
Проверка журнала ошибок
sudo tail -50 /var/log/nginx/example.com.error.log
Наблюдение в реальном времени:
sudo tail -f /var/log/nginx/example.com.error.log
Остановить:
Ctrl+C
Добавление дополнительной страницы
Создайте:
cat >/var/www/example.com/html/about.html <<'EOF'
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>О сайте</title>
</head>
<body>
<h1>О сайте</h1>
</body>
</html>
EOF
Проверьте:
curl http://example.com/about.html
Проверка 404
curl -I http://example.com/missing-page
Ожидается:
HTTP/1.1 404 Not Found
Изменение каталога сайта
Если требуется другой путь, измените:
root /srv/www/example.com;
Создайте каталог и перенесите файлы.
После изменения:
sudo nginx -t &&
sudo systemctl reload nginx
Несколько доменов на одном сервере
Для каждого домена создаётся отдельный файл:
/etc/nginx/sites-available/example.com
/etc/nginx/sites-available/example.net
И отдельный каталог:
/var/www/example.com/html
/var/www/example.net/html
В каждом server block должен быть собственный server_name.
Не используйте один root для независимых сайтов
Плохой вариант:
root /var/www/html;
для всех доменов.
Отдельные каталоги упрощают:
- управление;
- права;
- резервное копирование;
- журналы;
- удаление сайта;
- диагностику.
Типичные проблемы
Открывается стандартная страница Nginx
Проверьте:
sudo nginx -T |
grep -nE 'default_server|server_name|root '
Отключите стандартный сайт при необходимости.
Домен открывает другой сайт
Проверьте:
- DNS;
server_name;- дублирующиеся конфигурации;
- порядок включённых сайтов;
- заголовок Host.
Команда:
curl -v http://example.com
403 Forbidden
Проверьте каталог и права:
namei -l /var/www/example.com/html/index.html
Проверьте журнал:
sudo tail -50 /var/log/nginx/example.com.error.log
404 Not Found
Проверьте:
ls -l /var/www/example.com/html/
Проверьте root и index.
DNS возвращает старый IP
Проверьте:
dig example.com
Проверьте authoritative DNS:
dig +trace example.com
Дождитесь окончания TTL старой записи.
nginx -t сообщает conflicting server name
Найдите дубликаты:
sudo grep -Rni 'server_name.*example.com' /etc/nginx/
Оставьте домен только в нужном server block.
Конфигурация создана, но не применяется
Проверьте символическую ссылку:
ls -l /etc/nginx/sites-enabled/
Проверьте:
sudo nginx -T |
grep -n 'example.com'
Отключение сайта
Удалите символическую ссылку:
sudo rm -f /etc/nginx/sites-enabled/example.com
Проверьте:
sudo nginx -t
Примените:
sudo systemctl reload nginx
Файлы сайта и конфигурация в sites-available сохранятся.
Полное удаление виртуального хоста
Сначала отключите сайт.
Удалите конфигурацию:
sudo rm -f /etc/nginx/sites-available/example.com
Удалите каталог только после резервного копирования:
sudo rm -rf /var/www/example.com
Проверьте:
sudo nginx -t &&
sudo systemctl reload nginx
Быстрый набор команд
Создать каталог:
sudo mkdir -p /var/www/example.com/html
Создать конфигурацию:
/etc/nginx/sites-available/example.com
Включить:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
Проверить:
sudo nginx -t
Применить:
sudo systemctl reload nginx
Тестировать:
curl -I -H 'Host: example.com' http://127.0.0.1
Итог
После выполнения инструкции:
- создан отдельный каталог сайта;
- подготовлена тестовая страница;
- создан server block;
- сайт включён через
sites-enabled; - проверена DNS-запись;
- проверен HTTP-ответ;
- настроены отдельные журналы;
- рассмотрено отключение стандартного сайта.
Следующим отдельным этапом можно настроить HTTPS для этого домена через Certbot.