Сайт на виртуальном хостинге
Аккаунт и тариф
Виртуальный хостинг продают тарифом на один аккаунт. Тариф определяет,
сколько доменов можно добавить, сколько места на диске и трафика вы
получите, сколько баз данных и почтовых ящиков
входит в него и какие PHP
версии можно выбрать. Панель — место,
где всё это настраивается.
Прежде чем платить, проверьте пять вещей, потому что потом их менять
больно: доступ по SSH или хотя бы по
SFTP, предлагаемые версии PHP, число баз
данных, размер почтовых ящиков и то, делает ли провайдер резервные
копии и даёт ли вам восстановить одну самостоятельно.
Какой хостинг выбрать рассказывает об
остальном.
Когда аккаунт готов, вы получаете три адреса: панель, имя сервера или IP
для передачи файлов и временный адрес вроде
server17.hosting.example, по которому сайт
отвечает до подключения домена. Временный адрес полезен: на нём можно
собрать и проверить сайт, пока DNS ещё
указывает в другое место.
Добавить сайт
- Войдите в панель с паролем из приветственного письма и сразу смените его.
- Найдите раздел сайтов и нажмите Добавить сайт.
- Наберите домен без http и без косой черты в конце: example.com.
- Согласитесь с предложенной папкой, например /home/example/www/example.com, или напишите свою. Запомните её: именно туда попадут файлы.
- Выберите PHP 8.3 или самую новую версию, которую предлагает тариф.
- Сохраните, затем добавьте www.example.com псевдонимом того же сайта, если панель просит его отдельно.
Теперь панель создаёт папку, системного пользователя для неё, блок настройки веб-сервера и, если вы разрешили, зону DNS. Сайт доступен по временному адресу, обычно через приём с именем домена в заголовке Host, который nginx.conf: настройка и сайты объясняет для Nginx.
Загрузить файлы
Попасть файлами на виртуальный хостинг можно тремя способами: SFTP, файловый менеджер в панели и FTP. Пользуйтесь SFTP. Он шифрует пароль и файлы, работает через тот же порт, что и SSH, и его поддерживает каждая панель. FTP передаёт и то и другое открытым текстом, и многие провайдеры поэтому его отключают.
На своём компьютере откройте терминал в папке с сайтом и подключитесь:
sftp example@203.0.113.10
Connected to 203.0.113.10. sftp>
Локальная копия сайта — это папка ~/site/, внутри которой лежат config.php и папка html/. Загрузите config.php на уровень выше папки сайта, чтобы веб-сервер не мог его отдать, а содержимое html/ — в папку сайта. Точка в конце put -r . означает текущую локальную папку:
sftp> cd www sftp> put ~/site/config.php sftp> cd example.com sftp> lcd ~/site/html sftp> put -r . sftp> bye
Графический клиент, например FileZilla или WinSCP, делает то же самое двумя панелями: перетащите файлы слева, с вашего компьютера, направо, на сервер. Установите протокол SFTP, а не FTP. Если вам удобнее одна команда на всю папку, scp копирует её в два шага:
scp ~/site/config.php example@203.0.113.10:~/www/
scp -r ~/site/html/. example@203.0.113.10:~/www/example.com/
Файловый менеджер в панели годится для одного файла, правки настройки или быстрого взгляда на права. Для целого сайта он медленный и может оборваться на большом архиве. Передачи из скриптов описаны в статье SFTP из скрипта Bash: несколько строк Bash копируют папку по расписанию.
Первая страница и проверка PHP
Начните с одного статического файла. Создайте index.html на своём компьютере, загрузите его и откройте сайт:
curl -I http://example.com/
HTTP/1.1 200 OK Server: nginx Content-Type: text/html
Код 200 с правильным типом содержимого означает, что папка, файл и домен совпадают. Если браузер показывает список файлов, значит файл называется не index.html или лежит на папку выше. Если он показывает страницу провайдера по умолчанию, домен не привязан к этой папке.
Затем проверьте PHP, прежде чем строить страницу, которая его использует. Создайте test.php из трёх строк, загрузите его и откройте http://example.com/test.php:
nano test.php
<?php echo "PHP " . PHP_VERSION; echo ", " . ini_get("memory_limit") . " memory";
PHP 8.3.6, 256M memory
Вывод доказывает, что веб-сервер передал запрос PHP и что версия та, которую вы выбрали. Сразу удалите файл: страница, которая печатает сведения о сервере, помогает атакующему больше, чем вам. Не используйте phpinfo() для этой проверки; три строки выше дают всё нужное. Если браузер предлагает скачать файл вместо того, чтобы выполнить его, PHP для сайта не включён, и в панели есть настройка версии PHP для домена.
База данных и страница на PHP, которая её использует
Пример сайта — одна таблица и один файл PHP. В разделе баз данных панели создайте базу, пользователя и пароль и дайте пользователю доступ к этой базе. Панель часто добавляет к именам имя вашего аккаунта; принимайте то, что получилось, и записывайте настоящие имена. Здесь это example_db и example_user.
Затем создайте таблицу и одну строку в phpMyAdmin или во вкладке SQL базы данных:
CREATE TABLE pages ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, body TEXT NOT NULL ); INSERT INTO pages (title, body) VALUES ('Hello', 'This page came from the database.');
В таблице есть id, заголовок и текст — всё, что нужно небольшому сайту для начала. Сам сайт — два файла. config.php хранит четыре значения подключения на уровень выше папки сайта, где веб-сервер не может его отдать:
nano config.php
<?php
return [
'db_host' => 'localhost',
'db_name' => 'example_db',
'db_user' => 'example_user',
'db_pass' => 'a-long-random-password',
];
html/index.php загружает этот файл, читает первую строку подготовленным запросом и печатает её через htmlspecialchars, чтобы заголовок, содержащий HTML, не мог вставить теги:
nano html/index.php
<?php
$config = require __DIR__ . '/../config.php';
$pdo = new PDO(
'mysql:host=' . $config['db_host'] . ';dbname=' . $config['db_name'] . ';charset=utf8mb4',
$config['db_user'],
$config['db_pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare('SELECT title, body FROM pages ORDER BY id LIMIT 1');
$stmt->execute();
$page = $stmt->fetch(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?= htmlspecialchars($page['title']) ?></title>
</head>
<body>
<h1><?= htmlspecialchars($page['title']) ?></h1>
<p><?= nl2br(htmlspecialchars($page['body'])) ?></p>
</body>
</html>
Загрузите два файла, как показал предыдущий раздел, откройте http://example.com/ и должна появиться строка из таблицы:
curl -s http://example.com/ | grep -E '<h1>|<p>'
<h1>Hello</h1> <p>This page came from the database.</p>
Ошибка базы данных здесь означает, что четыре значения в
config.php не совпадают с панелью или
пользователю не дали доступ к базе. Пароль лежит вне веб-корня
намеренно: config.php внутри папки сайта отдали
бы любому, кто угадает его имя.
Всё, что сайт сохраняет, попадает в
html/uploads/. Эта папка для файлов и никогда
для PHP, и урок 7 показывает правило, которое отказывается выполнять там
код.
Если ваш сайт на WordPress, дополнительные шаги перечислены в отдельной
статье:
Отдельная статья:
WordPress (необязательно).
HTTPS и перенаправления
Выпустите сертификат, как описано в предыдущем уроке, чтобы сайт отвечал по HTTPS, затем включите два перенаправления: каждый запрос по http идёт на https, а одно из двух имён — на другое. Во многих панелях оба есть в виде флажков. Если в вашей нет, правила кладут в файл .htaccess в папке сайта, который Apache читает при каждом запросе. При наличии SSH:
nano .htaccess
RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]
Первый блок отправляет обычный HTTP на HTTPS и сохраняет запрошенный
путь. Второй берёт любое имя, которое начинается с
www., и отправляет его на то же имя без него, по
HTTPS. Порядок важен: запрос к
http://www.example.com/a попадает под оба правила
и заканчивается на https://example.com/a.
В Nginx .htaccess нет; те же перенаправления —
это строки return 301 в блоке сервера, и урок
5 их пишет.
Проверьте результат цепочкой перенаправлений:
curl -I http://www.example.com/about/
HTTP/1.1 301 Moved Permanently Location: https://example.com/about/
Цель — один 301 и итоговый 200. Цепочка из трёх перенаправлений замедляет каждый первый визит и путает поисковые системы. После переключения проверьте, что каждая картинка, таблица стилей и скрипт на странице загружаются по https:// или по относительному пути: браузер блокирует файл http:// на странице HTTPS как смешанное содержимое, и страница выглядит сломанной, хотя сертификат в порядке.
Почтовый ящик
Ящик на своём домене выглядит профессионально и на большинстве тарифов не стоит дополнительно. В разделе почты панели создайте you@example.com, задайте длинный пароль и запишите имена серверов, которые показывает панель. Обычно это:
| Настройка | Значение |
|---|---|
| IMAP, входящая почта | mail.example.com, порт 993, SSL/TLS |
| SMTP, исходящая почта | mail.example.com, порт 465, SSL/TLS или порт 587 с STARTTLS |
| Имя пользователя | Полный адрес, you@example.com |
Отправьте письмо на адрес у другого провайдера и ответьте на него. Если письмо попадает в спам, домену не хватает записей SPF и DKIM: в панели для них есть переключатели, а урок 9 объясняет, что они значат. Без них большинство крупных почтовых провайдеров сочтут вашу почту подозрительной, каким бы хорошим ни был ящик. Статью о фишинге стоит прочитать, прежде чем передавать ящик кому-то ещё.
Резервные копии
Провайдер делает резервные копии, и этого недостаточно. Нужна копия, до которой вы доберётесь, когда аккаунт заблокируют, у провайдера будет плохой день или неудачное обновление удалит половину базы. Сделайте одну после того, как сайт заработает, а затем — по расписанию.
Файлы скачивают по SFTP или архивом из панели. База данных требует отдельного экспорта: в phpMyAdmin есть кнопка экспорта, а при наличии SSH достаточно одной команды:
mysqldump -u example_user -p example_db > ~/backup-$(date +%F).sql
Команда спросит пароль базы данных и запишет текстовый файл со всеми таблицами и строками. Скачайте его в тот же день: копия, которая живёт только на сервере, который она копирует, — не резервная копия. Держите несколько последних дампов и удаляйте старые, чтобы папка не росла без предела. Принципы — в статье о резервных копиях, которые действительно восстанавливаются, а задача по расписанию для дампа — это строка cron.
Финальная проверка
- https://example.com отвечает 200 с нужной страницей.
- http://example.com один раз перенаправляет на HTTPS.
- https://www.example.com перенаправляет на выбранное вами имя.
- Сертификат действителен для обоих имён и не истекает в этом месяце.
- Страница PHP выполняется, а тестовый файл удалён.
- Страница показывает строку из таблицы, что доказывает работу базы данных.
- Почта в ящик и из ящика доходит, и в заголовках письма видно, что SPF и DKIM прошли.
- Резервная копия файлов и базы скачана на ваш компьютер, и архив открывается.
- Пароль панели длинный и уникальный, вход по двум факторам включён.
Вот и работающий сайт на виртуальном хостинге. У него есть домен, HTTPS, база данных, почта и резервная копия. Следующий урок делает то же самое на сервере, где администратор — вы, и большинство из этих девяти строк становятся командами, которые вы пишете сами.
Тест
1 Почему для загрузки сайта предпочитают SFTP, а не FTP?
Ответ
b) У FTP нет шифрования, поэтому любой, кто окажется на пути, может прочитать пароль. SFTP работает поверх SSH и шифрует весь сеанс.
2 Браузер предлагает скачать test.php вместо того, чтобы выполнить его. Что не так?
Ответ
b) Веб-сервер отдал файл как текст, значит он не попал к обработчику PHP. Проверьте настройку версии PHP для домена и папку, на которую указывает сайт.
3 Какие четыре значения нужны скрипту PHP, чтобы подключиться к базе данных?
Ответ
b) Они попадают в config.php, который лежит вне веб-корня. Хост — localhost, когда база данных работает на том же сервере, что и сайт.
4 Что делает второе правило в примере .htaccess?
Ответ
b) Оно находит хост, который начинается с www., и перенаправляет на то же имя без него, сохраняя путь.
5 Письма из нового ящика попадают в спам. Что исправить первым?
Ответ
b) Без SPF и DKIM получатели не могут понять, что письмо действительно пришло с вашего домена. В панели для обоих есть переключатели.
6 Провайдер делает ежедневные резервные копии. Зачем делать свои?
Ответ
b) Копия внутри того же аккаунта исчезает вместе с аккаунтом. Скачайте файлы и дамп базы на свою машину и проверьте, что они открываются.
7 На странице по HTTPS не показывается картинка, а консоль браузера говорит о смешанном содержимом. Что не так?
Ответ
a) Файл http:// на странице https:// — это смешанное содержимое, и браузеры отказываются его загружать. Используйте адрес https:// или относительный путь для каждой картинки, таблицы стилей и скрипта.
Автор статьи: Arthur Isaev