0
votes

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.

1
how are you running this?snahor
docker-compose up --build @snahorSaeed Esmaili

1 Answers

0
votes

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"