You want shop.test on localhost during the day, then the real client domain pointed at staging, then maybe the same domain pointed at a new server before DNS moves.
You do not need dnsmasq for that. You need a clean way to switch mappings without leaving three conflicting lines in /etc/hosts.
Why one big hosts file fails
After a few months it often looks like this:
127.0.0.1 shop.test
127.0.0.1 api.shop.test
# 203.0.113.10 www.client.com
10.0.0.5 www.client.com
127.0.0.1 www.client.com
Same hostname, several intentions. The browser will not tell you which line won. It just resolves something.
Comments help for a day. They do not help when you are tired and switching contexts.
Use profiles instead of comments
Keep separate files. Only one is active at a time for a given hostname.
Example layout:
~/dev/hosts-profiles/
local
staging
cutover
local
127.0.0.1 shop.test
127.0.0.1 api.shop.test
127.0.0.1 admin.shop.test
staging
203.0.113.40 www.client.com
203.0.113.40 api.client.com
cutover (pre-DNS migration test)
198.51.100.20 www.client.com
198.51.100.20 api.client.com
Apply a profile
macOS / Linux:
PROFILE=staging
sudo cp /etc/hosts "/etc/hosts.bak.$(date +%Y%m%d-%H%M%S)"
sudo cp ~/dev/hosts-profiles/$PROFILE /etc/hosts
Then flush DNS for your OS.
Windows: same idea. Keep profile files, back up the live hosts file, copy the profile over:
C:\Windows\System32\drivers\etc\hosts
Then:
ipconfig /flushdns
Small bash helper
#!/usr/bin/env bash
set -euo pipefail
PROFILE="${1:?usage: hosts-use <profile>}"
SRC="$HOME/dev/hosts-profiles/$PROFILE"
[[ -f "$SRC" ]] || { echo "missing $SRC"; exit 1; }
sudo cp /etc/hosts "/etc/hosts.bak.$(date +%Y%m%d-%H%M%S)"
sudo cp "$SRC" /etc/hosts
# macOS. Swap this block on Windows/Linux.
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
echo "Active hosts profile: $PROFILE"
Usage:
./hosts-use local
./hosts-use staging
Optional: base file + project overlay
If you want personal localhost names plus project-specific domains:
~/dev/hosts-profiles/
_base
project-shop-local
project-shop-staging
Apply with:
cat ~/dev/hosts-profiles/_base \
~/dev/hosts-profiles/project-shop-staging \
| sudo tee /etc/hosts >/dev/null
Keep _base small. Put production hostnames only in the project overlay so they are easy to turn off.
Pre-DNS cutover checklist
This is one of the best uses of hosts:
- Put the production hostnames on the new server IP in a
cutoverprofile - Apply the profile and flush DNS
- Test login, cookies, HTTPS, redirects, anything that depends on the Host header
- Switch back when you are done
Write the rollback next to the migration checklist. You will want it on cutover night.
Docker caveat
Hosts on your laptop affect the browser on your laptop.
Processes inside containers usually use Docker DNS, not your host /etc/hosts.
- Browser to
shop.teston the host: host hosts file - Container to another container: Compose service names or
extra_hosts
Do not debug the wrong layer.
After every switch
# What does the OS resolve?
getent hosts www.client.com
# macOS alternative:
# dscacheutil -q host -a name www.client.com
# What is in the file?
grep -n "www.client.com" /etc/hosts
If the terminal IP is wrong, fix hosts first. Do not dig into the app yet.
When hosts profiles stop being enough
Move to dnsmasq, CoreDNS, or company DNS when you need:
- lots of wildcards
- many services added every week
- one shared dynamic map for a whole team
Until then, separate profile files beat a single commented hosts file.
Start with three files
-
localfor your.testdomains -
stagingfor client staging IPs -
cutoverleft empty until migration week
Switch the whole file, flush DNS, verify in the terminal. That is the whole method.
Top comments (0)