Estoy usando FastAPI y postgresql para construir un back-end de API de Python simple. Cuando intento construir el archivo de migración de la base de datos (usando Alembic) ocurre este error:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) no se pudo traducir el nombre de host "db" a la dirección: Nombre o servicio desconocido
Como busqué mucho sobre este problema, parece que se debe a la configuración de mi ventana acoplable, pero no pude resolverlo. Aquí está mi código docker-compose:
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:
También sospecho de mi otro proyecto que usa docker en mi máquina local (la misma configuración con FastAPI, postgres y docker), y funciona bien y no tiene ningún problema similar.
¿Qué debo revisar y cambiar para solucionar el problema?
PD: soy un principiante en docker.
Esto es lo que está pasando:
Su contenedor web
está tratando de conectarse a db
, pero db
aún no está activo, en palabras simples, web
no puede "ver" db
.
La respuesta corta: inicie db
primero: docker-compose up -d db
luego inicie web: docker-compose up web
o lo que sea que esté ejecutando.
Ahora, la respuesta larga. Si continúa con la respuesta corta, está bien, pero es engorroso si me pregunta. Puede intentar cambiar la version
a 2.x
, por ejemplo, 2.4
y agregar depends_on
a web
, por ejemplo:
version: '2.4' services: web: ... depends_on: - db db: image: ... ...
Si solo ejecuta docker-compose up ...
, docker iniciará db
primero.
Ahora, puede encontrar otro problema: es posible que Postgres no esté listo para recibir conexiones. En este caso tendrás que esperar a que esté listo. Puede lograr esto volviendo a intentar la conexión db en caso de error (no recuerdo el error exacto, tendrá que consultar los documentos) o usar algo como pg_isready
. Suponiendo que se trata de un entorno de desarrollo, puede agregarlo a su Dockerfile instalando postgresql-client
y cambiando su cmd a:
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"