Создание виртуального хоста 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.

← Предыдущая статья Установка и базовая настройка Nginx в Ubuntu Следующая статья → Настройка HTTPS в Nginx через Certbot