I often launch small services on different platforms and programming languages. I usually use the simplest and most suitable technologies for a specific case — and everything works without problems until they gain enough popularity.
Recently, I needed to create a multilingual website with a blog for a Node.js service. I build such sites on WordPress — I have my own custom build for this. But the domain for the service and the site must be the same: people come from search results to blog articles, then navigate to the service, and all this traffic should accumulate on one domain. If you separate them across different domains, the weight will be diluted instead of strengthening each other.
What I Did
- Moved the service to my own server
- Installed and configured my WordPress build
- Configured the Apache config to properly direct the domain to both services
The Node.js service has a limited number of pages, while the WordPress editor will constantly create new posts. Therefore, I gathered all the service endpoints and configured Apache to proxy them to 127.0.0.1:3001 — the local port where Node.js is running. Everything else goes to WordPress via DocumentRoot.
SSL
It works without problems because both services are on a server we manage. The certificate is issued via Certbot — it automatically updates the Apache config and adds the redirect from HTTP to HTTPS.
Config Example
This is for Apache; it works similarly on 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
# Main → Node.js
RewriteRule "^/?$" "http://127.0.0.1:3001/" [P,L]
# Node.js paths
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
# ... other service endpoints
# Everything else → WordPress (via DocumentRoot)
</VirtualHost>
