You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose运行FastAPI项目报ModuleNotFoundError错误求助

问题背景
  • 项目为Docker学习练习项目,技术栈为Python + FastAPI,通过Dockerfile、Docker Compose完成容器编排,对接PostgreSQL数据库,使用SQLAlchemy作为ORM框架
  • 本地命令行直接启动项目运行正常,通过Docker Compose启动时先后抛出两类模块找不到的异常:
    1. 首个报错:
    ModuleNotFoundError: No module named 'routers'
    
    1. 尝试修复首个问题后出现第二个报错,且一直未解决:
    ModuleNotFoundError: No module named 'sqlalchemy'
    
  • 已确认requirements.txt中已正确声明SQLAlchemy依赖:
    SQLAlchemy==1.4.39
    
现有代码与配置
  • 主入口文件main.py:
from fastapi import FastAPI

from .routers import roles

app = FastAPI()


app.include_router(roles.router)
  • 路由模块代码:
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from db.postgres_connection import SessionLocal, engine
from models import roles
from schemas import roles as schemas

roles.Base.metadata.create_all(bind=engine)
router = APIRouter()


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


@router.get('/api/v1/roles/', response_model=list[schemas.RoleBase])
async def get_roles(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    roles = get_roles(db, skip=skip, limit=limit)
    return roles
  • Dockerfile配置:
FROM python:3.10.5-slim-buster
WORKDIR /code

COPY ./app ./code/app
COPY ./requirements.txt /code/

RUN pip install -r requirements.txt
EXPOSE 8000

CMD [ "uvicorn", "app.main:app", "--reload" ]
  • docker-compose.yml配置:
version: '3.9'
services:
  web:
    build: .
    ports:
      - '8000:8000'
    volumes:
      - .:/app

  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: hamel
      POSTGRES_PASSWORD: contrasena
      POSTGRES_DB: bankmel
    volumes:
      - /home/isla/storage:/var/lib/postgresql/data
    ports:
      - '5432:5432'
  • 项目目录结构参考:
    项目目录结构截图
问题根因

一共3处核心配置/代码错误,直接触发上述两个报错,还存在隐性运行bug:

  1. Dockerfile COPY路径配置错误
    WORKDIR已设置为/code,COPY ./app ./code/app会将本地app目录复制到容器内/code/code/app路径,和启动命令指定的app.main:app导入路径不匹配,直接触发routers模块找不到的报错。
  2. Docker Compose卷挂载路径错误
    配置的- .:/app挂载路径和容器工作目录/code不一致:镜像构建时依赖是安装在/code目录下的,挂载后容器运行时的Python路径不包含依赖安装位置,直接触发sqlalchemy模块找不到的报错。
  3. 隐性代码bug:路由接口函数递归调用自身
    get_roles接口内部再次调用get_roles(),就算模块问题修复,请求接口时也会触发递归深度超限的错误。
  4. 额外隐性配置问题:uvicorn未指定--host 0.0.0.0,启动后宿主机无法访问8000端口;数据库连接如果写localhost会无法连通PostgreSQL容器,需要用Compose服务名db作为数据库地址。
修复方案
  1. 修正Dockerfile配置,优化构建缓存:
FROM python:3.10.5-slim-buster
WORKDIR /code

# 先复制依赖文件,利用Docker层缓存避免每次改代码都重装依赖
COPY ./requirements.txt /code/
RUN pip install --no-cache-dir -r requirements.txt

# 复制项目代码到工作目录下的app文件夹
COPY ./app /code/app

EXPOSE 8000
# 加--host 0.0.0.0允许外部访问
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload"]
  1. 修正docker-compose.yml配置,修正挂载路径、添加服务依赖、使用命名卷:
version: '3.9'
services:
  web:
    build: .
    ports:
      - '8000:8000'
    volumes:
      # 挂载本地代码到容器工作目录,实现热重载
      - .:/code
    # 等数据库启动后再启动web服务
    depends_on:
      - db
    # 配置数据库连接地址,用服务名db连接PostgreSQL
    environment:
      - DATABASE_URL=postgresql://hamel:contrasena@db:5432/bankmel

  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: hamel
      POSTGRES_PASSWORD: contrasena
      POSTGRES_DB: bankmel
    volumes:
      # 用命名卷代替本地绝对路径,跨环境兼容性更好
      - postgres_data:/var/lib/postgresql/data
    ports:
      - '5432:5432'

volumes:
  postgres_data:
  1. 修正路由代码的递归调用bug:
@router.get('/api/v1/roles/', response_model=list[schemas.RoleBase])
async def get_roles(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    # 替换原递归调用,直接编写数据库查询逻辑
    role_list = db.query(roles.Role).offset(skip).limit(limit).all()
    return role_list
  1. 清理旧缓存重新部署:
    执行以下命令清理旧容器、缓存,重新构建启动:
    docker compose down -v
    docker compose build --no-cache
    docker compose up -d
    

内容的提问来源于stack exchange,提问作者cosmos multi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:18:46