Ответ
Для взаимодействия контейнеров без Docker Compose используется механизм пользовательских сетей (docker network). Это позволяет контейнерам обращаться друг к другу по имени, используя встроенный в Docker DNS-сервер.
Шаг 1: Создание пользовательской сети
Сначала необходимо создать сеть типа bridge (используется по умолчанию).
# Создаем сеть с именем 'my-app-net'
docker network create my-app-net
Шаг 2: Запуск контейнеров в созданной сети
При запуске контейнеров укажите созданную сеть с помощью флага --network.
# Запускаем контейнер с базой данных
docker run -d --name db --network my-app-net postgres:13
# Запускаем контейнер с приложением
docker run -d --name api --network my-app-net my-api-image
Шаг 3: Взаимодействие по имени контейнера
Теперь из контейнера api можно обратиться к контейнеру db по его имени. Например, в строке подключения к базе данных можно использовать хост db.
# Пример строки подключения в Python-приложении (контейнер 'api')
DATABASE_URL = "postgresql://user:password@db:5432/mydatabase"
Ключевые моменты:
- DNS-разрешение: Docker автоматически разрешает имена контейнеров в их IP-адреса внутри пользовательской сети.
- Изоляция: Контейнеры в одной сети изолированы от контейнеров в других сетях и от хост-машины.
- Отсутствие необходимости в
-p: Для внутреннего взаимодействия между контейнерами не нужно публиковать порты на хост-машину. Порты публикуются только для доступа извне.
Ответ 18+ 🔞
А, слушай, тут тебе надо контейнеры подружить без этого твоего Docker Compose, который, блядь, как шпаргалка для ленивых. Есть способ по-старинке, внатуре, через сети. Не, ну а хули, сети же, блядь, не только для котиков в интернете.
Шаг 1: Создаём свою сетку, как паутину для мух
Надо создать свою сеть, типа bridge, это по дефолту. Представь, что это общага для контейнеров, они там тусоваться будут.
# Создаём сеть с именем 'my-app-net'. Главное, чтоб не 'huinet', а то потом сам запутаешься.
docker network create my-app-net
Вот, сеть есть. Теперь туда можно селить.
Шаг 2: Запускаем контейнеры, чтоб они в этой сети оказались Тут важно, как соседей по общаге заселить — чтоб они друг друга по имени знали, а не по IP, который, как сосед-алкаш, может поменяться.
# Запускаем контейнер с базой данных. Имя 'db', сеть наша.
docker run -d --name db --network my-app-net postgres:13
# Запускаем контейнер с приложением. Имя 'api', сеть та же.
docker run -d --name api --network my-app-net my-api-image
Всё, поселили. Теперь api может крикнуть через стенку: «Эй, db, дай пароль!».
Шаг 3: Общаемся по имени, как нормальные люди
Вот тут магия, ёпта. Из контейнера api можно стучаться к db просто по имени db. Docker внутри сам всё разрешает, как свой в доску.
Смотри, в коде приложения строка подключения будет выглядеть вот так просто, без этих твоих локальных host'ов:
# Пример строки подключения в Python-приложении (контейнер 'api')
DATABASE_URL = "postgresql://user:password@db:5432/mydatabase"
Видишь? Хост — просто db. Никаких localhost:5432, которые, блядь, никуда не ведут. Всё чисто, как слеза младенца.
Что важно запомнить, чтобы не облажаться:
- DNS-разрешение: Docker внутри сети сам превращает имена контейнеров в их IP-адреса. Это не колдовство, это технология, блядь.
- Изоляция: Контейнеры в одной сети — как в одной квартире. С улицы (из другой сети или с хоста) к ним не зайдёшь просто так. Только если дверь (
-p) не открыл. - Порты наружу не торчат: Для внутренних разборок между
apiиdbпубликовать порты на хост (-p 5432:5432) не нужно. Это только если ты хочешь снаружи подключиться, например, из своей IDE. А так они сами между собой договорятся.
Вот и всё, никакой ебалы с Compose, если не хочешь. Хотя он, конечно, удобный, сука. Но иногда надо почувствовать себя настоящим сетевым инженером, а не кнопкодавом.