I'm using FastAPI and postgresql to build a simple python api backend. When I try to build the database migration file (using Alembic) this error occures:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not translate host name "db" to address: Name or service not known
As I searched a lot about this problem, it seems to be because of my docker config, but I couldn't figure it out. Here is my docker-compose code:
version: '3.7'
services:
web:
build: ./src
command: sh -c "alembic upgrade head && uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 8000"
volumes:
- ./src/:/usr/src/app/
ports:
- 8002:8000
environment:
- DATABASE_URL=postgresql://user:pass@db/my_db
db:
image: postgres:12.1-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=my_db
- POSTGRES_HOST_AUTH_METHOD=trust
ports:
- 5432:5432
volumes:
postgres_data:
I'm also suspicious to my other project that is using docker in my local machine (same setup with FastAPI, postgres, and docker), and it works fine and doesn't have any similar problem.
What should I check and change to fix the problem?
P.S: I'm a beginner in docker.
Here's what's happening:
Your web
container is trying to connect to db
, but db
is not up yet, in simple words web
cannot "see" db
.
The short answer: start db
first: docker-compose up -d db
then start web: docker-compose up web
or whatever you are running.
Now, the long answer. If you proceed with the short answer, that's ok, but it's cumbersome if you ask me. You could try changing the version
to 2.x
eg 2.4
and adding depends_on
to web
, example:
version: '2.4'
services:
web:
...
depends_on:
- db
db:
image: ...
...
If you just run docker-compose up ...
, docker will start db
first.
Now, you may hit another problem: postgres may not be ready to receive connections. In this case you will have to wait for it to be ready. You can achieve this by retrying the db connection on error (I don't remember the exact error, you will have to check the docs) or use something like pg_isready
. Assuming this is a dev environment, you can add it to your Dockerfile by installing postgresql-client
and changing your cmd to:
command: >
sh -c "
until pg_isready -q -h db; do sleep 1; done
&&
alembic upgrade head
&&
uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 8000"