Docker-compose - Не удается подключиться к Postgres
Похоже, что это распространенная проблема: невозможно подключиться к Postgres из приложения Django в Docker Compose.
На самом деле, я пробовал несколько решений из Интернета, но, возможно, я упускаю что-то, чего не вижу.
Ошибка, которую я получил:
django.db.utils.OperationalError: could not translate host name "db" to address: Попробуйте еще раз
Где "db" должно быть имя службы docker-compose, которое должно быть установлено в .env.
Мой docker-compose.yml:
version: '3.3'
services:
web:
build: .
container_name: drf_app
volumes:
- ./src:/drf
links:
- db:db
ports:
- 9090:8080
env_file:
- /.env
depends_on:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypass
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data/
ports:
- 5432:5432
volumes:
postgres_data:
Мой .env:
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=mydb
SQL_USER=myuser
SQL_PASSWORD=mypass
SQL_HOST=db #this one should match the service name
SQL_PORT=5432
Насколько я знаю, web и db должны автоматически видеть друг друга в одной сети, но этого не происходит
Проверив ip-адреса с помощью ifconfig на каждом контейнере: django app имеет 172.17.0.2, а db 172.19.0.2. Они не могут пинговать друг друга.
Результат команды docker ps:
400879d47887 postgres:13-alpine "docker-entrypoint.s…" 38 minutes ago Up 38 minutes 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp backend_db_1
Я действительно не могу понять проблему, может я что-то упускаю?
Вы сказали в комментарии:
Команда, которую я выполняю, следующая:
docker run -it --entrypoint /bin/sh backend_web
Docker Compose создает несколько ресурсов Docker, включая default
сеть. Если вы отдельно docker run
контейнер, он не видит ни одного из этих ресурсов. Контейнер docker run
находится в "сети моста по умолчанию" и не может использовать современные сетевые возможности Docker, но контейнер docker-compose
находится в отдельной "определяемой пользователем сети моста" под названием backend_default
. Именно поэтому вы наблюдаете пару симптомов: эти две сети имеют отдельные диапазоны IPv4 CIDR, и разрешение DNS контейнера Docker происходит только для текущей сети.
Нет никаких причин запускать контейнер с интерактивной оболочкой, а затем запускать свое приложение в ней (так же, как вы обычно не запускаете python
, а затем вручную вызываете main()
из его REPL). Просто запустите все приложение:
docker-compose up -d
Если вам понадобится интерактивная оболочка для отладки настройки контейнера или для выполнения некоторых ручных задач, таких как миграция базы данных, вы можете использовать docker-compose run
для этого. При этом сохраняется большинство, но не все настройки в файле docker-compose.yml
. В частности, вы не можете docker-compose run
создать интерактивную оболочку и запустить из нее ваше приложение, поскольку она игнорирует ports:
.
# Typical use: run database migrations
docker-compose run web \
./manage.py migrate
# For debugging: run an interactive shell
docker-compose run web bash
Я пишу это, чтобы избавить кого-либо в будущем от той же проблемы.
После бесчисленных попыток я начал думать, что с точки зрения чистого докера все в порядке: Я был прав.
РЕШЕНИЕ: Мое единственное подозрение было связано с выполнением внутри виртуальной машины , поэтому выполнение того же образа docker на хосте сработало как шарм! Проблема с сетью была связана с виртуальной машиной (VirtualBox Ubuntu 20.04)
Я не знаю, есть ли способ работать с docker-compose внутри виртуальной машины, поэтому любое предложение будет оценено по достоинству.