2

I am developing a django app and trying to run it inside docker. I have an issue that I could not understand so far. while running the app with docker-compose, it seems that the web app cannot connect to the database when i use these configurations:

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

but once I change the host to postgres, it works. like this

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

what is the difference between postgres and localhost. One is running without and issue inside docker and not in development environment in my mac and the other one is the opposite.

# docker-compose.yml    
version: '3'

    services:
      db:
        image: postgres
        expose: 
          - "5432"
      web:
        build: .
        command: python3 manage.py runserver 0.0.0.0:8000
        volumes:
          - .:/code
        ports:
          - "8000:8000"
        depends_on:
          - db
5
  • Are you sure that that docker-compose.yml corresponds to your config 'HOST': 'postgres'? Commented Jun 19, 2017 at 16:39
  • im not sure I have understood what you mean? Commented Jun 19, 2017 at 18:43
  • I mean, viewing your docker-compose.yml it seems impossible to use "postgres" as hostname instead of "db". If it does work, we are missing some important config to undestand the hole picture. Commented Jun 19, 2017 at 18:55
  • the only missing file is the Dockerfile. which is the standard one available in docker website. and I guess its not relevant Commented Jun 19, 2017 at 22:26
  • This: 'HOST': 'postgres' will never resolve to any IP with the provided docker-compose.yml. This will: 'HOST': 'db' Commented Jun 19, 2017 at 22:54

2 Answers 2

2

Docker Compose actually add the hostnames of all your linked containers to each other.

On you machine, the postgres database is actually running in localhost, that why you have the localhost hostname.

In Compose, it's running in the postgres container, with the hostname postgres, that's why you have the postgres hostname.

If you want, you can create an entry in your host file to redirect postgres to localhost, you will then just have to use postgres everywhere.

Sign up to request clarification or add additional context in comments.

3 Comments

does that mean that if i push my production env configuration should have a host with postgres, not localhost? I find it different as I remember last year when i played with docker I was not using postgres for the host for ruby on rails applications
It depends on what you use for your production environment. If you are running your production using Compose, then the development configuration is the same for the both environment. If not, you will have to make adjustment when you deploy.
i am still not using for production, but i will. i will be running it using docker-compose. thnks
2

Each docker container comes with it's own networking namespace by default. That namespace includes it's own private loopback interface, aka localhost. And they are also attached to networks inside of docker where they have their own internal DNS entry and can talk to other containers on that same network.

When you run your application inside a container with a bridge network, localhost will point to the container, not the docker host you are running on. The hostname to use depends on your scenario:

  • To talk to other containers, use the container name in DNS.
  • If it's started by docker-compose, use the service name to talk to one of the containers in that service using DNS round robin.
  • If it's started inside of swarm mode, you can use the service name there to go to a VIP that round robin load balances to all containers providing that service.
  • And if you need to talk to the docker host itself, use a non-loopback IP address of the docker host.

2 Comments

I still don't understand why he gets a DNS for "postgres" being its service name "db"
@Robert good point, we're missing some critical detail. Perhaps a line setting the container name, or a completely different container that's running.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.