anzoman
anzoman

Reputation: 129

Docker image on Django app with Postgres returns django.db.utils.OperationalError

I wanted to create a Docker image for my Django project mysite that has two apps tracks and users. I used docker build -t mysite to build my docker image. I have written a Dockerfile like it says on dockerhub. Then i created docker-compose.yml file and bash script entypoint.sh that I use in docker-compose file.

These are my files:

Dockerfile:

FROM django:onbuild

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

docker-compose.yml:

version: '3'

services:
  db:
    image: postgres
    container_name: postgres_container
    environment:
     - POSTGRES_USER=postgres
     - POSTGRES_PASSWORD=postgres
     - POSTGRES_DB=postgres
    ports:
     - 5432:5432
  web:
    image: mysite:latest
    build:
     context: .
     dockerfile: Dockerfile
    container_name: mysite_container
    ports:
      - "8000:8000"
    depends_on:
      - db
    entrypoint: /entrypoint.sh

entrypoint.sh

#!/bin/sh

python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
exec "$@"

So when I wanted to start the whole container I used following commands

docker build .
docker-compose build
docker-compose up

And my postgres_containter starts successfully, but mysite_container throws the following error:

mysite_container | Traceback (most recent call last):
mysite_container |   File "manage.py", line 22, in <module>
mysite_container |     execute_from_command_line(sys.argv)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
mysite_container |     utility.execute()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/core/management/__init__.py", line 365, in execute
mysite_container |     self.fetch_command(subcommand).run_from_argv(self.argv)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/core/management/base.py", line 288, in run_from_argv
mysite_container |     self.execute(*args, **cmd_options)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/core/management/base.py", line 335, in execute
mysite_container |     output = self.handle(*args, **options)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 79, in handle
mysite_container |     executor = MigrationExecutor(connection, self.migration_progress_callback)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/migrations/executor.py", line 18, in __init__
mysite_container |     self.loader = MigrationLoader(self.connection)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/migrations/loader.py", line 49, in __init__
mysite_container |     self.build_graph()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/migrations/loader.py", line 207, in build_graph
mysite_container |     self.applied_migrations = recorder.applied_migrations()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/migrations/recorder.py", line 61, in applied_migrations
mysite_container |     if self.has_table():
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/migrations/recorder.py", line 44, in has_table
mysite_container |     return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/backends/base/base.py", line 255, in cursor
mysite_container |     return self._cursor()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/backends/base/base.py", line 232, in _cursor
mysite_container |     self.ensure_connection()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
mysite_container |     self.connect()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/utils.py", line 89, in __exit__
mysite_container |     raise dj_exc_value.with_traceback(traceback) from exc_value
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
mysite_container |     self.connect()
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/backends/base/base.py", line 194, in connect
mysite_container |     self.connection = self.get_new_connection(conn_params)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/django/db/backends/postgresql/base.py", line 168, in get_new_connection
mysite_container |     connection = Database.connect(**conn_params)
mysite_container |   File "/usr/local/lib/python3.4/site-packages/psycopg2/__init__.py", line 130, in connect
mysite_container |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
mysite_container | django.db.utils.OperationalError: could not connect to server: Connection refused
mysite_container |      Is the server running on host "localhost" (127.0.0.1) and accepting
mysite_container |      TCP/IP connections on port 5432?
mysite_container | could not connect to server: Cannot assign requested address
mysite_container |      Is the server running on host "localhost" (::1) and accepting
mysite_container |      TCP/IP connections on port 5432?

My database in settings.py is

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

So, does anyone know why am I getting this error? My postgres is running successfully on localhost on port 5432 when I do docker-compose up, but it seems that my web container is not detecting that. What should I change in my Docker files to be able to run mysite_container properly?

EDIT: Now I added new settings_docker.py where I set my host to 'db' file and added environment variable DOCKER_SETTINGS_MODULE=mysite.settins_docker to my web service in docker-compose.yml and the container starts properly, but I don't have my database relations. So, how can I migrate those relations to docker?

Upvotes: 1

Views: 1061

Answers (2)

Andrew Graham-Yooll
Andrew Graham-Yooll

Reputation: 2258

I'm going to take a shot in the dark here and say your DATABASES setting is not correct in settings.py.

It needs to resemble:

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

For further reading here

EDIT: docker-compose.yml file adapted directly from the above link:

version: '3'

services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
  web:
    image: mysite:latest
    build:
    context: .
    dockerfile: Dockerfile
    container_name: mysite_container
    ports:
      - "8000:8000"
    depends_on:
      - db
    entrypoint: /entrypoint.sh

Upvotes: 0

H&#229;ken Lid
H&#229;ken Lid

Reputation: 23064

In the django container, the postgres container looks like a different server. You should not use localhost as the hostname. Instead use the container name. So in the django config set this:

DATABASES = {
  'default': {
    'HOST': 'db',  # container name for postgres 
     [...]

https://docs.docker.com/compose/networking/

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

Upvotes: 2

Related Questions