network_mode: service:vpn и пропавшее имя хоста db
Совместное использование пространства имён VPN — это выбор топологии. Либо db сохраняет собственный адрес, а vpn присоединяется к этой сети, либо всё отвечает на loopback.
Вы добавляете network_mode: service:vpn в приложение, перезапускаете стек, и приложение умирает, потому что db больше не разрешается. В файле compose ничего не переименовано, поэтому очевидные подозреваемые — DNS и база данных. Настоящее изменение меньше и страннее: приложение перестало быть участником сети Compose, где существует это имя. Пока вы не решите, из какого пространства имён должна отвечать база данных, любое исправление имени хоста — догадка.
Почему имя хоста db перестало разрешаться
Служба, использующая network_mode, не имеет собственного адреса в сети Compose; она заимствует пространство имён указанной службы. Это пространство приносит свои интерфейсы, маршруты, пространство портов и резолвер, и оно заменяет подключение приложения к сети backend. Имя db никогда не было абстрактным: оно жило в этой сети и разрешалось через встроенный DNS. Уберите подключение, и имени негде разрешаться.
Подтвердите это изнутри контейнеров, а не с хоста. Поиск, который не удаётся в приложении, но удаётся в контейнере базы данных, означает, что имя в порядке, а членство — нет. Этот результат также помещает исправление в топологию compose, а не в настройки резолвера приложения.
Три вопроса перед правкой файла
Ответьте на них по порядку, потому что каждый сужает топологию. На что должна отвечать база данных: на имя хоста, которое используют другие контейнеры, или только на приложение на loopback? Должно ли приложение публиковать порт на хост, и какая служба владела бы им? Должна ли база данных быть доступна с хоста или с другой машины, или только изнутри туннеля?
Если базе данных нужно собственное имя, а приложение ничего не публикует, держите их на отдельных подключениях. Если приложение должно публиковать порт и всё идёт через туннель, поместите базу данных в пространство имён VPN и используйте loopback. Смешение обоих даёт стек, который чисто запускается и падает при подключении.
Оставьте базу данных там, где она есть
Меньшее изменение подключает владельца пространства имён к сети, которая уже содержит базу данных. Приложение наследует это подключение, потому что делит стек vpn, и db разрешается точно как раньше.
services:
vpn:
networks:
- backend
app:
network_mode: service:vpn
db:
networks:
- backend
networks:
backend:Не добавляйте networks и в приложение. Compose отклоняет это свойство вместе с network_mode в той же службе, и ошибка указывает на файл, а не на пару. Если клиент VPN фильтрует назначение backend внутри своего пространства имён, настройте и его поддерживаемую политику локальной сети; общее подключение предлагает путь, но не отменяет этот фильтр.
Переместите базу данных в пространство имён
Большее изменение помещает базу данных в то же пространство имён и направляет приложение на 127.0.0.1 с настоящим портом. Два процесса не могут оба занять один и тот же адрес и порт только потому, что запустились в разных контейнерах, поэтому база данных, которая также слушает на wildcard-адресе, столкнётся со всем остальным, что это делает. Проверьте слушателя перед перемещением.
Опубликованные порты принадлежат службе, владеющей пространством имён. Добавление ports в приложение отклоняется вместе с network_mode, а изобретение отдельного адреса приложения описывает интерфейс, которого нет.
Готовность, блокировка и резолвер
depends_on упорядочивает запуск контейнеров; это не доказательство того, что туннель работает, и он не останавливает трафик, когда туннель падает. Рассматривайте достижимость, готовность туннеля и блокировку отказов как три отдельных требования. Стек, удовлетворяющий только первому, проходит ручной тест в хороший день и течёт в плохой. Запишите три ответа рядом с файлом compose, там, куда посмотрит следующий человек.
Совместное использование пространства имён также означает, что приложение наследует резолвер контейнера VPN, что помогает, когда туннель навязывает DNS-серверы, и путает, когда не делает этого. Проверьте, что пространство имён действительно содержит, вместо того чтобы предполагать, что резолвер хоста применим. Справочник служб Compose документирует network_mode, ports и поведение зависимостей в одном месте, включая то, почему у службы network_mode нет собственного адреса.