Этап 6 - Docker Networking
Networking часто забирает много времени у новичков, потому что localhost меняет смысл. Внутри container localhost означает этот же container, а не ноутбук и не другой container.
Ловушка localhost
Docker дает containers собственный network namespace. Это значит, что backend container, подключающийся к localhost:5432, ищет PostgreSQL внутри самого себя. Если PostgreSQL работает в другом container, backend должен использовать имя database container или service name в общей network.
browser -> host:8080 -> container:80
api container -> db:5432
localhost внутри api -> сам api
Bridge networks и ports
Default bridge network подходит для экспериментов, но user-defined bridge networks лучше для проектов. Они дают DNS resolution по имени container. Можно писать db:5432, а не искать container IP addresses.
Port mapping — отдельная концепция. -p 8080:80 означает: host port 8080 отправляет traffic в container port 80. Это нужно, когда browser, host tools или external clients должны попасть в container. Containers в одной network обычно не нуждаются в host port mapping, чтобы говорить друг с другом.
Два направления traffic
Есть два частых направления traffic. Host-to-container traffic использует port mapping. Container-to-container traffic обычно использует Docker network и service names. Смешивание этих моделей создает много confusing bugs.
Если browser открывает localhost:8080, он обращается к host port. Docker пересылает traffic в container port. Если API container подключается к db:5432, он остается внутри Docker network и не нуждается в host port.
Поэтому открывать database port наружу не обязательно для container-to-container communication. Его можно открыть для local GUI tool, но API service все равно может использовать internal service name.
Зачем custom networks
User-defined bridge networks дают более понятное DNS behavior, чем default bridge. Containers могут находить друг друга по name, а unrelated groups of containers можно изолировать.
Например, application network может содержать api, db и redis. Отдельная experiment network может содержать несвязанные containers. Это снижает accidental name collisions и делает diagrams понятнее.
В Compose это поведение в основном automatic. Services в одном Compose project получают default network и могут обращаться друг к другу по service name.
Где имеют смысл network names
Docker network names и service names имеют смысл внутри Docker host. Если два containers находятся в одной user-defined network, Docker может resolve names между ними. Ваш browser вне Docker не использует этот internal DNS.
Поэтому db:5432 может работать из API container, но browser не сможет открыть http://db:5432. Browser находится на стороне host, а не внутри Docker network. Для browser access нужен port mapping от host к container.
На server различие такое же. External users приходят на public host ports или reverse proxy. Containers общаются друг с другом через Docker networks и service names.
Команды: запустить и проверить
Выполняйте эти commands в terminal той машины, где установлен Docker. Для локального обучения это terminal на вашем ноутбуке. Для VPS сначала подключитесь к server по SSH, затем запускайте commands там. Не вставляйте commands вслепую: запустите одну command, посмотрите, что изменилось, затем переходите к следующей.
docker network create app-net
docker run -d --name db --network app-net postgres:16
docker run --rm --network app-net alpine nslookup db
docker run -p 8080:8080 --network app-net app:dev
Таблица для ориентира
| Тема | Что означает | Практический вывод |
|---|---|---|
| Bridge network | Private network на одном host | Default для local apps |
| Port mapping | Host port в container port | Для browser или host access |
| DNS name | Container/service name в network | Для container-to-container access |
Checklist подключения
Для каждого failed connection выпишите source, target, network и port. Source — process, который делает request. Target — process, который принимает его. Network — communication space между ними. Port — место, где target слушает.
Большинство Docker networking bugs становятся очевидными после фразы: «из этого container я подключаюсь к этому service name на этом port».
Контрольная точка
Идите дальше, когда можете объяснить, почему localhost внутри container обычно не подходит для доступа к другому container и когда нужен host port mapping.
Практика: проверка сети
Опишите failed connection как предложение: «process A подключается к host B на port C через network D». Если B — localhost, проверьте, чей это localhost. Если C — host port, проверьте, caller — это host или другой container. Такое маленькое предложение ловит большинство ошибок до случайного изменения Compose или Docker flags.