Edgar.A
Edgar.A

Reputation: 1383

Can't connect to postgres inside docker compose

Trying to achieve simple setup flask + postgres + nginx with docker compose, everything seems to work if i remove db connection logic, but otherwise it fails to connect to database by being unable to resolve service name:

Error from the flask:

app_1       | {for debug, conn string used} postgresql://postgres:kftxx2h9mvOqhz3zyLIL-NG7RiUabFEzdCQCNtska-OmeASaSFk3frbKJMVqsZ@postgres:5432/postgres
app_1       | {for debug, start timestamp of first attempt to connect} 2018-03-25 18:38:48.898683
app_1       | Error: (psycopg2.OperationalError) could not translate host name "postgres" to address: Name or service not known
app_1       |  (Background on this error at: http://sqlalche.me/e/e3q8)
That last error repeats bunch of times, since I'm making multiple attempts to connect until it succeeds.

Postgres log:

postgres_1  | 2018-03-25 18:38:38.871 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres_1  | 2018-03-25 18:38:38.871 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres_1  | 2018-03-25 18:38:38.875 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1  | 2018-03-25 18:38:38.891 UTC [19] LOG:  database system was shut down at 2018-03-25 18:38:37 UTC
postgres_1  | 2018-03-25 18:38:38.896 UTC [1] LOG:  database system is ready to accept connections

Just to note that the problem is not postgres not being ready yet when I'm trying to make a connection (check timestamps + im attempting to make a connection multiple times in python if it fails with small delays between each)

Compose:

version: '2'
services:

  data:
    image: postgres:latest
    volumes:
      - /var/lib/postgresql
    command: "true"

  postgres:
    restart: always
    image: postgres:latest
    env_file:
      - db_env_file
    volumes_from:
      - data
    ports:
      - "5432:5432"
    expose:
      - "5432"

  app:
    restart: always
    build: ./app
    env_file:
      - app_env_file
    networks:
      - mainnet
    depends_on:
      - "postgres"
    links:
      - postgres:postgres
    volumes:
      - ./app:/usr/src/app

  nginx:
    restart: always
    build: ./nginx
    networks:
      - mainnet
    links:
      - app
    volumes:
      - ./app/static:/usr/share/nginx/html
    ports:
      - "80:8080"

networks:
    mainnet:

db_env_file

POSTGRES_USER=postgres
POSTGRES_DB=postgres
POSTGRES_PASSWORD=kftxx2h9mvOqhz3zyLIL-NG7RiUabFEzdCQCNtska-OmeASaSFk3frbKJMVqsZ
PGDATA=/var/lib/postgresql/data/app_db_data

app_env_file

PYTHONUNBUFFERED=1 APP_DB_CONNECT_STRING=postgresql://postgres:kftxx2h9mvOqhz3zyLIL-NG7RiUabFEzdCQCNtska-OmeASaSFk3frbKJMVqsZ@app_db:5432/postgres

DEBUG_ENABLE=true
APP_SECRET=5:G[m+^]`^a|>^F^t8@5r/?$}S'S$(3q"{0qZN%JH!wYlwp"~"Gcw{Wd7CP]=K&P=R6klvzcg1]"!j+EY!lYJBtR:HLlXIqg#h$Uimb8ZycZg`>(1KvdNAxV16o62sF~_$Spo1+G-c-/k"Nlv(:>d5<~=X!M2iz0kc(5xZg^*MR$S.cp^^d7osHBsz<6Xsov8-X&1]LTzscCv1G}]RUsWP@v
DB_NAME=postgres
DB_USER=postgres
DB_PASS=kftxx2h9mvOqhz3zyLIL-NG7RiUabFEzdCQCNtska-OmeASaSFk3frbKJMVqsZ
DB_SERVICE=postgres
DB_PORT=5432

Connection logic:

 print("Connecting...", file=sys.stderr)
    print(self.db_connect_string)
    print(datetime.datetime.now())
    connected = False
    connectCount = 0
    while not connected:
        if connectCount > 0:
            sleep(1.0)

        connectCount += 1
        try:
            conn = self.engine.connect()
            conn.close()
            connected = True
        except OperationalError as e:
            if connectCount > 100:
                raise

            print("Error: " + str(e), file=sys.stderr)

Tried changing connection uri to localhost instead, adding 'expose: 5432' to postgre but didn't really help

Upvotes: 4

Views: 5819

Answers (1)

CSJ
CSJ

Reputation: 2957

As your log says

app_1       | Error: (psycopg2.OperationalError) could not translate host name "postgres" to address: Name or service not known

I guess it is because you didn't set the hostname of your containers. reference here

hostname: foo

To verify this, you can check /etc/hosts in each containers. for example:

# get the containers name
docker ps
# display /etc/hosts content
docker exec -it <your_container_name> cat /etc/hosts

Moreover, since your containers join the same networks, you don't need to use links to connect each other. Legacy container links

Upvotes: 3

Related Questions