Docker Compose with Django and Postgres Fails with "django.db.utils.OperationalError: could not connect to server:"

Question:

I am trying to run my django/postgres application with docker compose. When I run docker compose up -d I get the the following logs on my postgres container running on port 5432:

2023-02-18 00:10:25.049 UTC [1] LOG:  starting PostgreSQL 13.8 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
2023-02-18 00:10:25.049 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2023-02-18 00:10:25.049 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2023-02-18 00:10:25.052 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2023-02-18 00:10:25.054 UTC [22] LOG:  database system was shut down at 2023-02-18 00:10:06 UTC
2023-02-18 00:10:25.056 UTC [1] LOG:  database system is ready to accept connections

It appears my postgres container is working properly. However my python/django container has the following logs:

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?

docker-compose.yml

version: '3.8'
services:
  web:
    build: .
    command: sh -c "python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    env_file:
      - ./xi/.env
    depends_on:
      - db
  db:
    image: postgres:13-alpine
    environment:
      - POSTGRES_DB=***
      - POSTGRES_USER=***
      - POSTGRES_PASSWORD=***
    volumes:
      - dev-db-data:/var/lib/postgresql/data
    ports:
      - 5432:5432
volumes:
  dev-db-data:

Dockerfile:

FROM python:3.8
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code

# install psycopg2 dependencies
RUN apt-get update
RUN apt-get install nano python3-dev libpq-dev -y

COPY requirements-prod.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

I must be missing something small that allows the python container to communicate with the postgres container.

Also a few additional questions:

What does it mean that the container is "listening on IPv4 address ‘0.0.0.0’, port 5432"? To my understanding 0.0.0.0 encapsulates all ip addresses including 127.0.0.1. So, in this case that shouldn’t be an issue (correct me if I’m wrong)

I have been struggling with this for a few days. I have followed the getting started docs as well as the python usage guides on the docker docs, and it appears that I feel that I understand everything, but I am unable to debug my containers efficiently. What additional supplemental knowledge can I acquire that helps me debug a container with the same level of comfortability as I would a python script?

I tried a few things:

  • swapping env_file with the credentials hard coded in
  • changing python with python3
  • removing sh -c
  • I tried building my database first with docker-compose up -d --build db and then building my web app with docker-compose up -d --build web and the issue persisted.

I tried everything with the environment variables and it appears improper credentials is not the issue. Running python manage.py runserver without docker it successfully connects to the database. There are some similar stack overflow questions, but I have tried their solutions and they do not work.
Part of my issue is I don’t know what to try and how to efficiently debug docker containers yet (hence the question above).

Asked By: Rob Campbell

||

Answers:

What have you set as your HOST variable in DATABASES['default'] in settings.py? If it’s '127.0.0.1', try changing to 'db' to match the container service name.

Answered By: dr_cornelius