Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker connection error for PostGIS and Django

I am getting an error when I run PostGIS and Django in Docker. I am trying to set up a Django project to use PostGIS database.

docker-compose.yml

version: '3'
    
services:
  db:
    image: postgis/postgis
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports: 
      - 5432:5432
  web:
    build: .
    command: bash -c "
        python manage.py makemigrations
        && python manage.py migrate
        && python manage.py runserver 0.0.0.0:8000
        "
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

error message:

web_1  |   File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
web_1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
web_1  | django.db.utils.OperationalError: could not connect to server: Connection refused
web_1  |        Is the server running on host "db" (192.168.192.2) and accepting
web_1  |        TCP/IP connections on port 5432?
web_1  | 
ht_djangoapp_web_1 exited with code 1
like image 672
osakaP Avatar asked Jan 31 '26 03:01

osakaP


1 Answers

It's most likely a timing issue: your application is trying to connect to the database before the database is ready. The easiest solution here is probably to just set a restart policy on your application container, so that docker will restart it when it fails. You might as well get rid of the depends-on directive, because this is functionally useless: while docker knows when the database container is up, it knows nothing about the state of the database application itself.

  web:
    build: .
    command: bash -c "
        python manage.py makemigrations
        && python manage.py migrate
        && python manage.py runserver 0.0.0.0:8000
        "
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    restart: on-failure
      - db  web:
    build: .
    command: bash -c "
        python manage.py makemigrations
        && python manage.py migrate
        && python manage.py runserver 0.0.0.0:8000
        "
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    restart: on-failure

An alternative solution is to put a script into your application container that explicitly waits for the database to respond before starting up the web application.

The problem with this solution is that you may want to be able to restart the database container (for example, to upgrade to a newer version of postgres), in which case your application will probably fail again, unless it has reconnect logic built in. Using the restart policy is probably the better choice.

like image 153
larsks Avatar answered Feb 02 '26 17:02

larsks