Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres django.db.utils.OperationalError: could not connect to server: Connection refused

Trying to run my django server in a docker, but the postgres port is already being used? When I run "docker-compose up", I receive this error:

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?

ERROR: Service 'web' failed to build: The command '/bin/sh -c python manage.py migrate' returned a non-zero code: 1

sudo service postgresql status

returns:

9.6/main (port 5432): online

sudo lsof -nP | grep LISTEN

returns:

postgres  15817         postgres    3u     IPv4            1022328        0t0        TCP 127.0.0.1:5432

I tried to run "sudo kill -9 15817", but docker-compose up still receives the same error.

Docker-compose.yml

version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'stemletics',
        'USER': 'stemleticsadmin',
        'PASSWORD': 'changeme',
        'HOST': '127.0.0.1', # set in docker-compose.yml
        'PORT': 5432 # default postgres port
    }
}
like image 429
Dominic M. Avatar asked Jan 01 '23 20:01

Dominic M.


2 Answers

In order to use postgres inside of Docker you will need to configure information like the database user, password and db-name. This is done through setting environment variables for the container. A complete list of supported variables can be found here.

Additionally you will want to expose port 5432 of postgres to your web service inside your docker-compose file.

Something like this should work:

docker-compose.yml

version: '3'

services:
  db:
    image: postgres
    ports: 
      - "5432"
    environment:
      - POSTGRES_DB=stemletics
      - POSTGRES_USER=stemleticsadmin
      - POSTGRES_PASSWORD=changeme
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

You will also have to change the hostname you are using inside settings.py. docker-compose creates a default network for your services and attaches the running containers to this network. Inside your web container the database will be available at the hostname db.

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'stemletics',
        'USER': 'stemleticsadmin',
        'PASSWORD': 'changeme',
        'HOST': 'db', # set in docker-compose.yml
        'PORT': 5432 # default postgres port
    }
}

Lastly if you do not have any sort of database reconnection logic in your python code the migration may still fail. This is due to the fact that depends_on only waits for the container to start, but postgres will take a couple of seconds to initialze after the container is running.

In order to get around this quickly it will be easiest to run one container at a time.

i.e.:

$ docker-compose up -d db

Wait for postgres to initialize

$ docker-compose up -d web

Hopefully this gets you up and running.

like image 95
Jack Avatar answered Jan 05 '23 16:01

Jack


I was able to fix this issue simply building my db container, wait few seconds, then building the web container:

docker-compose up -d --build db

wait a few seconds

docker-compose up -d --build web

I hope this helps

like image 39
Khaled Badenjki Avatar answered Jan 05 '23 18:01

Khaled Badenjki