WordPress

Как подключить домен и HTTPS к WordPress на VPS

Продолжаем установку WordPress: DNS, сертификат Let's Encrypt, Nginx с PHP, смена локального URL на домен и проверка индексации. С копией перед изменениями.

Как подключить домен и HTTPS к WordPress на VPS

После установки WordPress нашим скриптом сайт доступен через SSH-туннель. Теперь подключим домен, выпустим сертификат и заменим локальный адрес в WordPress на публичный HTTPS-адрес.

Инструкция рассчитана на созданные установщиком Nginx, PHP 8.3 и отдельный пул сайта. Для WordPress, установленного из панели общего хостинга, используйте инструменты этой панели.

Подготовьте параметры и копию

Ниже пример для технического имени myblog и порта 18080. Замените домен и email. Команды этого руководства выполняются на VPS в одной root-сессии:

sudo -i
SITE=myblog
PORT=18080
DOMAIN=example.com
EMAIL=your.name@example.com
WEBROOT=/var/www/hostfera-$SITE
ACCOUNT=hfwp_$SITE
PUBLIC=/etc/nginx/sites-available/hostfera-$SITE-public
WPCLI=/usr/local/lib/hostfera/wp-cli-2.12.0.phar
wp_site() { (cd "$WEBROOT" && runuser -u "$ACCOUNT" -- php "$WPCLI" --path="$WEBROOT" "$@"); }
umask 077
BACKUP=/root/hostfera-$SITE-before-domain-$(date +%Y%m%d-%H%M%S)
mkdir -m 700 "$BACKUP"
wp_site db export - > "$BACKUP/database.sql"
tar -czf "$BACKUP/files.tar.gz" -C "$WEBROOT" .

Копия находится вне веб-каталога и включает файлы с конфигурацией. Для постоянного резервирования нужна также независимая копия вне VPS и проверка восстановления. Не заменяйте копию MariaDB примером SQLite из другой инструкции.

Привяжите домен

В DNS-панели создайте A-запись выбранного имени на публичный IPv4 вашего VPS. Если хотите использовать www, настройте его отдельно и добавьте это имя в сертификат и Nginx. В данном примере используется только один домен.

Если существует AAAA-запись, IPv6 должен вести на этот же работающий сайт. Устаревшая AAAA-запись может отправить часть посетителей и проверку сертификата на другой сервер. Подробности панелей разобраны в гайде о домене.

Проверьте DNS с компьютера, а не только на VPS:

nslookup example.com

Ожидаемый адрес — ваш VPS. Для выпуска сертификата по HTTP-01 порт 80 должен быть доступен извне. Сохраните SSH-доступ, если меняете правила UFW.

Подготовьте HTTP-проверку сертификата

Создайте отдельный публичный виртуальный хост. Локальная конфигурация установщика продолжит работать. Если файл $PUBLIC уже существует, сначала изучите его; не перезаписывайте неизвестный сайт.

test ! -e "$PUBLIC" || { echo 'Файл уже существует: сначала изучите его.'; exit 1; }
cat > "$PUBLIC" <<NGINX
server {
    listen 80;
    server_name $DOMAIN;
    root $WEBROOT;
    location ^~ /.well-known/acme-challenge/ { try_files \$uri =404; }
    location / { return 503; }
}
NGINX
chmod 644 "$PUBLIC"
ln -s "$PUBLIC" /etc/nginx/sites-enabled/hostfera-$SITE-public
nginx -t
systemctl reload nginx

Сейчас на домене намеренно отдаётся 503, кроме пути проверки ACME. WordPress пока не переносился: в его базе ещё локальный адрес. Это промежуточное состояние до готовности HTTPS.

Получите сертификат

apt-get update
apt-get install -y certbot
certbot certonly --webroot -w "$WEBROOT" \
  --cert-name "hostfera-$SITE" -d "$DOMAIN" \
  --email "$EMAIL" --agree-tos --non-interactive

Указывайте собственную рабочую почту и запускайте команду после ознакомления с условиями Let's Encrypt. При успешном выпуске проверьте наличие файлов:

test -s /etc/letsencrypt/live/hostfera-$SITE/fullchain.pem
test -s /etc/letsencrypt/live/hostfera-$SITE/privkey.pem

Если сертификат не выпущен, сначала исправьте DNS, доступность порта 80 или ACME-пути. Не включайте HTTPS-конфигурацию с отсутствующими файлами. Общее руководство по SSL содержит дополнительные проверки причин ошибки.

Включите HTTPS с обработкой PHP

Сохраните промежуточную конфигурацию и замените её следующей. В отличие от простого статического сайта, WordPress нужен PHP-обработчик и передача неизвестных путей в index.php.

cp "$PUBLIC" "$BACKUP/nginx-http.conf"
cat > "$PUBLIC" <<NGINX
server {
    listen 80;
    server_name $DOMAIN;
    root $WEBROOT;
    location ^~ /.well-known/acme-challenge/ { try_files \$uri =404; }
    location / { return 301 https://$DOMAIN\$request_uri; }
}
server {
    listen 443 ssl;
    server_name $DOMAIN;
    ssl_certificate /etc/letsencrypt/live/hostfera-$SITE/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/hostfera-$SITE/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    root $WEBROOT;
    index index.php;
    client_max_body_size 40m;
    add_header X-Content-Type-Options nosniff always;
    location / { try_files \$uri \$uri/ /index.php?\$args; }
    location = /xmlrpc.php { deny all; }
    location = /wp-config.php { deny all; }
    location ~ /\. { deny all; }
    location ~* ^/wp-content/uploads/.*\.(?:php[0-9]?|phtml|phar)(?:/|$) { deny all; }
    location ~* \.(?:sql|log|bak|ini|conf)$ { deny all; }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/hostfera-$SITE.sock;
        fastcgi_hide_header X-Powered-By;
    }
}
NGINX
chmod 644 "$PUBLIC"
nginx -t
systemctl reload nginx

Если nginx -t завершился ошибкой, не выполняйте reload: исправьте указанный файл либо верните сохранённую HTTP-конфигурацию. Когда проверка прошла, сначала проверьте сертификат и ответ https://example.com. До следующего шага WordPress может перенаправлять на локальный адрес — это ожидаемо.

Замените адрес в WordPress

Сначала посмотрите, какие значения будут изменены:

OLD_URL=http://127.0.0.1:$PORT
NEW_URL=https://$DOMAIN
wp_site search-replace "$OLD_URL" "$NEW_URL" \
  --all-tables-with-prefix --skip-columns=guid --precise --dry-run

Если старый и новый адреса верны, выполните замену:

wp_site search-replace "$OLD_URL" "$NEW_URL" \
  --all-tables-with-prefix --skip-columns=guid --precise
wp_site option update home "$NEW_URL"
wp_site option update siteurl "$NEW_URL"
wp_site config set FORCE_SSL_ADMIN true --raw
wp_site config set WP_ENVIRONMENT_TYPE production
wp_site rewrite flush
wp_site option get home
wp_site option get siteurl

WP-CLI учитывает сериализованные настройки; обычная строковая замена по SQL-файлу может их повредить. Параметр --all-tables-with-prefix включает дополнительные таблицы именно этого сайта. Для multisite нужна отдельная схема переноса.

Файл с первоначальными данными входа сохраняет старый локальный URL. После переноса открывайте https://example.com/wp-admin/; логин и пароль остаются прежними. SSH-туннель больше не нужен для обычного доступа.

Проверьте страницы и продление

Откройте главную, запись с изображением, /wp-admin/ и постоянную ссылку на запись. На HTTP должен быть переход к HTTPS. Убедитесь, что браузер не показывает смешанный контент, а изображения и стили загружаются с публичного адреса. Для Community отдельно проверьте вход, отправку поста и комментарий.

Подготовьте reload Nginx после обновления сертификата:

install -d -m 755 /etc/letsencrypt/renewal-hooks/deploy
HOOK=/etc/letsencrypt/renewal-hooks/deploy/hostfera-$SITE-nginx
test ! -e "$HOOK" || { echo 'Hook уже существует: проверьте его содержимое.'; exit 1; }
cat > "$HOOK" <<'SH'
#!/bin/sh
set -e
nginx -t
systemctl reload nginx
SH
chmod 755 "$HOOK"
systemctl enable --now certbot.timer
certbot renew --cert-name "hostfera-$SITE" --dry-run --run-deploy-hooks
systemctl list-timers certbot.timer

Проверяйте существующие hooks перед созданием, если Certbot уже обслуживает другие сайты. Не заменяйте неизвестный файл своим вариантом. Успешный dry-run подтверждает пробное продление в текущих условиях, но за сроком сертификата и ошибками таймера нужно следить дальше.

Разрешите индексацию, когда сайт готов

Установщик оставляет blog_public=0. Если настройка и содержимое готовы к публичному выпуску, снимите запрет в «Настройки → Чтение» или выполните:

wp_site option update blog_public 1

Откройте страницы без входа администратора, проверьте HTML robots и HTTP-заголовки. Локальный виртуальный хост установщика по-прежнему добавляет noindex; публичный хост из этой статьи такой заголовок не задаёт. Проверьте /wp-sitemap.xml либо карту используемого SEO-плагина.

В нашем испытании PHP-конфигурация и смена URL проверены на отдельной установке с локальным тестовым именем и доверенным тестовым сертификатом. Новый публичный домен и сертификат Let's Encrypt для этого WordPress не заказывались; внешний выпуск и dry-run нужно выполнить для своего домена. Проверка после запуска поможет завершить работу.

Первоисточники

Нашли неточность?

Сообщите адрес статьи и фрагмент через контакты редакции.