Тот же сайт на VPS или выделенном сервере
Выбрать тариф
Сайту из урока 4 нужно очень мало: несколько файлов PHP, одна
база данных, почтовый ящик в другом месте. Двух
виртуальных ядер, 2 ГБ памяти и 40 ГБ диска хватит ему и экспериментам,
которые последуют. Меньше — и сборка PHP или
импорт базы могут упереться в память в самый неподходящий момент.
Ищите в предложении четыре вещи. Резервные копии или хотя бы снимки,
которые можно восстановить за минуту. Адрес
IPv4 и адрес
IPv6. Консоль или режим
восстановления в панели — на тот день, когда
SSH перестанет отвечать. И дата-центр
недалеко от ваших посетителей.
VPS хостинг показывает, как создать
машину у одного провайдера, включая регион, образ и ключ SSH; шаги ниже
начинаются, когда машина работает и у вас есть её IP-адрес.
Ключ SSH и первый вход
Пароль по SSH можно подобрать; ключ — нельзя. Если вы создали сервер с открытым ключом, как описано на странице VPS, для первого входа пароль не нужен. Если провайдер прислал пароль root, войдите с ним один раз и сразу переходите на ключи.
ssh root@203.0.113.10
The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established. ED25519 key fingerprint is SHA256:.... This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])?
Набирайте yes, только если отпечаток совпадает с тем, что провайдер показывает в панели. Это сравнение — единственная защита от машины, которая притворяется вашим новым сервером. Приглашение меняется на root@example:~#.
Пользователь с sudo и обновления
Работа от root всё время — это способ превратить опечатку в простой. Создайте обычного пользователя, дайте ему право на sudo и скопируйте ключ, чтобы входить под этим пользователем:
adduser example
usermod -aG sudo example
cp -r /root/.ssh /home/example/.ssh
chown -R example:example /home/example/.ssh
chmod 700 /home/example/.ssh
chmod 600 /home/example/.ssh/authorized_keys
Откройте второй терминал и войдите под новым пользователем, прежде чем закрыть первый. Если ключ скопирован неправильно, у root ещё есть рабочая сессия, и вы можете всё исправить:
ssh example@203.0.113.10
С этого момента каждая команда, которая меняет систему, начинается с sudo. Затем приведите систему в актуальное состояние:
sudo apt update
sudo apt upgrade -y
apt update обновляет список доступных пакетов, apt upgrade устанавливает более новые версии. На свежем сервере вторая команда может обновить и ядро; перезагрузка в конце — это нормально.
Файрвол
В Ubuntu инструмент — ufw, надстройка над iptables, которая в Ubuntu 24.04 работает на бэкенде nftables. Сначала разрешите SSH, затем веб-порты и только потом включайте файрвол. В обратном порядке вы сами закроете себе доступ к серверу:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
sudo ufw status verbose
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- OpenSSH ALLOW IN Anywhere 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere OpenSSH (v6) ALLOW IN Anywhere (v6) 80/tcp (v6) ALLOW IN Anywhere (v6) 443/tcp (v6) ALLOW IN Anywhere (v6)
Два правила открывают веб-порты для сервера, который ставится дальше. Политика по умолчанию отклоняет каждое входящее подключение, которое не разрешено правилом, и это то, что нужно: база данных и панель остаются невидимыми из интернета, даже если слушают. Правила одинаковы в любом дистрибутиве Linux; Файрвол в Linux рассказывает о них подробнее.
Nginx, PHP-FPM и MariaDB
Сайт запускают четыре пакета: веб-сервер, обработчик PHP, база данных и горсть расширений PHP, которые нужны большинству сайтов на PHP. Ubuntu 24.04 поставляет PHP 8.3, и это та версия, которую использует курс:
sudo apt install nginx mariadb-server php8.3-fpm php8.3-mysql php8.3-curl php8.3-xml php8.3-mbstring php8.3-zip php8.3-gd unzip
Установщик запускает Nginx и MariaDB. PHP-FPM работает отдельной службой; Nginx использует его, когда блок сервера передаёт запросы .php в его сокет, что и делает блок ниже. Проверьте через systemctl, что все три службы работают:
systemctl is-active nginx mariadb php8.3-fpm
active active active
Откройте адрес сервера в браузере: отвечает приветственная страница Nginx, и это доказывает, что файрвол и веб-сервер согласны друг с другом. Если видите ошибку браузера, проверьте ufw status и systemctl status nginx. Полная установка, включая подробности о сайте по умолчанию, — в статье Установка Nginx на Ubuntu.
MariaDB нужна одна команда, чтобы быть в безопасности на свежей установке. Она задаёт пароль root для базы данных, удаляет анонимных пользователей и тестовые базы данных и задаёт несколько вопросов; отвечайте да на все:
sudo mariadb-secure-installation
Теперь база данных отвечает только на localhost, и это значение по умолчанию и правильная настройка для сайта на той же машине. Никогда не открывайте порт 3306 в файрволе.
Блок сервера
Папка для файлов, файл настройки для Nginx, символическая ссылка, которая его включает. Папка принадлежит пользователю сайта, а её группа — группа веб-сервера. Пока урок 8 не даст сайту собственный пул, PHP работает под www-data, поэтому папке загрузок понадобится запись для группы; команды после копирования её добавляют:
sudo mkdir -p /var/www/example.com/html
sudo chown -R example:www-data /var/www/example.com
sudo vi /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.php index.html; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm.sock; } location ~ /\.ht { deny all; } }
Блок location / пробует запрошенный файл, затем папку, затем отвечает 404. Это правильное правило для небольшого сайта из курса. Фронт-контроллер, к которому прибегает фреймворк или CMS, отправляет каждый запрос в один файл, с try_files $uri $uri/ /index.php?$query_string;. Блок PHP отправляет каждый запрос .php в сокет PHP-FPM по умолчанию; отдельный пул на сайт заменяет его в уроке 8. Последний блок отказывает в любом запросе к скрытому файлу .htaccess.
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo systemctl reload nginx
Домену пока не обязательно указывать сюда. Nginx выбирает сайт по заголовку Host, поэтому curl может притвориться доменом, и запрос дойдёт до вашего нового блока. Папка пока пустая, поэтому запрос ответил бы 403; сначала напишите тестовую страницу от пользователя сайта:
sudo -u example sh -c 'echo "<h1>example.com</h1>" > /var/www/example.com/html/index.html'
curl -H "Host: example.com" http://203.0.113.10/
<h1>example.com</h1>
Шаг с rsync ниже заменит этот тестовый файл настоящим сайтом.
Скопировать сайт через rsync
Со своего компьютера, из папки с файлами сайта, скопируйте всё на сервер. -a сохраняет права и время, -v перечисляет файлы, -z сжимает передачу, а --delete удаляет на сервере файлы, которых больше нет локально:
rsync -avz --delete ~/site/ example@203.0.113.10:/var/www/example.com/
sending incremental file list ./ config.php html/ html/index.php html/uploads/ ...
Назначение — папка сайта, а не html/: config.php попадает на уровень выше веб-корня, точно как на виртуальном хостинге.
Будьте осторожны с --delete в первый раз: он приводит сервер в точное соответствие с вашей папкой. Если папка загрузок есть только на сервере, её удалят. Скопируйте один раз без этой опции, сравните, затем добавьте её для регулярных обновлений.
PHP работает под www-data, пока урок 8 не создаст пул для сайта, а файлы, скопированные rsync, принадлежат example с группой example, поэтому сайт пока не может писать свои загрузки. Создайте папку, если копирование её не принесло, и дайте веб-серверу запись для группы только на эту папку:
sudo -u example mkdir -p /var/www/example.com/html/uploads
sudo chgrp -R www-data /var/www/example.com/html/uploads
sudo chmod -R g+w /var/www/example.com/html/uploads
Урок 8 заменит это пулом PHP-FPM, который работает под example, и тогда папку можно вернуть группе сайта.
Импорт базы данных
Файлы — только половина сайта; таблица pages и её строки живут в базе данных. Экспортируйте её на старом хосте, перенесите дамп и импортируйте на новом сервере. На старом хосте:
mysqldump -u example_user -p example_db > site.sql
scp site.sql example@203.0.113.10:~/
На новом сервере создайте базу и пользователя, дайте доступ и загрузите файл. Три команды создают те же имена, что были на старом хосте, чтобы config.php продолжал работать:
sudo mariadb -e "CREATE DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mariadb -e "CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'a-long-random-password';"
sudo mariadb -e "GRANT ALL ON example_db.* TO 'example_user'@'localhost';"
sudo mariadb example_db < ~/site.sql
Дамп большого сайта занимает время и ничего не печатает, когда всё удалось. Проверьте результат внутри базы данных: в списке таблиц должна быть pages:
sudo mariadb -e "SHOW TABLES FROM example_db;"
+---------------------+ | Tables_in_example_db | +---------------------+ | pages | +---------------------+
Если старый хост использовал другого пользователя или пароль базы,
отредактируйте config.php на новом сервере под
то, что вы только что создали. Тогда сайт загружается по временному IP с
заголовком Host из проверки выше, до любого
изменения DNS.
Если ваш сайт на WordPress, дополнительные шаги перечислены в отдельной
статье:
Отдельная статья:
WordPress (необязательно).
Снизить TTL и переключить DNS
Делайте это в два шага с разницей в день, и переезд займёт минуты, а не часы. Сначала, за день до переключения, снизьте TTL записей A и AAAA до 300 секунд. Тогда старый ответ быстро истечёт, когда вы его измените:
example.com. 300 IN A 198.51.100.20
Во-вторых, когда новый сайт правильно отвечает в проверке с заголовком Host, смените запись A на новый сервер, 203.0.113.10, и дождитесь, пока пройдёт старый TTL. Следите за ответом публичного резолвера: он ближе к тому, что видят посетители, чем ваш собственный:
dig +short @1.1.1.1 example.com
203.0.113.10
Оставьте старый сервер работать, а его файлы — неизменными хотя бы сутки после переключения. Некоторые посетители и некоторые почтовые серверы будут ещё пользоваться старым адресом, пока не истекут их кэши. Когда всё выглядит правильно, верните TTL к 3600 и отмените старый тариф.
Certbot и продление
Сертификат от Let's Encrypt бесплатен, и для него нужны две команды. Certbot читает настройку Nginx, доказывает контроль над каждым именем по HTTP, устанавливает сертификат и с --redirect пишет перенаправление с http на https. Первый запуск ещё спрашивает адрес почты для уведомлений об окончании срока и согласие с условиями обслуживания:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx --redirect -d example.com -d www.example.com
Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem This certificate expires on 2027-02-04. Deploying certificate Successfully deployed certificate for example.com to /etc/nginx/sites-enabled/example.com Congratulations! You have successfully enabled HTTPS on https://example.com
Проверьте, что перенаправление на месте:
curl -I http://example.com/
HTTP/1.1 301 Moved Permanently Location: https://example.com/
Certbot также ставит таймер systemd, который продлевает сертификат дважды в день, когда срок подходит к концу. Проверьте, что таймер есть и что продление прошло бы успешно, не дожидаясь настоящей даты:
systemctl list-timers | grep certbot
Fri 2026-11-06 15:22:00 UTC 9h left certbot.timer certbot.service
sudo certbot renew --dry-run
Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/example.com/fullchain.pem (success)
Пробный запуск — та проверка, которую повторяют после любого изменения настройки. О самом сертификате рассказывает статья об HTTPS и сертификатах простыми словами, а о службе, которая его выпускает, — letsencrypt.org.
Журналы
Когда сайт ведёт себя странно, три места отвечают на большинство вопросов. Nginx пишет строку на каждый запрос в журнал доступа, а причины сбоев — в журнал ошибок:
sudo tail -n 5 /var/log/nginx/access.log
203.0.113.55 - - [06/Nov/2026:10:00:00 +0000] "GET / HTTP/1.1" 200 5123 "-" "Mozilla/5.0" 203.0.113.55 - - [06/Nov/2026:10:00:01 +0000] "GET /wp-login.php HTTP/1.1" 404 162 "-" "Mozilla/5.0"
sudo tail -n 5 /var/log/nginx/error.log
2026/11/06 09:59:12 [error] 1234#1234: *56 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size exhausted" while reading response header from upstream
Третье место — журнал systemd, который хранит вывод самих служб. Здесь видно падение PHP-FPM или перезапуск Nginx:
sudo journalctl -u php8.3-fpm -n 20 --no-pager
Читайте журналы снизу вверх и отметьте время первой ошибки. Первая строка — причина; сто строк после неё — следствия.
Что меняется на выделенном сервере
Всё вышеперечисленное работает на выделенном сервере так же: это тоже машина с Ubuntu, где вы root. Различия физические.
- Оборудование только ваше. Диски, память и сетевой порт не делятся, поэтому шумный сосед не может вас замедлить. Вы также платите за всю машину, даже когда она простаивает.
- RAID — ваша работа. Два или четыре диска в RAID 1 или RAID 10 переживают отказ одного диска. Без RAID отказ диска — это восстановление из резервной копии. Проверяйте массив командой cat /proc/mdstat и следите за ним в мониторинге.
- Удалённая консоль — единственная клавиатура. IPMI, iDRAC или похожий интерфейс позволяет увидеть экран загрузки, войти в BIOS и исправить сломанную сетевую настройку. Узнайте, где она, до того как она понадобится.
- Диски меняет провайдер по заявке в поддержку, и массив перестраивается, пока сервер работает. Держите серийные номера и схему RAID в своих записях.
- Питание, охлаждение и сеть принадлежат дата-центру. Спросите о скорости канала, лимите трафика и о том, что происходит при отказе оборудования: замена диска за четыре часа — другое предложение, чем за четыре дня.
Для одного небольшого сайта VPS почти всегда выгоднее: те же команды, цена в несколько раз ниже и снимки, которые восстанавливаются за минуту. Выделенный сервер оправдан, когда нужны многие ядра, большой дисковый массив или сеть, на которую не может повлиять сосед.
Тест
1 Зачем создавать обычного пользователя с sudo вместо работы от root?
Ответ
c) Root может удалить что угодно одной командой. Обычному пользователю нужен sudo на каждое изменение, и это заставляет на миг подумать и оставляет след для аудита.
2 В каком порядке настраивают файрвол на новом сервере?
Ответ
b) При политике запрета по умолчанию и без правила для SSH вы сами закроете себе доступ. Разрешите нужные порты, затем включайте файрвол.
3 Какая директива заставляет Nginx отправлять запросы .php в PHP-FPM?
Ответ
d) fastcgi_pass указывает сокет или адрес пула PHP-FPM. root только говорит, где лежат файлы.
4 Зачем снижать TTL за день до переноса сайта на другой сервер?
Ответ
b) TTL решает, как долго резолверы держат старый адрес. Снижайте его до изменения, а не после, чтобы само изменение разошлось за минуты.
5 Файлы на новом сервере, база данных импортирована, но сайт показывает старое содержимое. Какова наиболее вероятная причина?
Ответ
b) До новой машины не добраться, пока DNS не укажет на неё и старые ответы не истекут. Проверьте заголовком Host против нового IP, чтобы разделить две проблемы.
6 Как узнать, что продление сертификата будет работать и дальше?
Ответ
c) Пробный запуск повторяет настоящее продление, ничего не меняя. Замок сегодня ничего не говорит о том, что будет через 60 дней.
7 Какая задача появляется только на выделенном сервере, но не на VPS?
Ответ
b) Провайдер VPS скрывает оборудование. На выделенной машине диски, массив и удалённая консоль становятся частью вашей работы.
Автор статьи: Arthur Isaev