Как развернуть сайт на VPS
Пошаговый путь для Ubuntu LTS от пользователя и SSH-ключа до Caddy с HTTPS, запуска через pm2, логов, обновлений и бэкапов.
Содержание10
Коротко
- Команды рассчитаны на свежий сервер с Ubuntu LTS (например, 24.04 или 26.04). Перед каждой командой поймите, что она делает.
- Порядок: отдельный пользователь с SSH-ключом, файрвол, Node.js, сборка, запуск через pm2, Caddy с HTTPS.
- Приложение слушает только
127.0.0.1, наружу смотрит Caddy. - A-записи для домена и
wwwна IP сервера создайте заранее. - Сразу продумайте обновления и бэкапы.
Что понадобится
VPS с Ubuntu LTS, его IP (ниже 203.0.113.10), домен (ниже example.com) и SSH-клиент. Создайте в самом начале A-запись для @ на IP сервера и запись для www (A на тот же IP или CNAME на example.com). Пока идёт настройка, DNS успеет обновиться. Подробности в статье как привязать домен к хостингу.
1. Пользователь и SSH-ключ
# на своём компьютере
ssh [email protected]
# на сервере под root
apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deploy
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
Последняя команда копирует ключ, добавленный при создании сервера. Если ключа нет, создайте его на своём компьютере (ssh-keygen -t ed25519) и добавьте через ssh-copy-id [email protected] (в Windows эта команда есть в Git Bash и WSL) либо вставьте содержимое файла id_ed25519.pub в ~/.ssh/authorized_keys пользователя deploy.
Во втором окне проверьте вход ssh [email protected] и выполните sudo whoami. Рабочую сессию не закрывайте, пока не убедитесь, что вход по ключу работает.
Только после этого в /etc/ssh/sshd_config задайте PermitRootLogin no и PasswordAuthentication no и выполните sudo systemctl restart ssh. Проверьте итог: sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication'. Если где-то всё ещё yes, ищите переопределения в /etc/ssh/sshd_config.d/.
2. Файрвол
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Правило для SSH добавляйте до включения, иначе потеряете доступ. Если у провайдера есть собственный файрвол, откройте там те же порты.
3. Node.js
Пакет nodejs из репозитория Ubuntu часто отстаёт от актуальной LTS. Откройте https://nodejs.org/en/download, выберите Linux и версию с пометкой LTS и выполните команды со страницы (для Linux там обычно предлагается nvm). Команды вида curl ... | bash запускают код из интернета, поэтому берите их только со страниц разработчиков. После установки откройте новую SSH-сессию и проверьте node -v.
4. Приложение
git clone https://github.com/<user>/<repo>.git mysite
cd mysite
npm ci
npm run build
Для приватного репозитория используйте deploy key только на чтение, а не личный ключ. Секреты храните в переменных окружения или в файле с правами chmod 600, но не в git. На серверах с 1 ГБ памяти и меньше сборка может упасть: соберите проект у себя и загрузите результат или добавьте swap.
5. Запуск через pm2
npm install -g pm2
NITRO_HOST=127.0.0.1 NITRO_PORT=3000 pm2 start .output/server/index.mjs --name mysite
pm2 startup
pm2 save
Так запускается Nuxt, а другие приложения стартуют по-своему. Главное, чтобы приложение слушало 127.0.0.1 и известный порт. Команду, которую напечатает pm2 startup (она уже начинается с sudo), скопируйте и выполните: тогда сайт поднимется после перезагрузки. Вместо pm2 можно использовать службу systemd, пример в статье как запустить Telegram бота на сервере.
6. Caddy и HTTPS
Установите Caddy из официального репозитория. Команды ниже взяты со страницы https://caddyserver.com/docs/install (раздел Debian, Ubuntu), при расхождениях верьте ей:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Затем откройте файл от имени администратора (sudo nano /etc/caddy/Caddyfile), замените содержимое и перезагрузите службу:
example.com, www.example.com {
reverse_proxy 127.0.0.1:3000
}
sudo systemctl reload caddy
Caddy сам получит сертификат и включит редирект на HTTPS, если A-запись уже ведёт на сервер, а порты 80 и 443 открыты. Вместо Caddy можно взять nginx с proxy_pass http://127.0.0.1:3000; и выпустить сертификат через certbot, см. SSL сертификат и HTTPS.
7. Логи, обновления и бэкапы
- Логи:
pm2 logs mysiteиsudo journalctl -u caddy -n 50. - Обновления: примерно раз в месяц выполняйте
sudo apt update && sudo apt upgrade. Если появился файл/var/run/reboot-required, перезагрузите сервер. Проверьте, что включены автоматические обновления безопасности (пакетunattended-upgrades). - Бэкапы: снимки у провайдера, дамп базы данных и копия
.envв надёжном месте, не только на этом сервере. Проверяйте, что восстановление работает.
Если не получилось
Permission deniedпри входе по SSH: неверный пользователь или ключ не скопирован. Проверьте~/.ssh/authorized_keysуdeploy.- Сайт не открывается: на сервере проверьте
sudo ufw status,pm2 statusиcurl -I http://127.0.0.1:3000. - Caddy не выпускает сертификат: A-запись ведёт не на этот сервер или закрыты порты 80 и 443 (в ufw либо у провайдера). Причина видна в
sudo journalctl -u caddy. - Ошибка 502: приложение не запущено или слушает другой порт.
- Сборка падает с
JavaScript heap out of memoryили процесс убивается: не хватает памяти, см. шаг 4. - После перезагрузки сайт не поднялся: вы не выполнили
pm2 startupиpm2 save.
Если что-то непонятно, напишите мне в Telegram: @lztcoder
Читайте также
Как выбрать хостинг для сайта или бота
Чем отличаются виртуальный хостинг, VPS, облако и статический хостинг, сколько памяти нужно сайту и боту и что спросить у продавца.
4 мин чтенияКак запустить Telegram бота на сервере
Polling или webhook, где взять токен и как его защитить, как запускать бота через systemd, pm2 или Docker и что делать при сбоях.
4 мин чтенияКак и где купить домен
Какую зону выбрать, что проверить перед оплатой, чем регистратор отличается от перепродавца и как не потерять домен.
4 мин чтения