Search code examples
djangopostgresqldockerdocker-composedjango-settings

How to connect a django app to a dockerized postgres db, both from a dockerized django and non-dockerized django using same DATABASE_HOST


I have a postgres container, docker-compose.yml:

services:
  db:
    container_name: db
    expose:
      - "5432"
    ports:
      - 5432:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data/

And a django project with settings.py:

DATABASES = {
    'default': {
        'HOST': os.environ.get('POSTGRES_HOST', '127.0.0.1')
        # etc
    }
}

.env

POSTGRES_HOST_DJANGO=db

When I run my django app locally with manage.py runserver 0.0.0.0:8000 it connects fine, using the default POSTGRES_HOST=127.0.0.1, because .env isn't loaded.

I also run my django app in a container sometimes:

docker-compose.yml:

   web:
    #restart: unless-stopped
    build: .
    env_file: .env
    command: bash -c "cd /app/src/ && python manage.py runserver 0.0.0.0:8000
    volumes: 
      - .:/app
    ports:
      - 8000:8000
    links: 
      - db:db

However it uses the .env file and connects with POSTGRES_HOST=db

If I try to connect the locally run django app with POSTGRES_HOST=db it fails:

django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known

And if I try to run the django app in a container with POSTGRES_HOST=127.0.0.1, it fails in the same way.

How can I get them to use the same POSTGRES_HOST?


Solution

  • I figured out how to do it. It wasn't getting them to use the same variable, it was to get them to read different variables based on how it was run. So:

    from docker-compose.yml

       web:
        build: .
        command: bash -c "cd /app/src/ && python manage.py runserver 0.0.0.0:8000
        env_file: .env
        environment:
          POSTGRES_HOST: db  # takes precendent over .env file
    

    And in .env:

    POSTGRES_HOST=127.0.0.1
    

    Now, when I run locally, with ./manage.py runserver, it uses the .env file and connects to the db container properly at 127.0.0.1:5342

    But if I run docker-compose up web, even though it also read the .env file, the environment variable provided in the compose file takes precedent and it uses POSTGRES_HOST: db and connects to the db container as well!