After switching to postgresql - connection reset by peer
According to this tutorial I switched to postgresql code.
# 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
}
}
Here is 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:
Everything worked before editing DATABASES
section.
When I run
$ curl 127.0.0.1:8000
curl: (56) Recv failure: Connection reset by peer
Try with using db Credentials -
# 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:
you can do with env file -
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
The failure to connect from web
happens before db
reports that it's ready to accept connections; depend_on: db
only forces web
to wait for the whole db
container to start, not for Postgres inside the container to start. Your web
is likely calling db
before it's ready to answer.
The docker compose
manual suggests it's best to make depend_on
check the service status:
# 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:
The manual entry even warns about your exact scenario (the parts in bold):
Control startup and shutdown order in Compose
You can control the order of service startup and shutdown with the
depends_on
attribute. Compose always starts and stops containers in dependency order, where dependencies are determined bydepends_on
,links
,volumes_from
, andnetwork_mode: "service:..."
.A good example of when you might use this is an application which needs to access a database. If both services are started with
docker compose up
, there is a chance this will fail since the application service might start before the database service and won't find a database able to handle its SQL statements.Control startup
On startup, Compose does not wait until a container is "ready", only until it's running. This can cause issues if, for example, you have a relational database system that needs to start its own services before being able to handle incoming connections.
The condition
and its corresponding healthcheck
command are straight from that doc. The pg_isready
comes bundled inside your postgres
image.
What you showed might've originally worked for the author of that tutorial and it might work for others if on their setup Postgres managed to start up fast enough. Or, in their case web
took longer before sending the requests, long enough for Postgres to finish starting up and catch them.
It might be tempting to try to add an initial sleep/wait/delay in your web
app, to let it give some time for the db
to initialise but it's safer to properly check and make sure. It's also clearer and easier to track if you define the dependency condition in the docker-compose.yml
rather than inside your app code, which shouldn't have to deal with matters related to environment setup.