I have a project structure like this
project-root/
back/
Dockerfile
docker-compose.yaml
.env
Where docker-compose.yaml
has
services:
postgres:
image: postgres:latest
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- ${POSTGRES_PORT}:${POSTGRES_PORT}
volumes:
- ./data:/var/lib/posgresql/data
flask_app:
network_mode: "host"
build:
context: ./back
dockerfile: Dockerfile
ports:
- ${FLASK_PORT}:${FLASK_PORT}
environment:
FLASK_ENV: "development"
depends_on:
- postgres
volumes:
- ./back:/app
And my Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
ENV FLASK_APP=main.py
CMD if [ "$FLASK_ENV" = "development" ]; then flask --debug run; else flask run; fi
and .env
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
FLASK_PORT=5000
But my flask app is unable to connect to postgres with the following error:
psycopg2.OperationalError: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
Is the server running locally and accepting connections on that socket?
Regular python scripts ran from my host like seed scripts and integration tests are able to connect to postgres with no problem. And when I move everything under /back
the flask app within docker can connect as well. But I would like docker-compose.yaml
to live in the project root so I can build out a frontend and connect all the pieces together.
There must be some docker compose networking piece that I haven’t been able to figure out.
Any input is appreciated. Thanks!
You should remove the network_mode: host
line for your Flask application and use postgres
as the database host provided in your Flask application, as according to the documentation :
Each container for a service joins the default network and is both
reachable by other containers on that network, and discoverable by
them at a hostname identical to the container name.
By default, the container’s name is the name of the service
, but you can override this behavior using container_name.
Keep in mind that localhost
should only be used when you’re trying to reach containers from your host machine, as long as you’ve exposed the ports of the container. Otherwise containers can join each other using container_name
.