All posts
Ethernet cables plugged into a network switch

SNAT vs DNAT: what actually happens on your VPS

NAT sounds academic until your Docker port mapping or reverse proxy breaks. SNAT and DNAT are just “who gets rewritten” on the packet.

DNAT — destination NAT (incoming)

DNAT changes the destination IP/port of inbound traffic. Your VPS public IP :443 hits Nginx or Traefik; DNAT (or Docker’s publish rules) forwards to a container on `172.17.0.2:3000`. The client never talks to the private IP directly.

  • Docker `-p 8080:80` → DNAT from host 8080 to container 80
  • Reverse proxy virtual hosts → DNAT-like behavior at application layer
  • Home lab: port forward on router → DNAT to your NAS

SNAT — source NAT (outgoing)

SNAT rewrites the source address of packets leaving a private network. Containers with only internal IPs reach the internet through the host’s public IP — the host masquerades (MASQUERADE) outbound traffic. Replies come back to the host, which unmangles and forwards to the container.

Where you see both on one VPS

Request: Internet → DNAT → Nuxt container. Container fetches API on same host: may hairpin or go out and SNAT back. Webhook callbacks from container to Stripe: SNAT applies. Misconfigured SNAT is why some setups “work locally in container network” but fail for external OAuth callbacks.

  1. Check `iptables -t nat -L` when debugging publish ports
  2. Prefer one reverse proxy (Traefik/Caddy) over dozens of published ports
  3. Document public URL vs internal service name for your team

Continue reading

DevOps

Best VPS tools in 2026: Portainer, Coolify, CapRover & aaPanel

Read article
CRM

Email open tracking in CRM: old pixels vs Resend webhooks

Read article