localhost усередині контейнера - це сам контейнер, а не хост. Тому з контейнера застосунку DB_HOST=localhost не знайде базу, що працює на хості.
Як звернутися до хоста:
Docker Desktop (macOS, Windows): спеціальне ім'я host.docker.internal вказує на хост:
DB_HOST=host.docker.internal
Linux: цього імені за замовчуванням немає, але його можна додати:
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
host-gateway Docker підставляє як адресу хоста в мережі контейнерів. Laravel Sail додає це налаштування саме для Xdebug, якому треба підключатися до IDE на хості.
Сервіс на хості має слухати не лише 127.0.0.1, а інтерфейс, доступний з мережі Docker, - інакше з'єднання буде відхилено.
Мережа host (--network host) - контейнер використовує мережевий стек хоста напряму: localhost - це хост, порти не потрібно публікувати. На Linux це просто й без накладних витрат; у Docker Desktop мережа host працює інакше (вона відноситься до віртуальної машини, а підтримка для хоста macOS/Windows з'явилася в нових версіях і має обмеження).
Чим Docker Desktop відрізняється від Linux:
- контейнери працюють у віртуальній машині з Linux - мережі Docker живуть у ній, а не на хості;
- IP-адреси контейнерів недоступні з хоста напряму - лише через опубліковані порти;
- опубліковані порти прокидаються з віртуальної машини на хост автоматично;
- VPN і корпоративні проксі можуть впливати на мережу VM - Docker Desktop має окремі налаштування проксі.
На Linux:
- IP-адреси контейнерів (
172.17.x.x) доступні з хоста напряму; - опубліковані порти Docker відкриває правилами iptables, що можуть обходити ufw - порт бази, опублікований на
0.0.0.0, стає доступним з інтернету, навіть якщо ufw його «закриває».
Практичні правила:
- сервіси між собою - через мережу Docker за назвою сервісу (
DB_HOST=db), а не через хост; - до хоста - через
host.docker.internalзhost-gatewayдля Linux; - не покладатися на IP-адреси контейнерів - вони змінюються при перестворенні;
- конфігурацію, що «працює на Mac», перевіряти на Linux (CI, сервер) - мережева поведінка відрізняється.