Проблема: WordPress заперт на localhost

Разработка WordPress на localhost удобна — до тех пор, пока не нужно показать результат кому-то ещё. Клиент не может открыть ваш http://localhost:8080. Платёжные шлюзы не могут отправить вебхуки на 127.0.0.1. Плагин, использующий внешние OAuth-коллбэки, не имеет публичного URL для редиректа. А деплоить на staging-сервер после каждого изменения CSS — пустая трата времени.

Помимо этого, у WordPress есть уникальная проблема: он хардкодит свой URL в базе данных. Опции siteurl и home определяют, как WordPress генерирует ссылки, подключает ассеты и обрабатывает редиректы. Если вы просто направите туннель на локальный WordPress без обновления этих значений, сайт сломается — стили не загрузятся, ссылки будут вести на localhost, а админ-панель станет недоступна.

В этой статье мы покажем, как правильно настроить связку localhost + туннель для WordPress: сконфигурировать WP_HOME и WP_SITEURL, протестировать плагины и темы с реальным трафиком, показать сайт клиенту и отладить вебхуки WooCommerce — всё без деплоя.

Решение: туннель с правильной конфигурацией WordPress

fxTunnel создаёт публичный HTTPS-адрес для вашего локального WordPress одной командой. В сочетании с двумя строками в wp-config.php вы получаете полностью рабочий WordPress-сайт, доступный из любой точки интернета.

Рабочий процесс:

  1. Запускаете WordPress локально (XAMPP, Docker, wp-env, Local — что угодно).
  2. Создаёте туннель командой fxtunnel http 8080.
  3. Устанавливаете WP_HOME и WP_SITEURL на URL туннеля.
  4. Открываете URL туннеля в браузере — WordPress работает с полноценным HTTPS.

Если вы впервые работаете с туннелями, в статье «Что такое туннелирование» разобраны основы.

Пошаговый гайд: WordPress + fxTunnel

Шаг 1. Установка fxTunnel

# Быстрая установка (Linux/macOS)
curl -fsSL https://fxtun.dev/install.sh | bash

# Или через go install
go install github.com/mephistofox/fxtun.dev/cmd/fxtunnel@latest

# Проверяем, что всё работает
fxtunnel --version

Шаг 2. Запуск локального WordPress

Используйте любую удобную среду разработки. Вот самые популярные варианты:

Docker Compose (рекомендуется):

# docker-compose.yml
version: '3.8'
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp-content:/var/www/html/wp-content

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:
docker compose up -d
# -> WordPress запущен на http://localhost:8080

wp-env (для разработки плагинов/тем):

# Устанавливаем wp-env глобально
npm install -g @wordpress/env

# Запускаем WordPress в директории плагина/темы
wp-env start
# -> WordPress запущен на http://localhost:8888

XAMPP / MAMP / Local by Flywheel: запускайте среду как обычно и запомните порт.

Шаг 3. Создание туннеля

# Открываем туннель к порту WordPress
fxtunnel http 8080

Результат:

fxTunnel v1.x — tunnel is active
Public URL:  https://wp-demo.fxtun.dev
Forwarding:  https://wp-demo.fxtun.dev -> http://localhost:8080

Теперь https://wp-demo.fxtun.dev указывает на ваш локальный WordPress. Но если вы откроете этот URL прямо сейчас, WordPress, скорее всего, перенаправит вас на localhost:8080 или загрузится без стилей. Причина — проблема с siteurl и home. Давайте её решим.

Шаг 4. Настройка WP_HOME и WP_SITEURL

Откройте wp-config.php и добавьте две строки перед строкой /* That's all, stop editing! */:

// wp-config.php — добавьте эти строки для доступа через туннель
define('WP_HOME', 'https://wp-demo.fxtun.dev');
define('WP_SITEURL', 'https://wp-demo.fxtun.dev');

Эти константы переопределяют значения из базы данных. WordPress теперь будет генерировать все ссылки, загружать все ассеты и обрабатывать все редиректы, используя URL туннеля.

Динамическая конфигурация (лучше для разработки)

Если вы не хотите каждый раз редактировать wp-config.php при перезапуске туннеля (или если вы часто переключаетесь между локальным и туннельным доступом), используйте динамический подход:

// wp-config.php — динамический URL на основе запроса
if (isset($_SERVER['HTTP_HOST'])) {
    $scheme = (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
        ? 'https'
        : (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http');
    $host = $_SERVER['HTTP_HOST'];
    define('WP_HOME', "{$scheme}://{$host}");
    define('WP_SITEURL', "{$scheme}://{$host}");
}

Этот сниппет считывает имя хоста и протокол из входящего запроса. Когда вы обращаетесь к сайту через туннель, WordPress использует URL туннеля. Когда заходите напрямую через localhost:8080 — использует localhost:8080. Никаких ручных изменений не нужно.

Почему важен X-Forwarded-Proto

fxTunnel терминирует TLS на сервере туннеля и перенаправляет запросы на ваш локальный WordPress по обычному HTTP. WordPress видит HTTP, а не HTTPS. Без проверки HTTP_X_FORWARDED_PROTO WordPress может генерировать ссылки с http://, хотя клиент подключён через https://. Динамический сниппет выше решает эту проблему автоматически.

Также добавьте это в wp-config.php, если WordPress работает за реверс-прокси (а туннель — это фактически реверс-прокси):

// Доверяем заголовку X-Forwarded-Proto от туннеля
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Шаг 5. Проверяем, что всё работает

Откройте https://wp-demo.fxtun.dev в браузере. Вы должны увидеть:

  • Зелёный замочек (валидный HTTPS-сертификат).
  • Вашу WordPress-тему со всеми загруженными стилями.
  • Рабочую навигацию — все ссылки ведут на https://wp-demo.fxtun.dev/....
  • Админ-панель по адресу https://wp-demo.fxtun.dev/wp-admin/ корректно загружается.

Если что-то не так — смотрите раздел «Troubleshooting» ниже.

Сценарий 1: демонстрация клиенту без деплоя

Показать WordPress-сайт клиенту обычно означает деплой на staging-сервер — загрузка файлов, миграция базы данных, исправление URL, настройка SSL. С туннелем всё это можно пропустить.

Рабочий процесс прост:

  1. Доводите сайт до нужного состояния на локальной машине.
  2. Запускаете fxtunnel http 8080.
  3. Устанавливаете WP_HOME и WP_SITEURL на URL туннеля (или используйте динамический сниппет).
  4. Отправляете ссылку клиенту.

Клиент видит именно то, что у вас на экране — ту же тему, тот же контент, те же плагины. Вы вносите изменения, клиент обновляет страницу. Никакого цикла деплоя, никаких расходов на staging-сервер.

Больше сценариев демонстрации — в статье «Как показать локальный проект клиенту без деплоя».

Кастомный домен для профессиональных демонстраций

Ссылка https://wp-demo.fxtun.dev работает, но https://preview.clientsite.com выглядит профессиональнее. Кастомные домены доступны от $5/мес.

fxtunnel http 8080 --domain preview.clientsite.com

Обновите wp-config.php соответственно:

define('WP_HOME', 'https://preview.clientsite.com');
define('WP_SITEURL', 'https://preview.clientsite.com');

Сценарий 2: тестирование плагинов и тем с реальным трафиком

Пробовали тестировать OAuth-плагин авторизации на localhost? Не получится — публичного URL для редиректа просто нет. Та же история с платёжными шлюзами, кнопками соцсетей, встраиванием контента и интеграциями с CDN. Туннель даёт публичный URL без деплоя.

Тестирование OAuth-плагинов

Плагины вроде Nextend Social Login, WP Social Login или Login with Google требуют OAuth redirect URI. На localhost зарегистрировать валидный редирект невозможно. С туннелем:

fxtunnel http 8080
# -> https://wp-demo.fxtun.dev

Зарегистрируйте https://wp-demo.fxtun.dev/wp-admin/admin-ajax.php (или другой URL, который использует плагин) как redirect URI в настройках OAuth-провайдера (Google, Facebook, GitHub). Поток авторизации работает целиком на вашей локальной машине. Этот паттерн подробно разобран в статье «OAuth Callback на localhost».

Тестирование SEO и соцсетей

Когда вы делитесь страницей WordPress в соцсетях, платформы (Facebook, Twitter, LinkedIn) запрашивают Open Graph мета-теги по URL. На localhost они не могут добраться до вашего сайта. Через туннель публичный URL доступен — можно проверить, как выглядят ваши страницы при расшаривании.

# Тестируем Open Graph теги
curl -A "facebookexternalhit/1.1" https://wp-demo.fxtun.dev/sample-page/

Тестирование Cron и запланированных задач

WordPress использует wp-cron.php, который срабатывает при посещении страницы. Некоторые разработчики используют внешние cron-сервисы, которые вызывают wp-cron.php через HTTP. Через туннель эти сервисы могут добраться до вашего локального WordPress:

# Внешний cron-сервис теперь может обращаться по этому URL
# https://wp-demo.fxtun.dev/wp-cron.php?doing_wp_cron

Сценарий 3: тестирование вебхуков WooCommerce

WooCommerce использует вебхуки для уведомления внешних систем о заказах, платежах, изменениях остатков и событиях клиентов. При разработке кастомной интеграции — например, синхронизации заказов с ERP или отправки уведомлений в Slack — необходимо тестировать вебхуки с реальными данными. На localhost у WooCommerce нет публичного URL для доставки вебхуков.

Настройка вебхуков WooCommerce через туннель

# Запускаем туннель
fxtunnel http 8080
# -> https://wp-demo.fxtun.dev
  1. Откройте WooCommerce -> Настройки -> Дополнительно -> Вебхуки в админ-панели WordPress.
  2. Нажмите Добавить вебхук.
  3. Название: Тестовый вебхук заказов.
  4. Статус: Активен.
  5. Тема: Заказ создан.
  6. URL доставки: https://wp-demo.fxtun.dev/wp-json/custom/v1/order-hook (или ваш внешний эндпоинт через туннель).
  7. Секрет: сгенерируйте секрет для проверки подписи.
  8. Сохраните.

Теперь создайте тестовый заказ в WooCommerce. Вебхук сработает и отправит запрос на URL доставки — туннель перенаправит его на ваш локальный обработчик.

Пример обработчика вебхуков

Если ваш эндпоинт для вебхуков находится на том же локальном WordPress (например, кастомный эндпоинт плагина), можно протестировать весь цикл:

// В вашем плагине — регистрация REST API эндпоинта для вебхука
add_action('rest_api_init', function () {
    register_rest_route('custom/v1', '/order-hook', [
        'methods'  => 'POST',
        'callback' => 'handle_woo_webhook',
        'permission_callback' => '__return_true',
    ]);
});

function handle_woo_webhook(WP_REST_Request $request) {
    $payload = $request->get_json_params();
    $signature = $request->get_header('X-WC-Webhook-Signature');

    // Проверка подписи
    $secret = 'your_webhook_secret';
    $expected = base64_encode(hash_hmac('sha256', $request->get_body(), $secret, true));

    if ($signature !== $expected) {
        return new WP_REST_Response(['error' => 'Invalid signature'], 401);
    }

    // Логируем данные вебхука
    error_log('WooCommerce вебхук получен: ' . wp_json_encode($payload));

    // Обрабатываем заказ
    $order_id = $payload['id'] ?? null;
    $status = $payload['status'] ?? 'unknown';
    error_log("Заказ #{$order_id} — статус: {$status}");

    return new WP_REST_Response(['received' => true], 200);
}

Внешний приёмник вебхуков

Если ваш приёмник вебхуков — отдельное приложение (Node.js, Python и т.д.), работающее на другом порту, откройте второй туннель:

# Терминал 1 — WordPress
fxtunnel http 8080
# -> https://wp-demo.fxtun.dev

# Терминал 2 — приёмник вебхуков (Node.js на порту 3000)
fxtunnel http 3000
# -> https://hook-receiver.fxtun.dev

Используйте https://hook-receiver.fxtun.dev/webhook как URL доставки в WooCommerce. Или, если оба сервиса работают локально, можно указать http://localhost:3000/webhook как URL доставки и обойтись без второго туннеля — но первый туннель всё равно нужен для доступа к админ-панели WooCommerce.

Отладка вебхуков через Inspector

Inspector в fxTunnel (от $5/мес) показывает каждый HTTP-запрос, проходящий через туннель — заголовки, тело, код ответа. Это незаменимо при отладке вебхуков: вы видите, что именно отправил WooCommerce и как ответил ваш обработчик. Replay позволяет повторить любой запрос одним кликом, так что не нужно создавать новый тестовый заказ каждый раз.

В статье «Тестирование вебхуков через туннель» разобран весь процесс подробнее.

Сценарий 4: Multisite и командная разработка

WordPress Multisite

WordPress Multisite использует доменные или поддиректорийные URL для каждого подсайта. Через туннель можно тестировать основной сайт, но подсайты требуют дополнительной настройки. Самый простой подход — Multisite на основе поддиректорий:

// wp-config.php для Multisite через туннель
define('WP_HOME', 'https://wp-demo.fxtun.dev');
define('WP_SITEURL', 'https://wp-demo.fxtun.dev');
define('DOMAIN_CURRENT_SITE', 'wp-demo.fxtun.dev');

Поддиректорийные подсайты (https://wp-demo.fxtun.dev/site2/) будут работать через туннель без дополнительной настройки.

Работа с другими разработчиками

Когда двум разработчикам нужно протестировать интеграцию (например, фронтенд-разработчику нужен WordPress REST API), бэкенд-разработчик открывает туннель и делится URL:

# Бэкенд-разработчик
fxtunnel http 8080
# -> https://wp-api.fxtun.dev

# Фронтенд-разработчик использует API
curl https://wp-api.fxtun.dev/wp-json/wp/v2/posts

Фронтенд-разработчик может указать https://wp-api.fxtun.dev как базовый URL API в своём React или Vue приложении и протестировать полную интеграцию без деплоя.

Локальные среды разработки: сравнение с поддержкой туннелей

Разные локальные WordPress-среды используют разные порты и конфигурации. Вот как они работают с fxTunnel:

СредаПорт по умолчаниюКоманда туннеляПримечания
Docker Compose8080 (настраивается)fxtunnel http 8080Максимальная гибкость, полный контроль над версиями PHP/MySQL
wp-env8888fxtunnel http 8888Официальный инструмент WordPress, идеален для разработки плагинов
XAMPP80fxtunnel http 80Классический стек, работает на Windows/macOS/Linux
MAMP8888fxtunnel http 8888Популярен на macOS, есть GUI
Local (Flywheel)варьируетсяfxtunnel http <порт>GUI-приложение, проверьте порт в настройках сайта
Landoварьируетсяfxtunnel http <порт>На основе Docker, проверьте lando info для порта
Laravel Valet80 (через домен .test)fxtunnel http 80Лёгкий вариант, только macOS

Troubleshooting: частые проблемы WordPress + туннель

Большинство проблем связаны с тремя вещами: несоответствие WP_HOME/WP_SITEURL, путаница HTTPS/HTTP или локальный сервер не запущен. Используйте таблицу ниже для быстрой диагностики.

ПроблемаПричинаРешение
Зацикленный редирект на localhostWP_HOME/WP_SITEURL всё ещё указывают на localhostОбновите wp-config.php, указав URL туннеля
Стили и скрипты не загружаютсяMixed content (HTTP-ассеты на HTTPS-странице)Добавьте фикс $_SERVER['HTTPS'] = 'on' для X-Forwarded-Proto
Админ-панель недоступнаWP_SITEURL не совпадает с URL туннеляУстановите WP_SITEURL точно на URL туннеля, включая https://
Ошибка «Too many redirects»WordPress принудительно перенаправляет на HTTPS, туннель повторно перенаправляетДобавьте $_SERVER['HTTPS'] = 'on' при X-Forwarded-Proto = https
Изображения с битыми URLwp_get_attachment_url возвращает localhost URLWP_HOME должен совпадать с URL туннеля
REST API возвращает 401Несовпадение nonce из-за смены доменаВыйдите из системы и войдите заново через URL туннеля
Вебхук WooCommerce не работаетURL доставки всё ещё указывает на localhostОбновите URL доставки вебхука на URL туннеля
Медленная загрузка страницБольшой сайт с множеством ассетовНормально — ассеты проходят через туннель. Используйте кэширование браузера

Фикс для определения HTTPS

Если WordPress-плагины или темы проверяют is_ssl() и получают false из-за того, что туннель пересылает HTTP, добавьте это в начало wp-config.php:

// Фикс определения SSL за туннелем/реверс-прокси
if (
    (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') ||
    (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on')
) {
    $_SERVER['HTTPS'] = 'on';
}

WordPress-туннель vs staging-сервер: когда что использовать

Туннель не заменяет staging-сервер — он дополняет его. Используйте туннель во время активной разработки и для быстрых демонстраций. Staging — для длительного QA, приёмочного тестирования клиентом и предпродакшен-проверки.

КритерийfxTunnelStaging-сервер
Время настройки30 секундОт 30 минут до нескольких часов
СтоимостьБесплатно (кастомный домен от $5/мес)$5-50/мес за хостинг
HTTPSАвтоматический, валидный сертификатНужен Let’s Encrypt или ручная настройка
Актуальность данныхВсегда актуальные (live localhost)Снимок с последнего деплоя
Совместная работаОдин разработчик за раз (его машина)Общий, доступен всей команде
ДоступностьПока туннель запущенВсегда доступен
ПроизводительностьЗависит от машины + сетиЗависит от характеристик сервера
Лучше всего дляРазработки, быстрых демо, тестирования вебхуковQA, приёмочного тестирования, предпродакшена

Сравнение других методов демонстрации — в статье «Как показать проект без деплоя».

Лучшие практики для разработки WordPress + туннель

1. Используйте динамический сниппет WP_HOME

Не хардкодьте URL туннеля — используйте динамический сниппет из Шага 4. Так вы сможете переключаться между localhost и URL туннеля без редактирования конфигурации.

2. Защитите wp-admin

Когда ваш WordPress-сайт доступен публично через туннель, wp-admin тоже доступен. Используйте надёжные пароли и рассмотрите добавление HTTP Basic-авторизации:

// .htaccess — базовая авторизация для wp-admin (Apache)
<Files wp-login.php>
  AuthType Basic
  AuthName "Restricted"
  AuthUserFile /path/to/.htpasswd
  Require valid-user
</Files>

3. Используйте тестовые данные

Никогда не демонстрируйте WordPress-сайт с реальными данными клиентов. Используйте FakerPress или WP CLI для генерации тестового контента:

# Генерируем тестовые записи через WP CLI
wp post generate --count=20 --post_type=post --post_status=publish
wp user generate --count=5 --role=subscriber

4. Закрывайте туннель после использования

Нажмите Ctrl+C, когда демонстрация или тестирование завершены. Не оставляйте туннель запущенным на ночь с WordPress-сайтом — wp-admin будет доступен любому, кто знает URL.

5. Используйте Inspector для отладки

Inspector в fxTunnel (от $5/мес) особенно полезен с WordPress, потому что WordPress отправляет множество внутренних HTTP-запросов (вызовы REST API, cron, проверка обновлений). Inspector позволяет увидеть их все и быстро обнаружить неправильно настроенные URL или неудавшиеся запросы.

Почему fxTunnel для разработки WordPress

WordPress-сайты грузят много ассетов на каждую страницу, поэтому важно, чтобы туннель не ограничивал трафик. Встроенный HTTPS с валидным сертификатом означает, что HTTPS-функции WordPress (Secure Cookies, is_ssl(), принудительный SSL в админке) корректно работают через туннель. URL остаётся постоянным между перезапусками, поэтому не нужно обновлять wp-config.php каждый раз.

ВозможностьfxTunnelДругие инструменты
Бесплатный тарифБез ограничений на трафик и подключенияЧасто ограничен по времени, запросам или трафику
HTTPS-сертификатВалидный, автоматический — без предупреждений браузераАналогично у большинства инструментов
Стабильный URLОдин и тот же URL между перезапусками (бесплатный тариф)Часто случайный на бесплатных тарифах
Inspector + ReplayОт $5/мес — просмотр всех запросов, повтор одним кликомОтсутствует или требует отдельной настройки
Кастомный доменОт $5/мес, до 5 туннелейДороже или недоступно
10+ туннелейОт $10/месЗначительно дороже
Open sourceДа — github.com/mephistofox/fxtun.devЧасто проприетарный

Все три инструмента мы подробно сравниваем в статье «ngrok vs Cloudflare vs fxTunnel».

FAQ

Почему WordPress ломается при открытии через туннель?

Всё дело в том, что WordPress хранит URL в базе данных (опции siteurl и home). Если адрес туннеля не совпадает с сохранённым — начинаются циклические редиректы, стили не грузятся, ссылки ведут не туда. Чтобы это исправить, задайте WP_HOME и WP_SITEURL в wp-config.php на URL туннеля или используйте динамический сниппет из Шага 4, который подстраивается автоматически.

Можно ли показать WordPress-сайт клиенту через туннель?

Да, и это занимает минуту. Запускаете локальный WordPress, открываете туннель командой fxtunnel http 8080, убеждаетесь, что WP_HOME и WP_SITEURL указывают на URL туннеля, и отправляете ссылку клиенту. Он видит вашу тему, плагины и контент ровно в том состоянии, в каком они на вашей машине. По завершении Ctrl+C всё закрывает.

Как тестировать вебхуки WooCommerce на localhost?

Откройте туннель командой fxtunnel http 8080 и вставьте URL туннеля как URL доставки в настройках вебхуков WooCommerce. Когда сработает событие (заказ создан, оплата завершена и т.д.), WooCommerce отправит данные через туннель на ваш локальный обработчик. Inspector (от $5/мес) позволяет просматривать каждый запрос и повторять его. Подробнее — в статье «Тестирование вебхуков через туннель».

URL туннеля меняется при перезапуске?

Нет. fxTunnel SaaS сохраняет URL между перезапусками, даже на бесплатном тарифе. С кастомным доменом (от $5/мес) адрес полностью под вашим контролем — например, dev.yoursite.com. Трогать wp-config.php или настройки вебхуков после перезапуска не придётся.

Безопасно ли открывать WordPress-сайт для разработки через туннель?

Для разработки и коротких демо — да. Весь трафик шифруется TLS. Со своей стороны работайте с тестовыми данными, защитите wp-admin надёжным паролем и закрывайте туннель по окончании сессии. Продакшен-сайт WordPress через туннель подключать не стоит.