Как разместить разные сервисы на одном домене: пример с Node.js и PHP

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

Недавно понадобилось для сервиса на Node.js сделать мультиязычный сайт с блогом. Такие сайты я делаю на WordPress — у меня есть для этого собственная сборка. Но домен у сервиса и сайта должен быть один: люди приходят из поиска на статьи блога, переходят на сервис, и весь этот трафик должен накапливаться на одном домене. Если разнести по разным доменам — вес будет размазываться, а не усиливать друг друга.

Что делал

  1. Перенёс сервис на собственный сервер
  2. Поставил и настроил свою WordPress-сборку
  3. Настроил Apache-конфиг, правильно направив домен на оба сервиса

У Node.js сервиса ограниченное количество страниц, а на WordPress редактор будет постоянно создавать новые статьи. Поэтому я собрал все эндпоинты сервиса и в Apache прописал, чтобы они проксировались на 127.0.0.1:3001 — локальный порт, где крутится Node.js. Всё остальное идёт на WordPress через DocumentRoot.

SSL

Работает без проблем, потому что оба сервиса находятся на сервере, которым мы управляем. Сертификат выдаётся через Certbot — он сам обновляет конфиг Apache и добавляет редирект с HTTP на HTTPS.

Пример конфига

Это для Apache, на Nginx всё работает похожим образом.

<VirtualHost *:443>
    ServerName example.com

    # SSL
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    # WordPress
    DocumentRoot /var/www/wordpress

    <Directory /var/www/wordpress>
        AllowOverride All
        Require all granted
    </Directory>

    RewriteEngine On

    # Главная → Node.js
    RewriteRule "^/?$" "http://127.0.0.1:3001/" [P,L]

    # Node.js пути
    ProxyPass /api/ http://127.0.0.1:3001/api/
    ProxyPassReverse /api/ http://127.0.0.1:3001/api/
    ProxyPass /watch http://127.0.0.1:3001/watch
    ProxyPassReverse /watch http://127.0.0.1:3001/watch
    # ... остальные эндпоинты сервиса

    # Всё остальное → WordPress (через DocumentRoot)
</VirtualHost>
keyboard_arrow_up