2

I'm trying to connect a python flask application to a database inside a postgres docker container.

I have the below database.conf:

POSTGRES_USER=testdbuser
POSTGRES_PASSWORD=testdbpass
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=testdb

and config.py:

import os

user = os.environ['POSTGRES_USER']
password = os.environ['POSTGRES_PASSWORD']
host = os.environ['POSTGRES_HOST']
database = os.environ['POSTGRES_DB']
port = os.environ['POSTGRES_PORT']

DATABASE_CONNECTION_URI = f'postgresql+psycopg2://{user}:{password}@{host}:{port}/{database}'

and finally docker-compose.yml:

version: '3.5'
services:
  database:
    container_name: postgres-test
    image: postgres:latest
    env_file: database.conf
    ports:
      - 5432:5432
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:

The error I'm getting after docker-compose up --build -d -> export $(xargs < database.conf) -> export FLASK_APP=app.py -> flask run is:

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not translate host name "postgres" to address: nodename nor servname provided, or not known
6
  • You are forwarding the port 5432 to your local machine (localhost) but trying to connect to a different host (postgres). Commented Jun 17, 2020 at 6:20
  • @Kendas can you please let me know where I have to make the change. Commented Jun 17, 2020 at 6:22
  • I'm crafting an answer. Commented Jun 17, 2020 at 6:23
  • Have you tried just setting POSTGRES_HOST to ‘localhost’ rather than postgres? Commented Jun 17, 2020 at 6:27
  • 1
    Docker executes the instructions in an image (in this case - postgres) on your computer but sandboxed. It is not really related to the terminal you run the command on. What the docker-compose file is doing is creating an internal network where this process has the same hostname as the service name (database). It is also forwarding the port 5432 to your machine's 5432. So any time you connect to the port 5432 on your local machine, you will hit the container through the forwarded port. Commented Jun 17, 2020 at 6:42

1 Answer 1

4

The error itself gives insight:

could not translate host name "postgres" to address: nodename nor servname provided, or not known

The host postgres does not exist in DNS or your local network. SQLAlchemy is unable to connect to it. This logically the case, since you created a docker container and forwarded the port 5432 to your local machine.

There are 2 choices you can take - either use the localhost address to connect from the flask app or run the flask app as a docker-compose service.

Option 1 - use localhost

The POSTGRES_HOST environment variable does not seem to be used by the postgres docker image. So you can just change this in the environment file:

POSTGRES_USER=testdbuser
POSTGRES_PASSWORD=testdbpass
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=testdb

Option 2 - run flask using docker-compose

For this, you will need to create a simple Dockerfile and add the flask app to the docker-compose.yml file.

I suggest something simple for the Dockerfile like so:

FROM python

COPY . /app
# How you install your python packages may differ
RUN pip install -r /app/requirements.txt

# Ensure the path here is correct
ENV FLASK_APP /app/app.py

CMD flask run

Then you will need to add this to the docker-compose.yml file:

version: '3.5'
services:
  database:
    container_name: postgres-test
    image: postgres:latest
    env_file: database.conf
    ports:
      - 5432:5432
    volumes:
      - postgres-data:/var/lib/postgresql/data

  flask:
    build:
      context: .
      dockerfile: Dockerfile
    environment:  # or use env_file as you did above
      POSTGRES_USER: testdbuser
      POSTGRES_PASSWORD: testdbpass
      POSTGRES_HOST: database     # This is the name of the database service in this file above
      POSTGRES_PORT: 5432
      POSTGRES_DB: testdb
    depends_on:
      - database

volumes:
  postgres-data:

Hope this gets you going.

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

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.