Django Is the server running on host "localhost" (127.0.0.1) and accepting web | TCP/IP connections on port 5432?

Viewed 71

I am trying to dockerize my Django application. My configs are the following:

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'DB_NAME',
        'USER': 'DB_USER',
        'PASSWORD': 'DB_PASSWORD',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

.env file

POSTGRES_USER='DB_USER'
POSTGRES_PASSWORD='DB_PASSWORD'
POSTGRES_DB='DB_NAME'
POSTGRES_HOST='localhost'
POSTGRES_PORT='5432'

Dockerfile.web

FROM python:3.9-bullseye

WORKDIR /app

ENV PYTHONUNBUFFERED=1

COPY csgo .

RUN apt-get update -y \
    && apt-get upgrade -y pip \
    && pip install --upgrade pip \
    && pip install -r requirements.txt

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

docker-compose.yml

version: '3'

services:
  web:
    container_name: web
    build:
      context: .
      dockerfile: Dockerfile.web
    env_file:
      - .env
    volumes:
      - .:/code
    ports:
      - '8000:8000'
    depends_on:
      - db

  db:
    image: postgres:13
    restart: always
    ports:
      - '5432:5432'
    env_file:
      - .env

volumes:
  postgres_data:

Now, when I docker-compose up all appear to be working fine besides connection to the database. I get this error:

django.db.utils.OperationalError: could not connect to server: Connection refused
web           |         Is the server running on host "localhost" (127.0.0.1) and accepting
web           |         TCP/IP connections on port 5432?
web           | could not connect to server: Cannot assign requested address
web           |         Is the server running on host "localhost" (::1) and accepting
web           |         TCP/IP connections on port 5432?

Can you please help me solve this problem? Additionally, I would be grateful for broader explanation about the localhost definition in docker containers and its connections.

1 Answers

In a Docker context, localhost means the container itself.

Docker compose sets up a docker bridge network and connects the containers to it. From one container, you can connect to another container using it's service name.

So you need to use db as the hostname for the database, like this

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'DB_NAME',
        'USER': 'DB_USER',
        'PASSWORD': 'DB_PASSWORD',
        'HOST': 'db',
        'PORT': '5432',
    }
}

As far as I can see, you don't use the environment variables, but you might need to change it there as well.

Related