Сайт на виртуальном хостинге

Аккаунт и тариф

Виртуальный хостинг продают тарифом на один аккаунт. Тариф определяет, сколько доменов можно добавить, сколько места на диске и трафика вы получите, сколько баз данных и почтовых ящиков входит в него и какие PHP версии можно выбрать. Панель — место, где всё это настраивается.

Прежде чем платить, проверьте пять вещей, потому что потом их менять больно: доступ по SSH или хотя бы по SFTP, предлагаемые версии PHP, число баз данных, размер почтовых ящиков и то, делает ли провайдер резервные копии и даёт ли вам восстановить одну самостоятельно. Какой хостинг выбрать рассказывает об остальном.

Когда аккаунт готов, вы получаете три адреса: панель, имя сервера или IP для передачи файлов и временный адрес вроде server17.hosting.example, по которому сайт отвечает до подключения домена. Временный адрес полезен: на нём можно собрать и проверить сайт, пока DNS ещё указывает в другое место.

Добавить сайт

  1. Войдите в панель с паролем из приветственного письма и сразу смените его.
  2. Найдите раздел сайтов и нажмите Добавить сайт.
  3. Наберите домен без http и без косой черты в конце: example.com.
  4. Согласитесь с предложенной папкой, например /home/example/www/example.com, или напишите свою. Запомните её: именно туда попадут файлы.
  5. Выберите PHP 8.3 или самую новую версию, которую предлагает тариф.
  6. Сохраните, затем добавьте 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.

Финальная проверка

  1. https://example.com отвечает 200 с нужной страницей.
  2. http://example.com один раз перенаправляет на HTTPS.
  3. https://www.example.com перенаправляет на выбранное вами имя.
  4. Сертификат действителен для обоих имён и не истекает в этом месяце.
  5. Страница PHP выполняется, а тестовый файл удалён.
  6. Страница показывает строку из таблицы, что доказывает работу базы данных.
  7. Почта в ящик и из ящика доходит, и в заголовках письма видно, что SPF и DKIM прошли.
  8. Резервная копия файлов и базы скачана на ваш компьютер, и архив открывается.
  9. Пароль панели длинный и уникальный, вход по двум факторам включён.

Вот и работающий сайт на виртуальном хостинге. У него есть домен, HTTPS, база данных, почта и резервная копия. Следующий урок делает то же самое на сервере, где администратор — вы, и большинство из этих девяти строк становятся командами, которые вы пишете сами.

Тест

1 Почему для загрузки сайта предпочитают SFTP, а не FTP?

  1. Он быстрее
  2. Он шифрует пароль и файлы, а FTP передаёт и то и другое открытым текстом
  3. Он сжимает файлы
  4. Он работает без пароля
Ответ

b) У FTP нет шифрования, поэтому любой, кто окажется на пути, может прочитать пароль. SFTP работает поверх SSH и шифрует весь сеанс.

2 Браузер предлагает скачать test.php вместо того, чтобы выполнить его. Что не так?

  1. У файла неверные права на чтение
  2. PHP не включён для этого сайта или файл лежит вне папки сайта
  3. База данных лежит
  4. Сертификат истёк
Ответ

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

3 Какие четыре значения нужны скрипту PHP, чтобы подключиться к базе данных?

  1. Домен, IP-адрес, DNS-серверы и TTL
  2. Хост, имя базы данных, пользователь базы данных и пароль
  3. Почтовый ящик, пароль, порт IMAP и порт SMTP
  4. Сертификат, ключ, цепочка и центр сертификации
Ответ

b) Они попадают в config.php, который лежит вне веб-корня. Хост — localhost, когда база данных работает на том же сервере, что и сайт.

4 Что делает второе правило в примере .htaccess?

  1. Сжимает картинки
  2. Отправляет www.example.com на example.com по HTTPS
  3. Блокирует посетителей из других стран
  4. Создаёт сертификат
Ответ

b) Оно находит хост, который начинается с www., и перенаправляет на то же имя без него, сохраняя путь.

5 Письма из нового ящика попадают в спам. Что исправить первым?

  1. Пароль почтового ящика
  2. Записи SPF и DKIM домена
  3. Порт IMAP
  4. Favicon сайта
Ответ

b) Без SPF и DKIM получатели не могут понять, что письмо действительно пришло с вашего домена. В панели для обоих есть переключатели.

6 Провайдер делает ежедневные резервные копии. Зачем делать свои?

  1. Копии провайдера всегда сломаны
  2. Нужна копия, которую вы контролируете, когда аккаунт заблокирован или у провайдера сбой
  3. Так сайт работает быстрее
  4. Это требуется для HTTPS
Ответ

b) Копия внутри того же аккаунта исчезает вместе с аккаунтом. Скачайте файлы и дамп базы на свою машину и проверьте, что они открываются.

7 На странице по HTTPS не показывается картинка, а консоль браузера говорит о смешанном содержимом. Что не так?

  1. Адрес картинки начинается с http://, и браузер блокирует её на странице HTTPS
  2. Сертификат выпущен для другого имени
  3. Не удалось подключиться к базе данных
  4. Порт 25 закрыт
Ответ

a) Файл http:// на странице https:// — это смешанное содержимое, и браузеры отказываются его загружать. Используйте адрес https:// или относительный путь для каждой картинки, таблицы стилей и скрипта.

Автор статьи: Arthur Isaev