Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not translate host name "db" to address using Postgres, Docker Compose and Psycopg2

In one folder I have 3 files: base.py, Dockerfile and docker-compose.yml.

base.py:

import psycopg2

conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")

Dockerfile:

FROM ubuntu:16.04

RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary

COPY base.py base.py

RUN python base.py

docker-compose.yml:

version: '3'
services:
  db:
    image: 'postgres:latest'
    expose:
      - "5432"
    environment:
      POSTGRES_PASSWORD: pw1234
      POSTGRES_DB: base123
  aprrka:
    build: .    
    depends_on:
      - db

After I ran docker-compose up, I got the following error:

Traceback (most recent call last):
  File "base.py", line 5, in <module>
conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")
   File "/usr/local/lib/python2.7/dist-packages/psycopg2/__init__.py", line 130, 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

ERROR: Service 'aprrka' failed to build: The command '/bin/sh -c python base.py' returned a non-zero code: 1

I don't know why I have this error. I exposed port 5432. By default Compose sets up a single network for app. Each service joins the default network, I think that my app with postgres should work together. Did I write incorrect docker-compose.yml?

like image 225
gongarek Avatar asked Aug 08 '18 15:08

gongarek


4 Answers

The problem is you should not be running python base.py as part of the RUN directive.

The RUN directive is executed only when you are building the image. The postgres container is not running at this point, nor has the network been created. Instead you want to use the CMD directive.

Change the Dockerfile to this:

FROM ubuntu:16.04

RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary

COPY base.py base.py

CMD ["python", "base.py"]

The above should result in the hostname db to be resolved. However if your python code doesn't have any reconnection logic for connecting to the database the container will likely still error out. This because the postgres container will be running but the database won't be ready to accept connections.

This can be temporarily fixed by adding restart: always to your docker-compose.yml.

version: '3'
services:
  db:
    image: 'postgres:latest'
    expose:
      - "5432"
    environment:
      POSTGRES_PASSWORD: pw1234
      POSTGRES_DB: base123
  aprrka:
    restart: always
    build: .    
    depends_on:
      - db

Hopefully this will get you up and running.

like image 181
Jack Avatar answered Nov 09 '22 23:11

Jack


Add database and web service on same network in docker compose file. Also link db service and start web service after starting db service.

After properly adding network, link and depends_on configuration in docker compose file issue will be fixed.

Configuration example:

  services:
      db:
          container_name: db
          networks:
              - djangonetwork
      web:
          depends_on:
             - db
          links:
             - db:db
          networks:
             - djangonetwork

  networks:
      djangonetwork:
          driver: bridge

In my docker compose file, I have used network name as 'djangonetwork', you can use any other name.

the above configuration helped me to resolve the issue 'Could not translate host name db'.

like image 29
Nivratti Boyane Avatar answered Nov 10 '22 00:11

Nivratti Boyane


If you're using docker-compose first add this line to your .yml:

environment:
  - "POSTGRES_HOST_AUTH_METHOD=trust"

After that you start only you db docker:

docker-compose up db

It should start normally with a message like:

Recreating db... done
Attaching to db
db_1           | ********************************************************************************
db_1           | WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow
db_1           |          anyone with access to the Postgres port to access your database without
db_1           |          a password, even if POSTGRES_PASSWORD is set. See PostgreSQL
db_1           |          documentation about "trust":
db_1           |          https://www.postgresql.org/docs/current/auth-trust.html
db_1           |          In Docker's default configuration, this is effectively any other
db_1           |          container on the same system.
db_1           | 
db_1           |          It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace
db_1           |          it with "-e POSTGRES_PASSWORD=password" instead to set a password in
db_1           |          "docker run".
db_1           | ********************************************************************************

ADVISE: This is NOT SAFE to do. If You decide to use this solution, make sure to list your docker file in .gitignore so you won't push this to production.

like image 12
Wagner Braga Avatar answered Nov 10 '22 00:11

Wagner Braga


if you add this to your db container in your docker-compose.yml it should resolve the issue

environment:
  - "POSTGRES_HOST_AUTH_METHOD=trust"
like image 6
helpfulT Avatar answered Nov 10 '22 00:11

helpfulT