Home > OS >  Django application running inside of a container but cannoct resolve DB outside of it
Django application running inside of a container but cannoct resolve DB outside of it

Time:01-11

I have a Django application which I've decided to setup in container as follows:

#docker-compose.yml
version: "3.9"
services:
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db
      
  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"

volumes:
  postgres_data:

with database config in settings as follows

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

And when I run the containers, the app works correctly with me being able to migrate and insert data into database.

However when I try to run the project outside of the container by following steps:

  1. python -m venv venv
  2. source venv/bin/activate
  3. pip install -r requirements.txt
  4. python manage.py runserver

I am getting an error:

Traceback (most recent call last):
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
    self.connect()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 225, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/postgresql/base.py", line 203, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib64/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/core/management/commands/runserver.py", line 137, in inner_run
    self.check_migrations()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/core/management/base.py", line 576, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/loader.py", line 58, in __init__
    self.build_graph()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/loader.py", line 235, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
    if self.has_table():
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/recorder.py", line 57, in has_table
    with self.connection.cursor() as cursor:
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 284, in cursor
    return self._cursor()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 260, in _cursor
    self.ensure_connection()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 243, in ensure_connection
    with self.wrap_database_errors:
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
    self.connect()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 225, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/postgresql/base.py", line 203, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known

I don't really understand why django is unable to recognize the database host outside of container. Any ideas?

CodePudding user response:

You need to make the "db" container available locally, just map a local port, like this:

  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    ports:
      - '5432:5432'
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"

now you can check connection with:

psql -h localhost -p 5432

to access it from Django locally, you need to change a config to:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "HOST": "localhost",   # <----- HERE IS THE CHANGE
        "PORT": 5432,
    }
}

CodePudding user response:

In your Django setup, I'd use an environment variable to specify the database location. You can set a default value for it, and I'd generally use a developer-friendly default.

DATABASES = {
  "default": {
    "HOST": os.getenv("PGHOST", "localhost"),
    ...
  }
}

So long as your database container publishes ports:, you can use this with a host-based development setup

docker-compose up -d db

. ./venv/bin/activate
./manage.py runserver

This means you need to set the environment variable in your Compose setup as well.

version: '3.8'  # most recent 3.x Compose file version
services:
  web:
    build: .
    ports:
      - 8000:8000
    depends_on:
      - db
    environment:   # add
      PGHOST: db   # add
    # (should not need volumes: or command: override)

  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"
    ports:            # add
      - '5432:5432'   # add

volumes:
  postgres_data:

If your host system is already using port 5432 for a different database, you need to change the first ports: number to something else that doesn't conflict; the second must be fixed at the standard port 5432. You also will need to make the database port number configurable in the same way.

  • Related