shared-hosting-to-vds/

Когда я начинал вести этот блог в 2009 году, хостить сайты, особенно небольшие, на VDS как-то не было принято. (Не говоря уже о том, что сами идеи «посвящать самому себе сайт» / «вести общедоступный дневник» были еще новыми и казались немного дикими.) Главным образом, все использовали shared hosting, потому что он стоил дешевле VDS и решал свою задачу — сайт работал, странички открывались. Сегодня, конечно же, все сильно изменилось. Не только VDS стали дешевле, но и современные браузеры стали ругаться на сайты, не использующие HTTPS. А за сертификаты хостинг-провайдеры берут деньги. Еще бы, ведь у клиентов нет на сервере рутовых прав, а значит Let’s Encrypt они прикрутить не могут. В любом случае, в современных реалиях держать сайт на шаред хостинге иначе как зашкваром не назовешь. Поэтому я решил рассказать о своем опыте переноса сайта на VDS, на примере этого самого блога.

Примечание: Описанная ниже конфигурация покажется кому-то довольно олдскульной (в нашу-то с вами эпоху контейнеров и микросервисов на Go !), потому что именно таковой она и является. Я ставил перед собой задачу перенести сайт на VDS в том виде, в каком он есть, а не менять используемый стек технологий. Возможно, когда-нибудь я решу уделить время и данному вопросу тоже, но это уже будет темой отдельной статьи. Отмечу также, что гуру Linux не найдут для себя много нового в этой статье. Однако тем, кто гуру не является, она может быть крайне полезна.

LAMP для нетерпеливых

В этом разделе я опишу установку так называемого LAMP, то есть, связку Linux + Apache + MySQL + PHP. По этой теме только ленивый не писал статей. Тем не менее, я посчитал, что для полноты картины соответствующую инструкцию следует включить в текст. Постараюсь быть максимально кратким.

Использованный мной VDS имеет 1 ядро CPU, 1 Гб RAM и 25 Гб места на диске. Как показала практика, для персонального блога этих ресурсов хватает просто за глаза. При выборе региона, в котором будет размещаться VDS, убедитесь, что он не попал под раздачу РКН . Также желательно, чтобы регион территориально находился близко к вашей основной аудитории — чем меньше пинг, тем быстрее кажется работа сайта. Например, если вы пользуетесь DigitalOcean, и ваша основная аудитория, согласно статистике сайта, находится в России, то можно порекомендовать регион AMS2 (на момент написания этих строк).

Работает VDS под управлением Ubuntu Linux 16.04, потому что именно такой дистрибутив использовался на старом хостинге. Я решил придерживаться стратегии «сначала унести все на VDS, а затем при необходимости обновить все на версии поновее». Если вы решите повторить действия из этой заметки, советую поступить так же. Для других дистрибутивов Linux отличия будут минимальными, и заключаться в основном в использовании другого менеджера пакетов.

Прежде всего, не сидим на сервере под рутом:

adduser afiskon
# говорим, что пользователь может sudo
vim / etc / sudoers
# копируем ~/.ssh/authorized_keys
cp -r .ssh / home / afiskon / .ssh
chown -R afiskon:afiskon / home / afiskon / .ssh /
exit

Заходим под новым пользователем. Меняем таймзону, чтобы время в логах нам о чем-то говорило, а запланированные посты публиковались вовремя:

sudo dpkg-reconfigure tzdata

На старом хостинге использовался PHP 5.3, поэтому добавим такой PPA:

sudo add-apt-repository ppa:ondrej / php
sudo apt update

Из него можно установить PHP 5.6, что достаточно близко. Более старые версии на момент написания этих строк больше не поддерживаются, и найти для них готовые пакеты оказалось проблематичным.

Ставим Apache:

sudo apt install apache2

Правим /etc/apache2/ports.conf, говорим слушать все интерфейсы на порту 8080:

Listen 8080

В файле /etc/apache2/mods-enabled/dir.conf переносим index.php в начало списка. Также включаем пару дополнительных модулей:

sudo a2enmod rewrite remoteip headers expires

Первый нужен для корректной работы WordPress, второй — для перезаписи $_SERVER [ 'REMOTE_ADDR' ] при работе за прокси-сервером, последние два используются WP-SuperCache.

В конец файла /etc/apache2/apache2.conf дописываем:

<Directory /var/www/html/>
AllowOverride All
</Directory>

<IfModule mod_remoteip.c>
RemoteIPHeader X-Real-IP
</IfModule>

# не палим версию сервера
ServerTokens Prod
ServerSignature Off

… и перезапускаем сервер:

sudo systemctl restart apache2

Теперь на порту 8080 должны видеть страничку «Apache2 Ubuntu Default Page».

Далее ставим MySQL (или, как альтернативный вариант, MariaDB):

sudo apt install mysql-server mysql-client
mysql —user root —password

Сравниваем sql_mode на новом сервере и на старом хостинге:

mysql> select @@sql_mode;

Если они отличаются, стоит поменять sql_mode в файле /etc/mysql/my.cnf, например, так:

[ mysqld ]
sql_mode = «NO_ENGINE_SUBSTITUTION»

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

Перезапускаем MySQL:

sudo systemctl restart mysql

Далее создаем нового пользователя и базу, на которой будет работать сайт (лучше всего — такие же, что были на старом хостинге):

mysql> CREATE DATABASE eaxme;
mysql> CREATE USER ‘eaxme’@’localhost’ IDENTIFIED BY ‘pa55w0rd’;
mysql> GRANT ALL ON eaxme.* TO ‘eaxme’@’localhost’;
mysql> exit

Проверяем, что пользователь может подключиться к базе, создавать / удалять таблицы, и так далее:

mysql —user eaxme eaxme —password

Теперь ставим PHP и его расширения, необходимые для работы WordPress:

sudo apt install php5.6 libapache2-mod-php5.6
php5.6-mysql php5.6-curl php5.6-gd php5.6-mbstring
php5.6-mcrypt php5.6-xml php5.6-xmlrpc

Правим немного /etc/php/5.6/apache2/php.ini:

short_open_tag = On
# а также другие параметры при необходимости

Apache нужно рестартонуть, чтобы он гарантированно увидел все новые модули:

sudo systemctl restart apache2

Далее говорим:

sudo chown -R afiskon:www-data / var / www / html
echo ‘<? phpinfo(); ?>’ > / var / www / html / test.php

Пытаемся открыть test.php в браузере. Если все было сделано правильно, увидим классический вывод phpinfo ( ) . Не забываем удалить test.php:

rm / var / www / html / test.php

На этом с установкой и настройкой LAMP покончено. Настройка Nginx и HTTPS будет рассмотрена далее отдельно от LAMP.

PHP-функция mail()

Чтобы в PHP работала функция mail() , требуется выполнить кое-какие дополнительные шаги. Если вы точно знаете, что ваш сайт не использует эту функцию, сей раздел можно смело пропустить.

Ставим ssmtp:

sudo apt install ssmtp

Это простой консольный SMTP-клиент. Помимо прочего, он создает в системе символьную ссылку /usr/sbin/sendmail, которую использует функция mail() .

В файле /etc/ssmtp/ssmtp.conf указываем параметры подключения к STMP-серверу, и кое-какие дополнительные настройки:

root=noreply@remontka.com
mailhub=mail.remontka.com:25
hostname=localhost
UseSTARTTLS=YES
AuthUser=noreply@remontka.com
AuthPass=sup3r_pa$$word
FromLineOverride=YES

Проверяем, что письма отправляются:

echo -e «From: Noreply <noreply@remontka.com> n »
«To: Somebody <somebody@example.org> n »
«Subject: Test message from ssmtp n n »
«This is a test message» | ssmtp -v somebody @ example.org

Если работает, проверяем функцию mail() :

<?php

$to = «Somebody <somebody@example.org» ;
$subject = «Test e-amil» ;
$body = «Testing mail() function» ;
$headers = «From: Noreply <noreply@remontka.com>» ;

mail ( $to , $subject , $body , $headers ) ;

echo «<h1>OK!</h1>» ;
?>

Ну вот, теперь с чистой совестью можно двигаться дальше.

Переносим данные

Резервное копирование файлов при помощи tar, а также базы данных в MySQL при помощи mysqldump ранее были описаны в заметке Резервное копирование базы данных и файлов по SSH . Далее предполагается, что эти резервные копии у вас уже есть, и что они залиты на новый сервер.

Начнем с импорта базы данных:

zcat eaxme-db.sql.gz | mysql —user eaxme eaxme —password

На время отладки поменяем домашний URL сайта в настройках движка:

mysql> update eaxme_options
-> set option_value = ‘http://123.45.67.89:8080’
-> where option_value = ‘https://remontka.com’;

Распаковываем архив с файлами:

tar -xvzf eaxme-files.tgz
rm / var / www / html / index.html
mv remontka.com / docs /* / var / www / html
mv remontka.com / docs / .htaccess / var / www / html

В файле wp-config.php нужно поправить параметры подключения к БД, как минимум — имя хоста. Также может потребоваться поменять абсолютные пути в файле wp-content/advanced-cache.php.

Меняем права доступа к файлам и каталогам:

cd / var / www / html
sudo chown -R afiskon:www-data . /
chmod -R g+ w wp-content / cache
chmod -R g+ w wp-content
chmod g+ w sitemap.xml
chmod g+ w sitemap.xml.gz
# вместо используемого мной пути «files»
# по дэфолту в WordPress используется «wp-content/uploads»
chmod -R g+ w files

Для корректной работы отложенной публикации постов говорим crontab -e и вписываем такую строчку:

*/10 * * * * curl ‘https://remontka.com/wp-cron.php’

Проверяем работу сайта. Все должно работать корректно.

Nginx и HTTPS

На этом этапе желательно отключить любое кеширование страниц, в частности — плагин WP-SuperCache, так как в кэше сейчас лежат страницы с HTTP-ссылками. На всякий случай проверяем, что в каталоге wp-content/cache/supercache ничего не осталось. Все это нужно для того, чтобы после включения HTTPS не остаться без CSS, JavaScript и картинок, что потенциально может привести к невозможности попасть в админку сайта.

Ставим Nginx :

sudo apt install nginx

Переносим файлы .crt и .key со старого хостинга на новый сервер, куда-нибудь в /etc/ssl, а также переносим конфиг Nginx:

sudo mkdir / etc / ssl / remontka.com /
# (кладем в него site.crt и site.key)
# …

sudo rm / etc / nginx / sites-enabled / default
sudo vim / etc / nginx / sites-available / remontka.com.site.conf
# (переносим конфиг с шаред хостинга)
# …

sudo ln -s / etc / nginx / sites-available / remontka.com.site.conf
/ etc / nginx / sites-enabled / remontka.com.site.conf

Проверяем конфиг:

sudo service nginx configtest
# или: sudo nginx -t

Если все ОК:

sudo systemctl reload nginx

Меняем адрес сайта обратно:

mysql> update eaxme_options
-> set option_value = ‘https://remontka.com’
-> where option_value = ‘http://123.45.67.89:8080’;

В /var/www/html/.htaccess дописываем:

<IfModule mod_setenvif.c>
SetEnvIf X-Forwarded-Proto https HTTPS=on
SetEnvIf X-Request-Scheme  https HTTPS=on
</IfModule>

У себя на компьютере прописываем новый адрес сайта в /etc/hosts, проверяем, что все работает. Не забываем включить обратно WP-SuperCache. Правим файл /etc/apache2/ports.conf, чтобы Apache не торчал наружу:

Listen 127.0.0.1:8080

Проверяем, что наружу торчат только порты 22 (SSH), 80 и 443 (Nginx), а 3306 (MySQL) и 8080 (Apache) открыты только на 127.0.0.1:

sudo systemctl restart apache2
sudo netstat -tuwpln

Если все хорошо, убираем изменения, сделанные в /etc/hosts, и вносим соответствующие изменения в DNS. Если ваш VDS-провайдер также предоставляет DNS, и вы решили им воспользоваться, не забываем внести соответствующие изменения в whois на сайте вашего регистратора доменов. Затем терпеливо ждем, пока всех посетителей не перкинет на новый сайт. Это будет видно по логам Nginx на старом хостинге и на новом сервере.

По окончании переезда можно сменить старого CA на Let’s Encrypt, введя пару команд из заметки Настройка HTTPS с сертификатами Let’s Encrypt . Также не забудьте поправить скрипты для резервного копирования сайта!

Заключение

Как видите, при переносе сайта было собрано не так уж и много граблей. По времени переезд занял где-то один вечер. Эта статья была написана уже после переезда и опубликована автоматически по расписанию. Так что, видимо, перенос можно считать успешным. Субъективно на VDS сайт работает существенно быстрее, что не может не радовать.

Дополнение: Поднимаем собственный почтовый сервер на VDS

EnglishRussianUkrainian