Нужен VPS для своего проекта?

Можно зарегистрировать аккаунт в Beget, создать виртуальный сервер и сразу пройти эту инструкцию по шагам.

Зарегистрировать аккаунт в Beget

Главная идея

VPS — это ваш отдельный Linux-сервер. В отличие от обычного хостинга, вы сами определяете структуру каталогов, устанавливаете нужные версии PHP, Node.js, базы данных и сервисов, открываете порты и отвечаете за безопасность.

Основной путь в книге: чистая Ubuntu/Debian + Nginx. Команды для других Linux-семейств могут отличаться.

Важное правило

Не выполняйте незнакомые команды от root вслепую. Перед изменением SSH, firewall, базы или обновлением проекта делайте резервную копию и держите вторую SSH-сессию открытой.

Оглавление

Маршрут для первого проекта

Создать VPS → SSH → Firewall → Nginx/PHP → Файлы → БД → DNS → SSL → Backup

Если терминал пока непривычен

В Beget можно выбрать готовое решение с панелью управления. В официальной инструкции Beget среди вариантов упоминаются ISPmanager, FASTPANEL и HestiaCP. Но понимание базовых глав этой книги всё равно пригодится.

Обозначения в командах

В книгеЧто подставить
203.0.113.10Публичный IP вашего VPS из панели Beget.
example.ruВаш настоящий домен.
myprojectКороткое системное имя проекта без пробелов.
deployНепривилегированный пользователь для работы с проектом.
phpX.Y-fpm.sockФактический сокет PHP-FPM. Узнайте через ls /run/php/.

Глава 1

Что такое VPS и где что находится

VPS (Virtual Private Server) — виртуальный сервер с собственной операционной системой, IP-адресом, диском, оперативной памятью и root-доступом. На нём можно запускать сайты, API, базы данных, очереди, Redis, WebSocket-сервисы, Docker-контейнеры и фоновые процессы.

Пользователь браузер → DNS example.ru → IP → VPS Beget Nginx → приложение → БД

Панель Beget

Создать/удалить VPS, посмотреть IP и нагрузку, управлять конфигурацией, снапшотами и резервными копиями.

Сам VPS

Файлы, Nginx, PHP, Node, база данных, cron, systemd, логи и настройки Linux.

DNS

Сообщает интернету, на какой IP должен вести домен.

SFTP / SSH

SSH — управление командами. SFTP — безопасная загрузка файлов по тому же SSH-порту.

Каталоги Linux, которые вы будете видеть чаще всего

ПутьНазначение
/var/www/Удобное стандартное место для веб-проектов.
/etc/nginx/Конфигурация Nginx.
/etc/php/Конфигурация PHP.
/etc/systemd/system/Ваши systemd-сервисы, например Node-приложение.
/var/log/Системные и сервисные логи.
/home/deploy/Домашняя папка пользователя deploy.
/root/Домашняя папка root. Не используйте её как web-root проекта.

Не путайте VPS с обычным хостингом

На VPS нет обязательной папки вроде public_html , пока вы сами или панель управления её не создали. Вы решаете, где будет жить приложение.

Глава 2

Создание VPS в Beget

В панели Beget откройте раздел виртуальных серверов и создайте новый сервер. Beget позволяет выбрать готовую конфигурацию или задать CPU, RAM и SSD вручную, выбрать чистую ОС либо готовое приложение/панель, а также создать сервер из снапшота существующего VPS.

Практика: создайте VPS и повторяйте команды из статьи

Если сервера ещё нет, зарегистрируйтесь в Beget, выберите VPS на Ubuntu или Debian и сохраните IP-адрес. После этого можно переходить к SSH, настройке Nginx и загрузке проекта.

Создать VPS в Beget

Партнёрская ссылка

Выберите подход

Для обучения и полного контроля: чистая Ubuntu/Debian. Для быстрого управления сайтами: готовая панель. Для контейнерных приложений: Docker/Portainer.

Выберите ресурсы

Для небольшого PHP-сайта обычно важнее RAM и быстрый диск, для компиляции/очередей/индексации — CPU. Не выбирайте конфигурацию «впритык»: ОС, база, PHP-FPM и кэш тоже используют память.

Добавьте SSH-ключ

Лучше сделать это сразу на этапе создания. В панели вставляется публичная часть ключа. Приватный ключ остаётся только на вашем компьютере.

Сохраните данные

Запишите IP, имя сервера и способ входа. При парольной авторизации Beget указывает пароль для root в данных созданного сервера/уведомлении.

Как выбрать конфигурацию без гадания

ПроектСтартовый ориентирЧто контролировать
Лендинг, небольшая CMS1–2 vCPU, 1–2 GB RAMRAM, swap, PHP-FPM
Интернет-магазин / CRM2+ vCPU, 2–4+ GB RAMБаза, PHP, cron, фоновые задания
Node + WebSocket2+ vCPU, 2–4+ GB RAMRAM, event loop, процессы
Docker с несколькими сервисами2+ vCPU, 4+ GB RAMКонтейнеры и дисковое место

Не привязывайтесь к цифрам

Это не тарифная рекомендация Beget, а технический стартовый ориентир. Фактические ресурсы подбираются по мониторингу реальной нагрузки.

Сразу после создания

Терминал

ssh root@203.0.113.10

# Ubuntu / Debian
apt update
apt upgrade -y

# Посмотреть ОС и ядро
cat /etc/os-release
uname -a

# Ресурсы сервера
free -h
df -h
nproc

Глава 3

SSH, ключи и SFTP

Подключение из Windows, macOS или Linux

Современные Windows, macOS и Linux имеют SSH-клиент в терминале. Базовая команда:

Терминал

ssh root@203.0.113.10

Первое подключение спросит, доверяете ли вы fingerprint сервера. Сверьте IP, затем подтвердите.

Создание современного SSH-ключа

Терминал

ssh-keygen -t ed25519 -a 100

Публичный ключ имеет расширение .pub. Его можно добавлять на сервер. Приватный файл без .pub никому не отправляется.

Если сервер уже создан

Терминал

# На вашем компьютере
scp ~/.ssh/id_ed25519.pub root@203.0.113.10:~/

# На сервере
cat ~/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Проверка перед отключением пароля

Откройте второе окно терминала и убедитесь, что вход по ключу действительно работает. Только после этого отключайте парольную авторизацию.

SFTP: самый понятный способ заливать файлы

Используйте WinSCP, FileZilla или другой клиент с протоколом SFTP. Для чистого VPS параметры обычно такие:

ПолеЗначение
ПротоколSFTP
ХостIP VPS, например 203.0.113.10
Порт22 (если вы его не меняли)
Пользовательdeploy или временно root
АвторизацияSSH-ключ предпочтительно; пароль — как временный вариант

Архив часто быстрее тысяч мелких файлов

Загрузите project.zip в /var/www/example.ru/ , затем распакуйте на сервере: unzip project.zip -d current . Для регулярных обновлений лучше Git или rsync.

Глава 4

Минимальная безопасность до публикации сайта

Сервер с публичным IP начинают сканировать автоматически почти сразу. Минимальная защита должна появиться до того, как на VPS окажутся реальные данные.

1. Создайте отдельного пользователя

Терминал

adduser deploy
usermod -aG sudo deploy

# Если root уже настроен на вход по ключу
mkdir -p /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

Проверьте вход: ssh deploy@203.0.113.10, затем sudo -v.

2. Отключите парольный вход по SSH

Файл конфигурации

# /etc/ssh/sshd_config.d/01_nopasswd.conf
PasswordAuthentication no

Терминал

sudo systemctl restart sshd
sudo sshd -T | grep -i passwordauth

3. Включите UFW

Терминал

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Не включайте UFW до правила SSH

Иначе можно заблокировать собственный удалённый доступ.

4. Установите базовую защиту и обновления

Терминал

sudo apt update
sudo apt install -y fail2ban unattended-upgrades curl unzip git htop
sudo systemctl enable --now fail2ban

5. Секреты проекта

  • .env не хранится в публичной папке и не коммитится в Git.
  • База слушает localhost, если удалённый доступ не нужен.
  • Не ставьте chmod -R 777.
  • Для админки проекта используйте 2FA, если она поддерживается.
  • Сделайте снапшот перед крупными системными изменениями.

Глава 5

Куда именно заливать проект

Для чистого VPS удобно принять единый стандарт и больше его не менять:

/var/www/
└── example.ru/
    ├── current/       ← текущая версия приложения
    │   ├── public/    ← публичный web-root, если он есть у CMS/framework
    │   ├── src/
    │   ├── vendor/
    │   ├── .env
    │   └── ...
    ├── shared/        ← загрузки, конфиги, постоянные данные
    └── releases/      ← версии для безопасного деплоя

Простой вариант для проекта из ZIP

Терминал

sudo mkdir -p /var/www/example.ru/current
sudo chown -R deploy:www-data /var/www/example.ru

# Загрузите project.zip по SFTP в /var/www/example.ru/
cd /var/www/example.ru
unzip project.zip -d current
rm project.zip

Права доступа

Терминал

sudo chown -R deploy:www-data /var/www/example.ru/current
sudo find /var/www/example.ru/current -type d -exec chmod 750 {} \;
sudo find /var/www/example.ru/current -type f -exec chmod 640 {} \;

Если CMS должна писать в папки

Например, storage , cache , uploads . Разрешайте запись только этим каталогам, а не всему проекту.

Терминал

# Пример
sudo chown -R deploy:www-data /var/www/example.ru/current/storage
sudo chmod -R 770 /var/www/example.ru/current/storage

Что является web-root

Тип проектаОбычно root в Nginx
Простой PHP-сайт/var/www/example.ru/current
Laravel / Symfony-подобная архитектура/var/www/example.ru/current/public
Статический HTMLПапка с index.html
Node.jsNginx обычно проксирует на порт приложения; файлы не обязан отдавать напрямую

Главная причина 403/404 после загрузки

Nginx смотрит не в ту папку. Проверьте директиву root и наличие index.php или index.html .

Глава 6

Nginx + PHP-FPM для CMS, CRM и магазина

Установка

Терминал

sudo apt update
sudo apt install -y nginx php-fpm php-cli php-mysql php-curl php-mbstring php-xml php-zip php-gd php-intl

php -v
ls /run/php/
systemctl status nginx --no-pager

Команда ls /run/php/ покажет реальное имя сокета, например php8.3-fpm.sock или другую установленную версию.

Конфигурация сайта

Файл конфигурации

# /etc/nginx/sites-available/example.ru
server {
    listen 80;
    listen [::]:80;
    server_name example.ru www.example.ru;

    root /var/www/example.ru/current/public;
    index index.php index.html;

    client_max_body_size 64m;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/phpX.Y-fpm.sock;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Терминал

sudo ln -s /etc/nginx/sites-available/example.ru /etc/nginx/sites-enabled/example.ru
sudo nginx -t
sudo systemctl reload nginx

Замените phpX.Y

Не копируйте строку сокета вслепую. Подставьте имя из ls /run/php/ .

Если проект использует Composer

Терминал

sudo apt install -y composer
cd /var/www/example.ru/current
composer install --no-dev --optimize-autoloader

Для боевого проекта

Не запускайте Composer от root внутри проекта. Работайте пользователем deploy , чтобы не получить файлы с неожиданным владельцем.

Проверка PHP

Терминал

php -m
systemctl list-units --type=service | grep php
sudo nginx -t
curl -I http://127.0.0.1

Глава 7

MySQL / MariaDB: база для проекта

Для большинства PHP-CMS на одном VPS достаточно держать базу локально, не открывая порт 3306 наружу.

Установка MariaDB

Терминал

sudo apt update
sudo apt install -y mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo mysql_secure_installation

Создание базы и отдельного пользователя

Терминал

sudo mariadb
CREATE DATABASE myproject CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myproject_user'@'localhost' IDENTIFIED BY 'СЛОЖНЫЙ_ПАРОЛЬ';
GRANT ALL PRIVILEGES ON myproject.* TO 'myproject_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Запись в .env

DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myproject
DB_USERNAME=myproject_user
DB_PASSWORD=СЛОЖНЫЙ_ПАРОЛЬ

Импорт и экспорт

Терминал

# Импорт дампа
mariadb -u myproject_user -p myproject < backup.sql

# Экспорт
mysqldump --single-transaction -u myproject_user -p myproject > backup.sql

Не публикуйте порт базы без необходимости

Если приложение и БД живут на одном VPS, DB_HOST=127.0.0.1 — нормальный вариант. Удалённое подключение требует отдельной сетевой и пользовательской настройки.

Проверка

Терминал

sudo systemctl status mariadb --no-pager
sudo ss -lntp | grep 3306
mariadb -u myproject_user -p myproject -e "SELECT 1;"

MySQL вместо MariaDB

Можно использовать MySQL Server. Логика остаётся той же: отдельная база, отдельный пользователь приложения, локальный доступ, регулярный дамп.

Глава 8

Домен и DNS: направляем сайт на VPS

Домен начинает открывать ваш VPS только после того, как DNS-запись укажет на IP сервера.

Минимальные записи

ТипИмяЗначение
A@ или корень домена203.0.113.10
Awww203.0.113.10

Вместо второй A-записи для www допустим CNAME на основной домен, если ваш DNS-интерфейс это поддерживает и такая схема вам удобнее.

AAAA не добавляйте «на всякий случай»

AAAA должна указывать на реально настроенный IPv6. Неправильная AAAA-запись способна сделать сайт недоступным части пользователей.

Проверка DNS

Терминал

# С любого Linux/macOS или через WSL
nslookup example.ru

# Если установлен dig
dig +short A example.ru
dig +short A www.example.ru

Как понять, что DNS уже готов для SSL

Оба имени, которые вы собираетесь включить в сертификат, должны разрешаться в IP именно этого VPS. Beget отдельно обращает внимание на корректную A-запись перед выпуском Let’s Encrypt на VPS.

Домен → A-запись → IP VPS → Nginx по server_name → Ваш проект

Если домен управляется не в Beget

Это не проблема. A-запись меняется у того провайдера, который обслуживает текущие DNS-серверы домена. VPS может находиться в Beget, а DNS — у регистратора или отдельного DNS-провайдера.

Глава 9

HTTPS: бесплатный Let's Encrypt

На VPS сертификат устанавливается на ваш веб-сервер или через панель управления. Для Nginx удобно использовать Certbot.

До запуска Certbot

  • example.ru указывает на IP VPS.
  • www.example.ru тоже указывает на VPS, если вы включаете его в сертификат.
  • Порт 80 открыт.
  • Nginx запущен и конфигурация проходит nginx -t.

Установка

Терминал

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

Certbot предложит email и условия, затем обновит конфигурацию Nginx. После завершения проверьте:

Терминал

curl -I https://example.ru
sudo certbot renew --dry-run
systemctl status certbot.timer --no-pager

Срок сертификата

Let’s Encrypt использует короткоживущие сертификаты, поэтому важна автоматизация продления. Проверка renew --dry-run полезнее, чем надежда, что всё продлится само.

Редирект с HTTP на HTTPS

Если Certbot не добавил редирект автоматически, настройте отдельный HTTP server-блок:

server {
    listen 80;
    listen [::]:80;
    server_name example.ru www.example.ru;
    return 301 https://example.ru$request_uri;
}

Выберите один канонический адрес

Например, всегда https://example.ru без www. Это упрощает SEO, cookies и настройки приложений.

Глава 10

Node.js: приложение на 3000, сайт на 443

Node-приложение удобно держать на локальном порту, например 127.0.0.1:3000, а внешний трафик принимать Nginx. Так Node не нужно напрямую публиковать в интернет.

Структура

/var/www/api.example.ru/current/
├── package.json
├── server.js
├── .env
└── ...

Установка зависимостей

Терминал

cd /var/www/api.example.ru/current
npm ci --omit=dev
which node

Systemd-сервис

Файл конфигурации

# /etc/systemd/system/myproject-node.service
[Unit]
Description=MyProject Node application
After=network.target

[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/api.example.ru/current
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=3
Environment=NODE_ENV=production
EnvironmentFile=/var/www/api.example.ru/current/.env

[Install]
WantedBy=multi-user.target

Путь Node

Подставьте фактический путь из which node . Если Node установлен через nvm, путь может находиться в домашнем каталоге пользователя.

Терминал

sudo systemctl daemon-reload
sudo systemctl enable --now myproject-node
sudo systemctl status myproject-node --no-pager
curl http://127.0.0.1:3000

Nginx reverse proxy

server {
    listen 80;
    server_name api.example.ru;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Глава 11

Docker: когда проект состоит из нескольких сервисов

Docker удобен, когда приложению нужны web, worker, Redis, база или отдельные версии окружения. Главное правило — не публиковать наружу все контейнерные порты подряд.

Базовая установка из репозитория дистрибутива

Терминал

sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable --now docker
sudo usermod -aG docker deploy

docker --version
docker compose version

После добавления в группу docker нужно выйти из SSH и войти снова.

Пример Compose

services:
  app:
    build: .
    restart: unless-stopped
    env_file: .env
    ports:
      - "127.0.0.1:3000:3000"
    depends_on:
      - db

  db:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_DATABASE: myproject
      MARIADB_USER: myproject
      MARIADB_PASSWORD: change_me
      MARIADB_ROOT_PASSWORD: change_root_me
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

База не опубликована наружу

В примере у db нет ports: , поэтому 3306 не торчит в интернет. Приложение обращается к базе по внутреннему имени db .

Управление

Терминал

docker compose up -d
docker compose ps
docker compose logs -f --tail=200
docker compose pull
docker compose up -d
docker compose down

Снапшот перед обновлением контейнерной системы

Beget позволяет создавать снапшоты VPS. Это удобная дополнительная точка отката перед крупным обновлением, но не заменяет резервные копии данных.

Глава 12

Как обновлять проект и не ломать боевой сайт

Вариант A: простой ZIP

  1. Сделайте дамп базы.
  2. Сделайте снапшот VPS перед крупным релизом.
  3. Загрузите архив в отдельную папку.
  4. Перенесите .env и пользовательские загрузки.
  5. Проверьте права и зависимости.
  6. Только потом переключайте web-root/симлинк.

Вариант B: Git

Терминал

cd /var/www/example.ru/current
git status
git pull --ff-only
composer install --no-dev --optimize-autoloader
sudo nginx -t
sudo systemctl reload nginx

Не делайте git pull, если на сервере вручную изменены файлы проекта

Сначала git status . Боевой сервер не должен быть местом для случайного редактирования исходников.

Вариант C: releases + current

/var/www/example.ru/
├── releases/
│   ├── 2026-08-12_1100/
│   └── 2026-08-18_1530/
├── shared/
│   ├── .env
│   └── uploads/
└── current -> releases/2026-08-18_1530/

Новая версия готовится отдельно. После проверки симлинк current переключается на неё. Откат — вернуть симлинк на предыдущую версию.

Терминал

ln -sfn /var/www/example.ru/releases/2026-08-18_1530 /var/www/example.ru/current

Очередность для CMS с миграциями

DB backup → новый release → dependencies → migration → switch → health-check

После деплоя проверяйте не только главную

Авторизация, создание/изменение записи, загрузка файла, отправка формы, cron, очередь, API и платёжный callback могут ломаться отдельно.

Глава 13

Резервные копии: код, файлы, база, весь VPS

У хорошей схемы резервного копирования несколько уровней. Beget сообщает об автоматических файловых резервных копиях VPS на отдельных серверах в другом дата-центре; кроме этого, в VPS доступны снапшоты. Для критичного проекта всё равно полезно иметь независимую копию вне основного VPS.

Git

Исходный код и история. Не хранит реальную базу и пользовательские загрузки.

DB dump

Снимок базы на конкретный момент.

Файловый backup

Uploads, конфиги, документы, пользовательские данные.

Snapshot VPS

Быстрый откат всего состояния сервера перед рискованным изменением.

Пример ручного бэкапа проекта

Терминал

sudo mkdir -p /var/backups/myproject

# База
mysqldump --single-transaction -u myproject_user -p myproject \
  | gzip > /var/backups/myproject/db-$(date +%F-%H%M).sql.gz

# Пользовательские файлы
sudo tar -czf /var/backups/myproject/files-$(date +%F-%H%M).tar.gz \
  /var/www/example.ru/shared

Пример cron

Терминал

sudo crontab -e
# Каждый день в 03:20. Лучше использовать отдельный credentials-файл,
# а не писать пароль прямо в crontab.
20 3 * * * /usr/local/sbin/backup-myproject.sh >> /var/log/backup-myproject.log 2>&1

Backup, который никогда не восстанавливали, — только предположение

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

Перед любым большим обновлением

  • Проверить свежий DB dump.
  • Проверить backup пользовательских файлов.
  • Сделать snapshot VPS, если изменение затрагивает ОС/сервисы.
  • Записать, как откатить новую версию приложения.

Глава 14

Логи и диагностика: куда смотреть, когда «не работает»

Состояние сервера

Терминал

uptime
free -h
df -h
df -i
htop
sudo ss -lntup
sudo systemctl --failed

Nginx

Терминал

sudo nginx -t
sudo systemctl status nginx --no-pager
sudo tail -n 100 /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

PHP-FPM

Терминал

systemctl list-units --type=service | grep php
sudo journalctl -u phpX.Y-fpm -n 100 --no-pager

MariaDB

Терминал

sudo systemctl status mariadb --no-pager
sudo journalctl -u mariadb -n 100 --no-pager

Node / systemd

Терминал

sudo systemctl status myproject-node --no-pager
sudo journalctl -u myproject-node -f

Docker

Терминал

docker compose ps
docker compose logs --tail=200
docker stats

Сеть и DNS

Терминал

curl -I http://127.0.0.1
curl -I https://example.ru
nslookup example.ru
sudo ss -lntp | grep -E ':80|:443|:3000|:3306'

Диагностируйте слоями

1) процесс жив? 2) порт слушается? 3) локальный curl работает? 4) Nginx проксирует? 5) DNS ведёт на этот IP? 6) firewall пропускает? 7) HTTPS валиден?

Глава 15

Типовые ошибки и быстрый путь к причине

СимптомЧаще всегоПроверка
502 Bad GatewayPHP-FPM/Node не запущен, неверный socket/портsystemctl status, ss -lntp, Nginx error.log
504 Gateway TimeoutПриложение зависло или долго отвечаетЛоги приложения, база, внешние API, таймауты
403 ForbiddenНеправильные права или web-rootls -la, Nginx root, владелец файлов
404 на всех внутренних URLНет правила маршрутизации CMStry_files ... /index.php?$query_string
500 Internal Server ErrorОшибка приложения/PHPNginx error.log + лог CMS/framework
SSL не выпускаетсяDNS не указывает на VPS, закрыт 80, неверный доменdig/nslookup, ufw status, nginx -t
Сайт открывается по IP, но не по доменуDNS или server_namenslookup, Nginx config
Can't connect to databaseНеверные DB_* или сервис не запущенsystemctl status mariadb, ручной вход в БД
No space left on deviceЗакончился диск или inodedf -h, df -i, Docker/logs/backups
SFTP permission deniedФайлы принадлежат root/www-datals -la, chown deploy:www-data

Безопасный порядок исправления

  1. Не менять десять настроек сразу.
  2. Сохранить текущий конфиг.
  3. Проверить точную ошибку в логах.
  4. Исправить одну причину.
  5. Проверить конфигурацию (nginx -t и т. п.).
  6. Перезапускать только нужный сервис.

Не лечите права командой chmod 777

Она часто маскирует настоящую проблему и увеличивает риск компрометации.

Глава 16

Если хочется панель вместо терминала

Beget предлагает готовые решения для VPS. В своей инструкции Beget рекомендует новичкам рассмотреть панели, включая ISPmanager, FASTPANEL и HestiaCP; для контейнеров также упоминается Portainer.

HestiaCP / FASTPANEL

Удобны, когда нужно быстро добавлять сайты, домены, PHP, базы, SSL и пользователей через веб-интерфейс.

ISPmanager

Коммерческая панель с широким набором функций. Удобна для нескольких сайтов и администрирования через UI.

Portainer

Графический интерфейс к Docker. Полезен, если проект живёт в контейнерах.

Чистый VPS

Меньше лишних слоёв, полный контроль, но больше ответственности за настройку.

Как изменится вопрос «куда заливать?»

В панели путь обычно создаётся автоматически при добавлении сайта. Не угадывайте путь. Посмотрите document root в настройках конкретного домена. Он может отличаться от предложенной в этой книге схемы /var/www/example.ru/current.

Что панель не отменяет

  • DNS всё равно должен вести на VPS.
  • SSL всё равно зависит от корректного домена и доступности сервера.
  • Backup нужно проверять.
  • Обновления CMS и зависимостей остаются вашей задачей.
  • Нагрузка и свободный диск требуют наблюдения.
  • Секреты и пароли нужно хранить безопасно.

Для первого VPS панель — нормальный выбор

Не обязательно сразу становиться системным администратором. Но держите в голове слои: DNS → веб-сервер → приложение → база → фоновые сервисы.

Глава 17

Готовые сценарии: что делать для разных проектов

Сценарий 1. Самодельная PHP CMS / CRM

Ubuntu → Nginx → PHP-FPM → MariaDB → /var/www/domain → DNS → Certbot

  1. Создать VPS и SSH-ключ.
  2. Создать deploy, UFW, fail2ban.
  3. Установить Nginx, PHP-модули, MariaDB.
  4. Залить архив в /var/www/domain/current.
  5. Создать БД и прописать .env.
  6. Создать Nginx server block.
  7. Направить A-записи.
  8. Выпустить SSL.
  9. Настроить cron и бэкап.

Сценарий 2. Node API / WebSocket

Node app :3000 ← systemd ← Nginx :443 ← Интернет

Node слушает только 127.0.0.1. Systemd перезапускает его после сбоя/ребута. Nginx принимает HTTPS и проксирует запрос.

Сценарий 3. Docker-проект

Nginx → app container → db/redis internal

Наружу публикуйте только то, что действительно должно быть доступно. Базы и Redis обычно остаются во внутренней Docker-сети.

Сценарий 4. Несколько сайтов на одном VPS

/var/www/site1.ru/current
/var/www/site2.ru/current
/var/www/crm.site3.ru/current

/etc/nginx/sites-available/site1.ru
/etc/nginx/sites-available/site2.ru
/etc/nginx/sites-available/crm.site3.ru

У каждого домена свой server block, свой каталог, желательно своя БД и отдельный пользователь БД. Для высокой изоляции можно разделять и системных пользователей.

Глава 18

Командная шпаргалка владельца VPS

КомандаЧто делает
ssh deploy@IPПодключиться по SSH
sudo -iВременно открыть root shell через sudo
pwdТекущая папка
ls -lahПоказать файлы и права
cd /pathПерейти в каталог
cp -a A BКопировать с сохранением атрибутов
mv A BПереместить / переименовать
rm -rf pathОпасно: рекурсивно удалить без корзины
chown -R deploy:www-data pathСменить владельца/группу
chmod 640 fileПрава файла
df -hСвободное место
free -hОперативная память
htopПроцессы и нагрузка
ss -lntupКакие порты слушаются
systemctl status NAMEСтатус сервиса
systemctl restart NAMEПерезапустить сервис
journalctl -u NAME -fСледить за логом сервиса
nginx -tПроверить конфигурацию Nginx
ufw statusПравила firewall
curl -I URLПроверить HTTP-заголовки
dig +short A domain.ruПроверить A-запись
tar -czf a.tar.gz folderСоздать gzip-архив
unzip file.zipРаспаковать ZIP
git statusСостояние Git-репозитория
git pull --ff-onlyБезопаснее обычного pull для прямолинейного деплоя

Три команды, с которыми особенно осторожно

rm -rf , массовый chmod/chown и любые команды с перенаправлением > в системные файлы. Ошибка в пути может удалить или перезаписать не тот каталог.

Глава 19

Чек-лист боевого запуска проекта

Сервер

  • ОС обновлена.
  • Есть пользователь deploy с sudo.
  • SSH по ключу проверен.
  • Парольный SSH отключён после проверки ключа.
  • UFW разрешает только необходимые публичные порты.
  • Fail2ban включён.

Приложение

  • Файлы лежат в понятном каталоге /var/www/....
  • Web-root не открывает наружу .env, vendor/system/config без необходимости.
  • Writable-папки ограничены точечно.
  • Секреты не находятся в Git.
  • Боевой режим debug выключен.

Домен и HTTPS

  • A-записи ведут на IP VPS.
  • Nginx server_name совпадает с доменом.
  • HTTP открывается до выпуска сертификата.
  • HTTPS работает без предупреждений.
  • Есть один канонический вариант домена.
  • Проверено автоматическое продление сертификата.

Данные и эксплуатация

  • База не доступна из интернета без необходимости.
  • Есть автоматический DB dump.
  • Есть backup пользовательских файлов.
  • Проверен сценарий восстановления.
  • Перед крупными обновлениями используется snapshot/backup.
  • Известно, где смотреть Nginx, PHP/Node и DB логи.
  • Есть контроль свободного места и RAM.

Если все пункты закрыты

Вы уже не просто «залили сайт на VPS», а построили базовую рабочую схему эксплуатации, которую можно масштабировать на несколько проектов.

Готовы запустить свой проект на VPS?

Создайте аккаунт в Beget, поднимите VPS и используйте чек-лист выше как последовательность запуска: сервер → файлы → база → домен → HTTPS → резервные копии.

Перейти в Beget

Партнёрская ссылка

Приложение

Официальные материалы Beget и полезные ориентиры

Книга составлена как самостоятельная практическая инструкция. При изменении интерфейса панели или доступных образов VPS сверяйтесь с актуальной документацией провайдера.

  1. Beget: виртуальные серверы (VPS/VDS), создание, готовые решения, снапшоты, SSH-ключи
  2. Beget: первые шаги после создания VPS, защита и мониторинг
  3. Beget: настройка UFW на Ubuntu
  4. Beget: Let's Encrypt на VPS
  5. Beget: руководство по панели управления, включая резервное копирование VPS
  6. Beget: SSH-авторизация по ключу
  7. Beget: подключение по SFTP через WinSCP