Как получить доступ к базе данных на localhost из Django в контейнере Docker
У меня есть django в контейнере docker, который должен получить доступ к базе данных postgres на моем localhost. Dockerfile работает нормально при доступе к базе данных, расположенной на внешнем хосте, но он не может найти базу данных на моем хосте. Это хорошо известная проблема, и есть много документации, но в моем случае она не работает.
Все зависит от того, какой интернет-адрес я передаю ключу HOST в драйвере базы данных dictioonary в django settings.py:
print('***', os.environ['POSTGRES_DB'], os.environ['POSTGRES_USER'],
os.environ['POSTGRES_HOST'], os.environ['POSTGRES_PORT'])
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # os.environ['ENGINE'],
'NAME': 'demo',
'USER': os.environ['POSTGRES_USER'],
'PASSWORD': os.environ['POSTGRES_PASSWORD'],
'HOST': os.environ['POSTGRES_HOST'],
}
}
И запуск Dockerfile:
docker build -t dd .
docker run --name demo -p 8000:8000 --rm dd
Когда POSTGRES_HOST указывает на мой внешний сервер 192.168.178.100, он работает отлично. При запуске python manage.py runserver он находит хост и базу данных. Сервер запускается и ждет команд. При указании на 127.0.0.1 происходит сбой (что на самом деле тоже здорово: контейнер действительно изолирован).
django.db.utils.OperationalError: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
Но так как я могу подключиться к своему серверу, я должен быть в состоянии подключиться к IP локального хоста, и это также не удается (я забыл сказать, что база данных действительно запущена). Когда я использую host.docker.internal, это тоже не работает, когда запускаю:
docker run --name demo -p 8000:8000 --rm --add-host host.docker.internal:host-gateway dd
Заменяет host.docker.internal на 172.17.0.1. Единственное решение, которое работает до сих пор:
# set POSTGRES_HOST at 127.0.0.1
docker run --name demo -p 8000:8000 --rm --network host dd
но это, похоже, то, чего я не хочу. Насколько я понимаю документацию, это делает весь стек хоста доступным для контейнера, что в первую очередь разрушает идею контейнера. Но во-вторых: это не работает в docker-compose, хотя я указываю:
extra_hosts:
- "host.docker.internal:host-gateway"
network_mode: host приводит к ошибке компиляции, docker-compose отказывается запускаться.
Есть ли способ получить доступ к службе, запущенной на моем ПК, из докера, запущенного на моем ПК, а также из Dockerfile, а также из docker-compose и может быть развернут?
использую Ubuntu 21.04 (последняя версия), Docker версии 20.10.7, сборка 20.10.7-0ubuntu5.1, postgresql v14. Мой Dockerfile:
FROM python:3
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
RUN mkdir /app
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "manage.py", "runserver", "127.0.0.1:8000"]