How to Map Custom Domain Names to Localhost Ports for Node.js Development on macOS


1 views

When working with multiple Node.js applications locally (like Harp.js and Sails.js projects), you often need to run them on different ports. However, many web applications expect to run on standard domains without port numbers in the URL. Here's how to solve this on macOS.

The simplest approach is to modify your system's hosts file to point your custom domains to localhost:

sudo nano /etc/hosts

Add these lines at the bottom:

127.0.0.1   dev.hostOne.com
127.0.0.1   dev.hostTwo.com

For more flexibility, you can use Nginx as a reverse proxy:

brew install nginx

Then edit the Nginx configuration:

sudo nano /usr/local/etc/nginx/nginx.conf

Add these server blocks:

server {
    listen 80;
    server_name dev.hostOne.com;
    location / {
        proxy_pass http://localhost:123;
    }
}

server {
    listen 80;
    server_name dev.hostTwo.com;
    location / {
        proxy_pass http://localhost:456;
    }
}

For more advanced setups, dnsmasq can handle wildcard domains:

brew install dnsmasq

Configure dnsmasq:

echo "address=/dev/127.0.0.1" >> /usr/local/etc/dnsmasq.conf

After making changes, test with:

ping dev.hostOne.com
curl -I http://dev.hostOne.com

Remember to restart services after configuration changes:

sudo brew services restart nginx
sudo brew services restart dnsmasq

For Node.js developers, you can programmatically check the host header:

app.use((req, res, next) => {
    if(req.hostname === 'dev.hostOne.com') {
        // Special handling for this domain
    }
    next();
});

When working with multiple Node.js servers (like Harp.js and Sails.js) that need to run simultaneously, using distinct domain names instead of raw port numbers makes your development environment mirror production setups. Here's how to implement this properly on macOS.

The most straightforward method is modifying the /etc/hosts file. Open Terminal and run:

sudo nano /etc/hosts

Add these entries at the bottom:

127.0.0.1   dev.hostOne.com
127.0.0.1   dev.hostTwo.com

Test your configuration with:

ping dev.hostOne.com
nslookup dev.hostTwo.com

Both should resolve to 127.0.0.1

For more flexibility, install dnsmasq:

brew install dnsmasq

Configure it to handle all *.test domains:

echo "address=/.test/127.0.0.1" >> /usr/local/etc/dnsmasq.conf
sudo brew services start dnsmasq

Then setup macOS to use dnsmasq:

sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/test

For Express-based servers, add virtual host support:

const express = require('express');
const vhost = require('vhost');

const app1 = express().use((req, res) => res.send('Host One'));
const app2 = express().use((req, res) => res.send('Host Two'));

const mainApp = express();
mainApp.use(vhost('dev.hostOne.com', app1));
mainApp.use(vhost('dev.hostTwo.com', app2));

mainApp.listen(80);

For SSL/TLS, use mkcert to generate trusted certificates:

brew install mkcert
mkcert -install
mkcert "dev.hostOne.com" "dev.hostTwo.com"

Then configure your Node server:

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('dev.hostOne.com-key.pem'),
  cert: fs.readFileSync('dev.hostOne.com.pem')
};

https.createServer(options, app).listen(443);

For more complex setups, consider Nginx:

server {
    listen 80;
    server_name dev.hostOne.com;
    location / {
        proxy_pass http://localhost:123;
    }
}

server {
    listen 80;
    server_name dev.hostTwo.com;
    location / {
        proxy_pass http://localhost:456;
    }
}