Connecting two Docker Containers Flask to PostGIS

Issue

I am new to docker so this may be a silly question. I have one docker container containing a PostGIS database and another containing a Flask App. When running the Flask app locally I have no problems connecting to the database, running migrations etc. But when I launch the Flask app into its own container, any connection results in an error like this

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?

The error suggests the database container isn’t accepting incoming traffic, but this is confusing because it does work when the incoming traffic is not from another container.

The way I run the database is by simply pulling the PostGIS image down

docker run \
        --name some-postgis \
        --publish 5432:5432 \
        --env POSTGRES_PASSWORD='password' \
        --env POSTGRES_DB='my-database' \
        -d postgis/postgis

The Dockerfile for the Flask app looks like this:

FROM python:3.8.3-slim-buster

RUN mkdir /build /app

WORKDIR /build

COPY . /build/
COPY requirements/base.txt /build/requirements/base.txt
COPY alembic.ini /build/
COPY source_files/ /build/source_files/
COPY alembic/ /build/alembic/


RUN python3 -m pip install \
    --target /app \
    --requirement ./requirements/base.txt

ENV PORT 5000
ENV PATH "/app/bin:${PATH}"
ENV PYTHONPATH /app
ENV POSTGRES_PASSWORD=password
ENV POSTGRES_USER=postgres
EXPOSE ${PORT}

RUN groupadd --gid 999 user && \
    useradd --system \
        --uid 999 \
        --gid user \
        user

USER user:user

ENV FLASK_ENV=development
ENV FLASK_APP=src/main.py
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

I have seen lots about docker compose and networks, but I have worked with prepared containers where an API is in 1 and database in another without doing that and haven’t had problems.

Any help would be appreciated.

Solution

Where is the code that tells the flask application the address of the database?

It looks to me like flask is trying to connect to localhost:5432, which will work fine in local mode as the database is accessible on localhost:5432 (docker is exposing to the host machine), but when running in a container, flask is its own host and cannot access host machine services via localhost.

Providing the above is correct, there is a couple of different ways to do it:

  • Access host machine ports (and therefore exposed ports from other containers) with "host.docker.internal:5432" instead of "localhost:5432" in flask.
  • Use docker compose or similar, name the database container e.g. postgis, and connect to "postgis:5432"
  • Create a docker network instead https://docs.docker.com/network/bridge/

Answered By – clarj

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published