1

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.

Docker
  • 159
  • 1
  • 2
  • 10
  • `POSTGRES_HOST='db'`, localhost is as always, the local loopback of a machine the fact that it is a container does not differ. So, different container means It is not localhost anymore. – β.εηοιτ.βε Sep 12 '22 at 10:57
  • Please don't re-ask the same question again; if you believe your original isn't a duplicate, please clarify on the original question. You may also be looking for [What does localhost means inside a Docker container?](https://stackoverflow.com/questions/50278632/what-does-localhost-means-inside-a-docker-container). – David Maze Sep 12 '22 at 11:20
  • In my case had to change the host in `settings.py` to `'HOST': 'postgres'`. – Tiago Martins Peres Mar 02 '23 at 13:49

1 Answers1

2

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.

Hans Kilian
  • 18,948
  • 1
  • 26
  • 35
  • I have used it, then came up with idea that env_file is enough to meet env variable expectations, no? – Docker Sep 12 '22 at 11:03
  • Yeah bro, thanks. Your answer was really helpful, I got understanding of concepts of docker and its container! Additionally, I am getting a new error, heh. Could you help me solve it? ```django.db.utils.OperationalError: FATAL: password authentication failed for user "DB_USER"``` – Docker Sep 12 '22 at 11:05
  • I hate this kind of errors. I don't understand how do I connect to a database. And if I create that database with my own password, then why it raises this auth error? – Docker Sep 12 '22 at 11:06