这个问题已经被问过了,例如Docker:服务器是否在主机“localhost”(::1)上运行,并在端口5432上接受TCP/IP连接?,但我仍然无法弄清如何正确地将应用程序连接到数据库。
文件:
Dockerfile
文件:
Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY . .
RUN pip install --upgrade pip
RUN pip install "fastapi[all]" sqlalchemy psycopg2-binary
docker-compose.yml
version: '3.8'
services:
ylab:
container_name: ylab
build:
context: .
entrypoint: >
sh -c "uvicorn main:app --reload --host 0.0.0.0"
ports:
- "8000:8000"
postgres:
container_name: postgr
image: postgres:15.1-alpine
environment:
POSTGRES_DB: "fastapi_database"
POSTGRES_PASSWORD: "password"
ports:
- "5433:5432"
main.py
import fastapi as _fastapi
import sqlalchemy as _sql
import sqlalchemy.ext.declarative as _declarative
import sqlalchemy.orm as _orm
DATABASE_URL = "postgresql://postgres:password@localhost:5433/fastapi_database"
engine = _sql.create_engine(DATABASE_URL)
SessionLocal = _orm.sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = _declarative.declarative_base()
class Menu(Base):
__tablename__ = "menu"
id = _sql.Column(_sql.Integer, primary_key=True, index=True)
title = _sql.Column(_sql.String, index=True)
description = _sql.Column(_sql.String, index=True)
app = _fastapi.FastAPI()
# Create table 'menu'
Base.metadata.create_all(bind=engine)
如果我只将postgres数据库托管在容器中而我的应用程序在本地运行,则此方法有效,但是如果数据库和应用程序位于它们自己的容器中,无论我如何更改设置,错误都会出现:
"sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) 连接到位于“localhost”(127.0.0.1),端口5433的服务器失败:连接被拒绝 ylab | 该服务器是否正在运行并接受TCP / IP连接? ylab | connection to server at "localhost" (::1), port 5433 failed: Cannot assign requested address ylab | 该服务器是否正在运行并接受TCP / IP连接?"
这个错误会在以下位置出现:
Base.metadata.create_all(bind=engine)
我也尝试过
DATABASE_URL = "postgresql://postgres:password@postgres:5433/fastapi_database"
但仍然出现错误:
"sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) 连接到服务器“postgres”(172.23.0.2),端口5433失败:连接被拒绝 ylab | 该主机上是否正在运行服务器并接受TCP/IP连接?"
在上面的答案中提到了某种配置文件或其他内容,但我无法弄清楚如何管理该配置。
DATABASE_URL = "postgresql:// postgres:password @ postgres:5432 / fastapi_database"
,那会发生什么呢? 在应用程序在本地运行且postgres在容器中的第一个示例中,这可行,因为您将“localhost:5433”映射到postgres容器端口“5432”。 当您尝试在应用程序容器中执行此操作时,它不起作用,因为数据库不在应用程序容器中本地运行。 当您将“localhost”更改为“postgres”时,这将开始以正确的容器对准db,但是容器内运行的db端口为5432而不是5433。 - Chris Doyle