После перехода на postgresql - соединение сбрасывается коллегой
Согласно этому руководству я перешел на код postgresql.
# django_project/settings.py
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "db", # set in docker-compose.yml
"PORT": 5432, # default postgres port
}
}
Вот docker-compose.yml
# docker-compose.yml
version: "3.9"
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
- db
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
volumes:
postgres_data:
Все работало до редактирования DATABASES
раздела.
Когда я бегу
$ curl 127.0.0.1:8000
curl: (56) Recv failure: Connection reset by peer
Попробуйте использовать учетные данные db -
# docker-compose.yml
version: "3.9"
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
- db
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
volumes:
postgres_data:
вы можете сделать это с помощью env-файла -
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.dev.db
here is env
#.env.dev.db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=postgres
Невозможность подключения от web
происходит до того, как db
сообщает, что готов принимать соединения; depend_on: db
заставляет web
ждать запуска всего db
контейнера, а не запуска Postgres внутри контейнера. Скорее всего, ваш web
вызывает db
раньше, чем он готов ответить.
В docker compose
руководстве предлагается depend_on
проверить статус обслуживания:
# docker-compose.yml
version: "3.9"
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
db:
condition: service_healthy
db:
image: postgres:13
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
retries: 5
start_period: 30s
timeout: 10s
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
volumes:
postgres_data:
В статье руководства даже предупреждается о вашем точном сценарии (части, выделенные жирным шрифтом ):
Управление порядком запуска и выключения в Compose
Вы можете управлять порядком запуска и остановки сервисов с помощью атрибута
depends_on
. Compose всегда запускает и останавливает контейнеры в порядке зависимости, где зависимости определяютсяdepends_on
,links
,volumes_from
иnetwork_mode: "service:..."
.Хорошим примером того, как это можно использовать, является приложение, которому требуется доступ к базе данных. Если обе службы запущены с
docker compose up
, есть вероятность, что это не удастся, поскольку служба приложения может запуститься раньше службы базы данных и не найдет базу данных, способную обрабатывать ее SQL-запросы.Управление запуском
.При запуске Compose не ждет, пока контейнер будет «готов», а только пока он не будет запущен. Это может вызвать проблемы, если, например, у вас есть система реляционной базы данных, которая должна запустить свои собственные службы, прежде чем сможет обрабатывать входящие соединения.
Команда condition
и соответствующая ей команда healthcheck
взяты прямо из этого документа. Команда pg_isready
поставляется в комплекте с вашим postgres
образом.
То, что вы показали, возможно, изначально работало для автора этого руководства, и это может работать для других, если в их настройках Postgres удалось запустить достаточно быстро. Или, в их случае, web
потребовалось больше времени для отправки запросов, чтобы Postgres успел завершить запуск и перехватить их.
Может возникнуть соблазн попытаться добавить начальный сон/ожидание/задержку в приложение web
, чтобы дать ему время на инициализацию db
, но безопаснее проверить и убедиться в этом. Также понятнее и проще отслеживать, если вы определяете условие зависимости в docker-compose.yml
, а не в коде вашего приложения, которое не должно иметь дело с вопросами, связанными с настройкой среды.