Skip to content

Troubleshooting: Caddy DNS Caching

The Problem

When the backend container is recreated (e.g., after docker compose up -d backend):

  1. Docker assigns a new IP address to the backend container
  2. Docker DNS updates the backend hostname to the new IP
  3. Caddy's Go DNS resolver caches the old IP for up to 30 minutes
  4. Some requests go to the new IP (new connections), some go to the old IP (cached connections)
  5. Requests to the old IP fail or return unexpected responses → intermittent 400 errors

Symptoms

  • Some page loads work, some show "Une erreur inattendue"
  • curl shows alternating 200 and 400 responses
  • Backend logs show requests with wrong Host headers

The Fix: Static IP Network

1. Create a static Docker network

docker network create --driver bridge --subnet 172.29.0.0/16 messages_static

2. Assign static IPs in compose.yml

services:
  backend:
    networks:
      messages_static:
        ipv4_address: 172.29.0.10

  frontend:
    networks:
      messages_static:
        ipv4_address: 172.29.0.20

3. Point Caddy to the static IP

MESSAGES_FRONTEND_BACKEND_SERVER=172.29.0.10:8000

Why This Works

The backend's IP never changes (it's pinned to 172.29.0.10). Caddy always connects to the same IP. Docker container recreation doesn't affect connectivity.

Network Diagram

messages_static (172.29.0.0/16)
├── 172.29.0.10 → backend (static, never changes)
├── 172.29.0.20 → frontend
├── 172.29.0.30 → calendars-backend
├── 172.29.0.31 → calendars-frontend
└── 172.29.0.35 → calendars-caldav

This Applies to Both Messages and Calendars

Both frontends run Caddy and proxy to their respective backends. Both need static IPs.