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 внутри виртуальной машины, поэтому любое предложение будет оценено по достоинству.

Вернуться на верх