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

Docker-Compose部署Flask应用遇循环导入错误求助

Flask容器启动循环导入错误解决方案

问题描述

通过docker-compose up启动Flask容器时出现以下错误:

web_1            | Traceback (most recent call last):
web_1            |   File "/app/app.py", line 3, in <module>
web_1            |     from presentation.controllers.notifications import notifications_router
web_1            |   File "/app/presentation/controllers/notifications.py", line 4, in <module>
web_1            |     from app.presentation.models.notifications_body import NotificationsBody
web_1            |   File "/app/app.py", line 3, in <module>
web_1            |     from presentation.controllers.notifications import notifications_router
web_1            | ImportError: cannot import name 'notifications_router' from partially initialized module 'presentation.controllers.notifications' (most likely due to a circular import) (/app/presentation/controllers/notifications.py)

目录结构:
项目目录结构

应用在Docker Compose外运行正常,但容器内启动时报错,相关配置及代码如下:

docker-compose.yml

version: '3.9'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "5000:5000"
    depends_on:
      - mongodb
      - rabbitmq
      - nginx

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

  mongodb:
    image: mongo:latest
    ports:
      - "27017:27017"
    environment:
      - MONGO_INITDB_DATABASE=test
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=admin
      - MONGO_URI="mongodb://admin:admin@mongodb:27017/"
    volumes:
      - mongodb_data:/data/db

  mongo-express:
    image: mongo-express:latest
    ports:
      - "8081:8081"
    environment:
      - ME_CONFIG_MONGODB_ADMINUSERNAME=admin
      - ME_CONFIG_MONGODB_ADMINPASSWORD=admin
      - ME_CONFIG_MONGODB_SERVER=mongodb
      - ME_CONFIG_MONGODB_ENABLE_ADMIN=true
      - ME_CONFIG_BASICAUTH_USERNAME=admin
      - ME_CONFIG_BASICAUTH_PASSWORD=admin
    depends_on:
      - mongodb

  rabbitmq:
    image: rabbitmq:3-management
    container_name: rabbitmq
    restart: always
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=admin
      - RABBITMQ_DEFAULT_VHOST=/
    ports:
      - 15672:15672
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
  
volumes:
  mongodb_data: 
  rabbitmq_data:

app.py

from app.infrastructure.server import entrypoint

app = entrypoint.start()

if __name__ == '__main__':
    app.run(host='0.0.0.0')

entrypoint.py

from flask import Flask

from app.infrastructure.server import url_mapping


def start():
    """
    Starts the application

    Returns:
        Flask: Flask application
    """
    app = Flask(__name__)
    app.url_map.strict_slashes = False
    url_mapping.map_routes(app)
    app.app_context().push()
    return app

url_mapping.py

from flask import Flask

from app.presentation.controllers.notifications import notifications_router
from app.presentation.controllers.ping_ctr import ping_router


def map_routes(application: Flask) -> None:
    """
    Map routes

    Args:
        application (Flask): Flask application
    """
    application.register_blueprint(ping_router)
    application.register_blueprint(notifications_router)

解决方案

1. 排查核心原因

本地与容器运行差异的根源是Python路径配置不一致:本地环境自动将项目根目录加入sys.path,而容器内路径配置错误,导致导入逻辑触发循环依赖。错误链为:
app.py → entrypoint → url_mapping → notifications_router,同时notifications.py导入模型时,因路径问题间接触发app.py的重复导入。

2. 具体修复步骤

步骤1:统一导入路径

确保所有模块使用一致的绝对/相对导入风格。修改notifications.py中的导入语句:
原代码:

from app.presentation.models.notifications_body import NotificationsBody

改为(适配容器内/app为顶层路径):

from presentation.models.notifications_body import NotificationsBody

步骤2:延迟导入避免循环

将蓝图导入逻辑移到函数内部,延迟加载以规避启动阶段的循环依赖。修改url_mapping.py:

from flask import Flask

def map_routes(application: Flask) -> None:
    """
    Map routes

    Args:
        application (Flask): Flask application
    """
    # 延迟导入蓝图,避免启动时循环依赖
    from app.presentation.controllers.ping_ctr import ping_router
    from app.presentation.controllers.notifications import notifications_router
    
    application.register_blueprint(ping_router)
    application.register_blueprint(notifications_router)

步骤3:配置容器内Python路径

在Dockerfile中明确设置项目根目录为Python路径:

WORKDIR /app
ENV PYTHONPATH=/app

确保容器内Python环境与本地保持一致。

3. 验证修复

重新构建镜像并启动容器:

docker-compose build web
docker-compose up web

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:20:20