73

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?

2
  • 2
    jack-gore's answer addresses your question. One approach for your diagnosis could have been to use a known good 2nd container to access the db. See the image's documentation on docs.docker.com and the use of the adminer image (docs.docker.com/samples/library/postgres/…). Second, the Dockerfile would benefit from reducing the number of layers created by reducing the number of RUN commands. For example RUN apt-get update && apt-get -y install python-pip (you don't need the final apt-get update). Commented Aug 8, 2018 at 16:46
  • I had the same issue, and what helped was: 1) stopping docker containers in the docker Desktop interface; 2) closing the terminal where the python script runs; 3) opening the new terminal window where the script was re-run. Commented Oct 31, 2023 at 10:42

7 Answers 7

48

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.

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

4 Comments

Thank You! It is sad but I still don't know how to fix next error. aprrka_1 | 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 connect to server: Connection refused Is the server running on host "db" (172.20.0.2) and accepting TCP/IP connections on port 5432?
This error is what the second part of my answer tried to fix. You either need to add reconnection logic to your code, add the restart: always to your compose-file. Have you tried that?
Yes I did. It works, but firsts of tryies to connect to db are unsuccessful. Do I need to type in my base.py file some 'wait time' to make connection correctly without errors? I suppose that it won't be 'better' for my whole Docker image, but it will be nicer to see how it runs. Is my sollution correct?
Yes, this is a seperate question, but you want to implement some sort of waiting mechanism in your code.
27

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'.

3 Comments

This worked for me. Keep on forgetting to add a network whenever I create a new service.
Setting a links entry of db:db seems to be superfluous, judging from the docs. What's your intention behind it?
You don't have to set the network explicitly. By default, a network is already created for multi container applications and each container join the network with its container name. docs.docker.com/compose/networking
14

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.

5 Comments

I posted this in another answer, but this is not a good idea. Its like begging to be robbed.
You completly right, however I don't see any problem if your docker won't be sent to production. Juts put the config file in gitnore and you will be fine.
This should be added as a warning in the answer then, otherwise, newcomers will think this is a perfectly fine way to do this.
@Munib Agreed and done.
And what would be the safe approach for production if having same issue?
7

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

environment: - "POSTGRES_HOST_AUTH_METHOD=trust" 

2 Comments

It will also make your database unsecure.
This is like begging to be robbed. Don't do this, not even in dev env.
0

Updating the docker compose version to 3.8 helped me

Comments

-1

Another possible scenario,

Check if ports have been used or not by other docker container. Use command:

$ docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a 

Then change your ports/expose in docker-compose file

Comments

-1

I thought I'd give an updated answer as I recently found a similar issue.

I had a similar setup where the app would connect correctly from docker running locally, but would fail when running in Jenkins.

Changing image: postgres:latest to image: postgres:13.4-alpine solved the issue.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.