The traditional /etc/hosts
file doesn't support wildcard DNS entries like *.localhost
. When you need to test multiple subdomains in development (e.g., api.localhost
, app.localhost
, test.localhost
), manually adding each entry becomes tedious.
Option 1: Local DNS Server (Recommended)
Setting up a local DNS server like dnsmasq provides the most flexible solution:
# Install dnsmasq (macOS: brew install dnsmasq)
sudo apt install dnsmasq
# Configure dnsmasq
echo "address=/localhost/127.0.0.1" | sudo tee /etc/dnsmasq.d/localhost.conf
# Restart service
sudo systemctl restart dnsmasq
# Update DNS resolver (macOS/Linux)
sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/localhost
Option 2: Using xip.io (Quick Temporary Solution)
For temporary testing, services like xip.io provide wildcard DNS:
yourproject.127.0.0.1.xip.io # Resolves to 127.0.0.1
api.127.0.0.1.xip.io # Also resolves to 127.0.0.1
For Django's runserver to handle subdomains:
# In settings.py
ALLOWED_HOSTS = ['.localhost', '127.0.0.1'] # Note the leading dot
# In urls.py (subdomain routing example)
from django.conf import settings
from django.urls import path, include
from django.conf.urls import handler404, handler500
urlpatterns = [
path('', include('main.urls')),
]
if settings.DEBUG:
urlpatterns += [
path('', include('api.urls')), # api.localhost
path('', include('admin.urls')), # admin.localhost
]
Verify your setup works:
curl -H "Host: api.localhost" http://127.0.0.1
curl -H "Host: app.localhost" http://127.0.0.1
Modern browsers may cache DNS or apply security restrictions. For reliable testing:
- Use private/incognito mode
- Disable DNS cache (Chrome:
chrome://net-internals/#dns
) - Consider adding entries to your system's hosts file as fallback
The /etc/hosts
file doesn't natively support wildcard entries like *.localhost.com
. This becomes a challenge when you need to test multiple subdomains locally for web development, especially with frameworks like Django that may handle subdomain routing.
Here are three effective approaches to solve this problem:
1. Using dnsmasq (Recommended for Linux/OSX)
Install and configure dnsmasq to handle wildcard DNS locally:
# Install dnsmasq
brew install dnsmasq # OSX
sudo apt-get install dnsmasq # Linux
# Configure dnsmasq
echo "address=/localhost.com/127.0.0.1" >> /usr/local/etc/dnsmasq.conf
# Start dnsmasq
sudo brew services start dnsmasq # OSX
sudo systemctl start dnsmasq # Linux
# Configure your system to use dnsmasq
sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/localhost.com
2. Django Development Server Configuration
For Django projects, you can modify the development server to handle subdomains:
# settings.py
ALLOWED_HOSTS = ['.localhost.com'] # Note the leading dot
# urls.py
from django.urls import path
from django.conf import settings
from django.contrib import admin
from django.http import HttpResponse
def subdomain_view(request):
subdomain = request.get_host().split('.')[0]
return HttpResponse(f"Hello from {subdomain}.localhost.com")
urlpatterns = [
path('admin/', admin.site.urls),
path('', subdomain_view),
]
3. Using a Local Reverse Proxy
Set up Nginx as a reverse proxy to handle wildcard subdomains:
# nginx.conf
server {
listen 80;
server_name ~^(?.+)\.localhost\.com$;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
After implementing any of these solutions, test with curl:
curl -H "Host: test.localhost.com" http://127.0.0.1
curl -H "Host: api.localhost.com" http://127.0.0.1
Or configure your browser to resolve these domains properly. You may need to flush your DNS cache:
sudo dscacheutil -flushcache # OSX
sudo systemd-resolve --flush-caches # Linux (systemd)
- For HTTPS, you'll need a wildcard SSL certificate or use tools like mkcert
- Consider using .test or .localhost TLD instead of .com for better compatibility
- Browser security policies may affect some of these solutions