@NyxDeveloper

Django не видит Postgresql на 5432 порту при запуске изпод Docker?

Запускаю простое приложение Django "из коробки" в контейнере с базой Postgres. База создается, джанга запускается, образ билдится и контейнер запускается без ошибок, но в логах докера висит джанговская ошибка:
Traceback (most recent call last):
web_1  |   File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
web_1  |     self.run()
web_1  |   File "/usr/local/lib/python3.8/threading.py", line 870, in run
web_1  |     self._target(*self._args, **self._kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/autoreload.py", line 64, in wrapper
web_1  |     fn(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
web_1  |     self.check_migrations()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 486, in check_migrations
web_1  |     executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
web_1  |     self.loader = MigrationLoader(self.connection)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/loader.py", line 53, in __init__
web_1  |     self.build_graph()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/loader.py", line 220, in build_graph
web_1  |     self.applied_migrations = recorder.applied_migrations()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
web_1  |     if self.has_table():
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 55, in has_table
web_1  |     with self.connection.cursor() as cursor:
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
web_1  |     return func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 259, in cursor
web_1  |     return self._cursor()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
web_1  |     self.ensure_connection()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
web_1  |     return func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
web_1  |     self.connect()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
web_1  |     raise dj_exc_value.with_traceback(traceback) from exc_value
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
web_1  |     self.connect()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
web_1  |     return func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 200, in connect
web_1  |     self.connection = self.get_new_connection(conn_params)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
web_1  |     return func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
web_1  |     connection = Database.connect(**conn_params)
web_1  |   File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 122, in connect
web_1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
web_1  | django.db.utils.OperationalError: could not connect to server: Connection refused
web_1  | 	Is the server running on host "localhost" (127.0.0.1) and accepting
web_1  | 	TCP/IP connections on port 5432?
web_1  | could not connect to server: Address not available
web_1  | 	Is the server running on host "localhost" (::1) and accepting
web_1  | 	TCP/IP connections on port 5432?


Я голову поломал и решил спросить у знающих людей, т.к. это мой первый опыт с docker.
Мой docker-compose.yml
version: '3.8'

services:
  web:
    # Берем Dockerfile из каталога youmaster
    build: ./youmaster
    # Запускаем тестовый сервер
    command: python manage.py runserver 0.0.0.0:8000
    # куда будут помещены данные из каталога youmaster
    volumes:
      - ./youmaster/:/usr/src/youmaster/
    # Открываем порт 8000 внутри и снаружи
    ports:
      - 8000:8000
    # Файл содержащий переменные для контейнера
    env_file:
      - ./.env.dev
  db:
    # Образ и версия базы, которую мы будем использовать
    image: postgres:12.0-alpine
    # Внешний том(volume) и место где он будет подключен внутри контейнера
    volumes:
      - postgres_volume:/var/lib/postgresql/data/
    environment:
      # Учетные данные, которые можно будет переопределить
      - POSTGRES_USER=youmaster
      - POSTGRES_PASSWORD=youmaster
      - POSTGRES_DB=youmaster

volumes:
  postgres_volume:


Мой Dockerfile
# образ на основе которого создаём контейнер
FROM python:3.8.10-alpine

# рабочая директория внутри проекта
WORKDIR /usr/src/youmaster

# переменные окружения для python
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Устанавливаем зависимости для Postgre
RUN apk update \
    && apk add postgresql-dev gcc python3-dev musl-dev

# устанавливаем зависимости
RUN pip3 install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# копируем содержимое текущей папки в контейнер
COPY . .

# run entrypoint.sh
ENTRYPOINT ["/usr/src/youmaster/entrypoint.sh"]


Содержимое файла entrypoint.sh
#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

python manage.py flush --no-input
python manage.py migrate

exec "$@"


Настройки базы данных и поддерживаемых хостов
from os import environ

ALLOWED_HOSTS = environ.get('ALLOWED_HOSTS', 'localhost').split(' ')

DATABASES = {
    'default': {
        'ENGINE': environ.get('POSTGRES_ENGINE', 'django.db.backends.sqlite3'),
        'NAME': environ.get('POSTGRES_DB', os.path.join(BASE_DIR, 'db.sqlite3')),
        'USER': environ.get('POSTGRES_USER', 'user'),
        'PASSWORD': environ.get('POSTGRES_PASSWORD', 'password'),
        'HOST': environ.get('POSTGRES_HOST', 'localhost'),
        'PORT': environ.get('POSTGRES_PORT', '5432')
    }
}


Ну и переменные окружения для этих настроек
DEBUG=1
SECRET_KEY=temp_secretkey
ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
POSTGRES_ENGINE=django.db.backends.postgresql
POSTGRES_DB=youmaster
POSTGRES_USER=youmaster
POSTGRES_PASSWORD=youmaster
POSTGRES_HOST=localhost
POSTGRES_PORT=5432


Раньше подобные ошибки возникали, но они решались запуском runserver от имени sudo, чего с докером делать не сильно хотелось бы. Подскажите пожалуйста, как исправить ситуацию?
Спасибо!
  • Вопрос задан
  • 4601 просмотр
Решения вопроса 2
sergey-gornostaev
@sergey-gornostaev Куратор тега PostgreSQL
Седой и строгий
Во-первых, пихать СУБД в контейнер - это само по себе идея не очень. Во-вторых, localhost у каждого контейнера свой.
Ответ написан
fox_12
@fox_12 Куратор тега Django
Расставляю биты, управляю заряженными частицами
POSTGRES_HOST=db
в вашем случае
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@mva2204
Мне помогло переустановить docker как написано в https://docs.docker.com/engine/install/ubuntu/
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы