Чтобы разместить сайт на VPS, нужны три вещи: веб-сервер, который отдает файлы сайта, домен, указывающий на IP вашего сервера, и HTTPS-сертификат. Nginx справляется с первыми двумя задачами легко, а сертификат Let’s Encrypt выдается бесплатно через certbot. В этой инструкции сайт работает на Ubuntu 24.04 или Debian 12, а HTTPS настраивается автоматически с продлением. Домен должен уже указывать на сервер: как это сделать, описано в статье как привязать домен к VPS.

Что понадобится

  • VPS с публичным IPv4 или IPv6 и доступом по SSH. Подключение описано в статье как подключиться к VPS по SSH.
  • Домен, например example.com, с записями A или AAAA, которые ведут на ваш сервер.
  • Файлы сайта: готовая статика HTML, CSS и JavaScript или собранный фронтенд.

Шаг 1. Установка Nginx

Обновите список пакетов и установите Nginx. Пакет запускается сразу и слушает порт 80.

sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx
sudo systemctl enable --now nginx
systemctl status nginx --no-pager

Откройте в браузере IP-адрес сервера. Если видна стандартная страница Nginx, веб-сервер работает. Пока что сайт по домену недоступен, потому что каталог с вашими файлами еще не создан.

Шаг 2. Каталог сайта и права

Файлы сайта лучше держать вне системных каталогов, например в /var/www/example.com/html. Создайте каталог, скопируйте в него файлы и назначьте владельца, с которым работает Nginx.

sudo mkdir -p /var/www/example.com/html
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
echo 'Сайт работает' | sudo tee /var/www/example.com/html/index.html

Пользователь www-data читает файлы, а менять их может только владелец. Если вы загружаете сайт через SFTP под своим пользователем, загружайте файлы в каталог, владельцем которого будет тот же www-data, либо оставьте доступ через отдельную группу.

Если сайт представляет собой приложение на Python, Node.js или Go, Nginx обычно работает как обратный прокси. Он принимает запросы на порты 80 и 443 и передает их приложению, которое слушает локальный порт, через директиву proxy_pass. Для обычного статического сайта каталог с файлами проще и надежнее, поэтому в этой инструкции используется именно он.

Шаг 3. Server block для домена

Server block описывает, какой домен обслуживает какой каталог. Создайте конфигурацию в /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;
    }
}

Включите сайт символической ссылкой в sites-enabled, проверьте синтаксис и перезагрузите Nginx. Команда nginx -t обязательна перед перезагрузкой: если в файле ошибка, она покажет строку, и Nginx продолжит работать со старой конфигурацией.

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

Теперь откройте http://example.com в браузере. Если появилась страница из index.html, сайт работает по HTTP. Следующий шаг добавит HTTPS.

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

Шаг 4. Файрвол: порты 80 и 443

Let’s Encrypt проверяет владение доменом через порт 80, а посетители сайта подключаются по порту 443 для HTTPS. Если на сервере включен ufw, откройте оба порта. Сначала разрешите SSH, иначе после включения файрвола вы потеряете доступ к серверу.

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status

Профиль Nginx Full открывает 80 и 443. Если вы используете файрвол в панели управления провайдера, откройте эти же порты там: правила панели работают независимо от ufw, и порт должен быть открыт в обоих местах. Для сайта без HTTPS можно оставить только порт 80, но так делать не стоит.

Шаг 5. SSL-сертификат Let’s Encrypt

Установите certbot и плагин для Nginx. Плагин сам меняет конфигурацию: добавляет слушающий порт 443, пути к сертификату и перенаправление с HTTP на HTTPS.

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

Certbot спросит адрес электронной почты для уведомлений об истечении сертификата и предложит согласиться с условиями. На вопрос о перенаправлении HTTP на HTTPS выберите вариант с перенаправлением. Перед выпуском убедитесь, что домен example.com и www.example.com уже указывают на IP сервера, иначе проверка не пройдет.

Certbot сохраняет резервные копии изменяемых конфигураций и хранит сертификаты в каталоге /etc/letsencrypt/live/example.com. Эти файлы не нужно копировать вручную: certbot сам знает, где их искать при продлении.

Если вы только пробуете процедуру, добавьте флаг --staging. Тестовый сервер Let’s Encrypt не выдает доверенных сертификатов, зато не расходует боевые лимиты на выпуск.

Шаг 6. Автообновление сертификата

Сертификаты Let’s Encrypt действуют ограниченное время. Пакет certbot устанавливает systemd-таймер, который проверяет их и продлевает за несколько недель до окончания срока. Убедитесь, что таймер активен, и проверьте продление без реального обращения к серверу.

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

Если тестовое продление прошло без ошибок, сервер будет обновлять сертификат сам. После продления Nginx нужно перезагрузить, поэтому плагин certbot делает это автоматически. Проверить дату окончания можно командой sudo certbot certificates.

Почему это важно: браузеры помечают сайты без HTTPS как небезопасные, а поисковые системы учитывают шифрование как часть качества сайта. После установки сертификата откройте адрес в браузере и убедитесь, что отображается замок, а http-адрес перенаправляется на https.

Частые проблемы

  • Certbot не проходит проверку домена. Проверьте A или AAAA запись командой dig +short example.com и убедитесь, что порт 80 открыт.
  • Nginx не перезагружается после правок. Выполните sudo nginx -t и исправьте строку, которую он покажет.
  • Страница по домену открывается, а по IP нет, или наоборот. Проверьте server_name и то, какой server block стоит первым в sites-enabled.
  • Сайт открывается со старыми файлами. Очистите кэш браузера и убедитесь, что вы загрузили файлы в правильный каталог root.

Перед любыми правками копируйте конфигурацию, например командой sudo cp /etc/nginx/sites-available/example.com /root/example.com.bak. Тогда при ошибке можно вернуть рабочий вариант за минуту, даже если certbot уже изменил файл.

Итоги

Сайт на VPS состоит из Nginx, каталога с файлами, server block для домена и сертификата Let’s Encrypt. Certbot выпускает сертификат и настраивает HTTPS, а таймер systemd продлевает его без вашего участия. Для проекта с несколькими сервисами или базой данных удобнее упаковать окружение в контейнеры: см. статью Docker на VPS. Если вы выбираете сервер под сайт, полезно сначала прочитать как выбрать VPS, а затем сравнить тарифы в разделе VPS. Для статического сайта обновление сводится к загрузке новых файлов в каталог root: Nginx отдает их сразу, перезапуск не нужен. Регулярно копируйте каталог сайта и конфигурацию, чтобы восстановить работу после ошибки.