How to Route Subdomains to Localhost Ports on Windows for Seamless Development


2 views

For basic local development, modifying the Windows hosts file is the simplest solution. This works for HTTP requests but has port limitations:

# Edit C:\\Windows\\System32\\drivers\\etc\\hosts
127.0.0.1 api.myserver.com
127.0.0.1 www.myserver.com

However, this method can't specify ports - all requests will go to port 80. For port routing, we need more advanced solutions.

The most flexible approach is running a local reverse proxy. Here are two excellent options:

1. Using Nginx

Nginx configuration for port routing:

server {
    listen 80;
    server_name api.myserver.com;
    
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
    }
}

server {
    listen 80;
    server_name www.myserver.com;
    
    location / {
        proxy_pass http://localhost:8008;
        proxy_set_header Host $host;
    }
}

2. Using Caddy Server

Caddy offers simpler configuration with automatic HTTPS:

api.myserver.com {
    reverse_proxy localhost:8000
}

www.myserver.com {
    reverse_proxy localhost:8008
}

For Windows-specific solutions, you can create a PowerShell script to simulate DNS resolution:

# Run as Administrator
Add-DnsClientNrptRule -Namespace "api.myserver.com" -NameServer "127.0.0.1"
Add-DnsClientNrptRule -Namespace "www.myserver.com" -NameServer "127.0.0.1"

Modern browsers require HTTPS for many features. To enable HTTPS for local subdomains:

# Using mkcert (recommended)
mkcert -install
mkcert "api.myserver.com" "www.myserver.com"

Then update your proxy configuration to use these certificates.

For more complex setups, consider using Docker with Traefik:

version: '3'
services:
  api:
    image: your-api-image
    ports:
      - "8000:8000"
    labels:
      - "traefik.http.routers.api.rule=Host(api.myserver.com)"
  
  web:
    image: your-web-image
    ports:
      - "8008:8008"
    labels:
      - "traefik.http.routers.web.rule=Host(www.myserver.com)"

  traefik:
    image: traefik
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

When developing multiple web services locally, we often need to mirror production subdomain structures (like api.myserver.com) to different localhost ports. The main obstacles are:

  • Browser security restrictions on localhost subdomains
  • Port number visibility in API calls
  • Cross-service communication requirements

The simplest approach is editing the Windows hosts file:

# C:\Windows\System32\drivers\etc\hosts
127.0.0.1 api.myserver.com
127.0.0.1 www.myserver.com

Limitations:

  • Can't specify ports
  • Requires admin privileges
  • Doesn't work for HTTPS without certificates

For complete solution, we'll use Nginx:

# nginx.conf
server {
    listen 80;
    server_name api.myserver.com;
    
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
    }
}

server {
    listen 80;
    server_name www.myserver.com;
    
    location / {
        proxy_pass http://127.0.0.1:8008;
        proxy_set_header Host $host;
    }
}

For dynamic environments, create a setup script:

# setup-proxy.ps1
$hostsEntry = "127.0.0.1 api.myserver.com www.myserver.com"
Add-Content -Path "$env:windir\System32\drivers\etc\hosts" -Value $hostsEntry

# Start Nginx
Start-Process "nginx.exe" -ArgumentList "-c "path\to\your\nginx.conf""

For SSL termination:

# Generate self-signed cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout api.myserver.com.key -out api.myserver.com.crt \
-subj "/CN=api.myserver.com"

# Nginx SSL configuration
server {
    listen 443 ssl;
    server_name api.myserver.com;
    
    ssl_certificate api.myserver.com.crt;
    ssl_certificate_key api.myserver.com.key;
    
    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}
Tool Pros Cons
Nginx Lightweight, stable Manual config
Caddy Auto HTTPS Higher memory
Windows IIS ARR Native integration Complex setup
  • Use ping subdomain to verify DNS resolution
  • Check Nginx error logs at logs/error.log
  • Test with curl -v http://api.myserver.com
  • Verify ports with netstat -ano | findstr LISTENING