0

I'm using Django 2.x and configuring it using Docker.

I'm using postresql database engine.

Dockerfile contents are

FROM python:3-alpine
RUN apk --update add libxml2-dev libxslt-dev libffi-dev gcc musl-dev libgcc curl
RUN apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev postgresql-dev
RUN apk add --no-cache bash
ENV PYTHONUNBUFFERED 1
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
RUN set -ex && mkdir /app
COPY Pipfile /app
COPY Pipfile.lock /app
WORKDIR /app
RUN pip install pipenv
RUN pipenv install --system --deploy
ADD . /app/
RUN chmod +x start.sh

# Expose port
EXPOSE 9010

docker-compose.yml file contains

version: '3'

services:
  nginx:
    image: nginx:alpine
    container_name: "originor-nginx"
    ports:
      - "10080:80"
      - "10443:43"
    volumes:
      - .:/app
      - ./config/nginx:/etc/nginx/conf.d
    depends_on:
      - web
    networks:
      - originor_web_network
  web:
    build: .
    container_name: "originor-web"
    command: ./start.sh
    volumes:
      - .:/app
    ports:
      - "9010:9010"
    depends_on:
      - db
    networks:
      - originor_web_network
      - originor_db_network
  db:
    image: postgres:11
    container_name: "originor-postgres-schema"
    volumes:
      - originor_database:/var/lib/postgresql/data
    networks:
      - originor_db_network
    environment:
      - POSTGRES_USER=originor_schema_u
      - POSTGRES_PASSWORD=ADF45sa98SD9q9we8r34&
      - POSTGRES_DB=originor_schema

networks:
  originor_web_network:
    driver: bridge
  originor_db_network:
    driver: bridge

volumes:
  originor_database:

and Django settings.py file has

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'originor_schema',
        'USER': 'originor_schema_u',
        'PASSWORD': 'ADF45sa98SD9q9we8r34&',
        'HOST': 'db',
        'PORT': '5432',
    }
}

But when I run

docker-compose up

It gives error as

originor-web | django.db.utils.OperationalError: could not connect to server: Connection refused
originor-web |  Is the server running on host "db" (172.23.0.2) and accepting
originor-web |  TCP/IP connections on port 5432?
Anuj TBE
  • 9,198
  • 27
  • 136
  • 285

3 Answers3

1

I think the problem is that your postresql is not ready when your django ap is trying to connect to it. Docker compose always starts and stops containers in dependency order, or sequential order in the file if not given. But docker-compose do not guarantee that it will wait till the dependency container is running. You can refer it from here. There is a possibility that your application may work sometimes if the database is ready when app is connecting to the db.

However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running. There’s a good reason for this.

So as recommended to overcome those inconsistencies you could use wait-for-it.sh or similar script to wrap your django app starting command. You can change the command of the web container to following after copying above script to your project root:

command: ["./wait-for-it.sh", "db:5432", "--", "./start.sh"]
Hansika Weerasena
  • 3,046
  • 1
  • 13
  • 22
  • 1
    I feel the same. Because the first time it gives this error. But next time when I re-run the `docker-compose up` it works and the database is connected. Sometimes it works for the first time as well and sometimes not. – Anuj TBE Jan 03 '19 at 10:01
  • Yes your compose file all other configurations are fine. You don't need to map any port to use services inside same network so try to use that wait-for-it.sh wrapper script with your command to overcome such application stat-up inconsistencies. – Hansika Weerasena Jan 03 '19 at 10:15
0

You have not yet configured port in your docker-compose file.

ports:
    - "5432:5432"
PPShein
  • 13,309
  • 42
  • 142
  • 227
  • You don't need to map ports since the services are inside same network `originor_db_network` – Hansika Weerasena Jan 03 '19 at 09:17
  • When I added **ports**, it works for first time but running again started giving same error again. – Anuj TBE Jan 03 '19 at 09:40
  • what do you mean *running again*? If it was working on first time, the rest should be ok. – PPShein Jan 03 '19 at 09:42
  • @PPShein running again means rebuilding the project after deleting everything from scratch. – Anuj TBE Jan 03 '19 at 09:43
  • @HansikaMadushanWeerasena `network` is just to use specific network range between `db` and `web` container. Current problem is, `db` container not yet expose `port` to other container to be linked. – PPShein Jan 03 '19 at 09:43
  • @AnujTBE Could you check as to connect that `postgres` container from your `web` container with `bash` after running it? – PPShein Jan 03 '19 at 09:46
  • Yes its working from `web` but for that I had to change database name to **postgres** in django **settings.py**. – Anuj TBE Jan 03 '19 at 09:49
  • 1
    @PPShein you do not need to expose the port to access it from same network. See this answer (And the postgres official Dockerfile has exposed the port https://github.com/docker-library/postgres/blob/f8bfec9c70f06c5fb9815653732c5d976f6f3c36/11/Dockerfile). See following answer for difference of expose and publish https://stackoverflow.com/questions/22111060/what-is-the-difference-between-expose-and-publish-in-docker – Hansika Weerasena Jan 03 '19 at 10:07
0

Just add ports

db:
    image: postgres:11
    container_name: "originor-postgres-schema"
    volumes:
      - originor_database:/var/lib/postgresql/data
    networks:
      - originor_db_network
    environment:
      - POSTGRES_USER=originor_schema_u
      - POSTGRES_PASSWORD=ADF45sa98SD9q9we8r34&
      - POSTGRES_DB=originor_schema
    ports:
      - "15432:5432"
Sergey Pugach
  • 5,561
  • 1
  • 16
  • 31