GerardJP
GerardJP

Reputation: 1015

psycopg2.OperationalError: could not translate host name 'db' (While name 'db' is pingable in container)

There's a lot of dated information out there on similar issues, which I all went through. I'm running docker-compose file version 3.8. My issue is that:

psycopg2 or Django can not resolve my database's container name.

However, I can after a docker-compose up:

gerard@solace ~$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
21bcbcc35083        project_web            "/app/entrypoint.sh …"   6 seconds ago       Up 6 seconds        0.0.0.0:8006->8000/tcp   project_web_1
a92e3e98477f        postgres:12.0-alpine   "docker-entrypoint.s…"   7 seconds ago       Up 6 seconds        0.0.0.0:5432->5432/tcp   project_db_1

gerard@solace ~$ docker exec -it project_web_1 ping -c 2 db
PING db (172.25.0.2): 56 data bytes
64 bytes from 172.25.0.2: seq=0 ttl=64 time=0.078 ms
64 bytes from 172.25.0.2: seq=1 ttl=64 time=0.302 ms

--- db ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.078/0.190/0.302 ms```

Also, my entrypoint.sh connects before continuing, and does continu so host and port seems accessible:

Entrypoint snippet:

    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 1
    done

What am I missing?

To be complete. I've 'verbosed' everything in the webcontainer to make sure everything comes in from the .env files and what not, and everything looks good

db_1   | 2020-11-15 14:35:18.557 UTC [1] LOG:  starting PostgreSQL 12.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 8.3.0) 8.3.0, 64-bit
db_1   | 2020-11-15 14:35:18.557 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2020-11-15 14:35:18.557 UTC [1] LOG:  listening on IPv6 address "::", port 5432
web_1  | Waiting for postgres...
web_1  | PostgreSQL started
db_1   | 2020-11-15 14:35:18.559 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2020-11-15 14:35:18.575 UTC [18] LOG:  database system was shut down at 2020-11-15 14:35:16 UTC
db_1   | 2020-11-15 14:35:18.580 UTC [1] LOG:  database system is ready to accept connections
web_1  | YO: -----------------------------------------
web_1  | SQL_ENGINE ('django.db.backends.postgresql',)
web_1  | SQL_DATABASE ('diff_api_d',)
web_1  | SQL_HOST ('db',)
web_1  | SQL_PORT 5432
web_1  | SQL_USER ('diff_api_u',)
web_1  | SQL_PASSWORD ('diff_api_p',)
web_1  | Traceback (most recent call last):
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 220, in ensure_connection
web_1  |     self.connect()
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
web_1  |     return func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 197, in connect
web_1  |     self.connection = self.get_new_connection(conn_params)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
web_1  |     return func(*args, **kwargs)
web_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 185, in get_new_connection
web_1  |     connection = Database.connect(**conn_params)
web_1  |   File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
web_1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
web_1  | psycopg2.OperationalError: could not translate host name "('db'" to address: Name does not resolve
web_1  | could not translate host name ")" to address: Name does not resolve

Upvotes: 1

Views: 2391

Answers (1)

GerardJP
GerardJP

Reputation: 1015

As it turns out (if not always), it was a typo. I've moved the database settings away from the DATABASES dict to setting them at the top as individual declarations.

DATABASES = {
    'default': {
        "ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
        "NAME": os.environ.get("SQL_DATABASE", os.path.join(BASE_DIR, "db.sqlite3")),
        "USER": os.environ.get("SQL_USER", "user"),
        "PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
        "HOST": os.environ.get("SQL_HOST", "localhost"),
        "PORT": os.environ.get("SQL_PORT", "5432")
    }
}

The issue was I forgot to remove the trailing comma's. Making them a tuple instead of a string.

# check the trailing comma
SQL_HOST = os.environ.get("SQL_HOST"),

Thanks to Adrian for finding the proverbial needle.

Upvotes: 1

Related Questions