Docker-Compose部署Python项目遇ModuleNotFoundError: No module named 'three'求助
解决Docker部署中
ModuleNotFoundError: No module named 'three'问题 问题背景
项目包含三个Python模块:one、two为独立服务,three是公共库。在根目录执行docker-compose up --build时,one和two容器启动失败,报错:
ModuleNotFoundError: No module named 'three'
项目结构:
/root-folder │ ├── one │ ├── Dockerfile │ ├── requirements.txt │ ├── __init__.py │ └── main.py │ ├── two │ ├── Dockerfile │ ├── requirements.txt │ ├── __init__.py │ └── main.py │ ├── three │ ├── Dockerfile │ ├── requirements.txt │ ├── __init__.py │ └── setup.py │ └── docker-compose.yaml
问题分析
从Docker配置来看,one和two的Dockerfile虽尝试复制three目录并执行pip install /three,但存在以下问题:
pip install未明确绑定项目虚拟环境,可能导致three未安装到运行时Python环境中- three的
setup.py中find_packages(include=['*'])参数无法精准识别目标包 - 代码复制与依赖安装顺序不合理,可能导致依赖生效失败
修复方案
方案1:修正one和two的Dockerfile安装逻辑
修改one和two的Dockerfile,明确使用虚拟环境的pip安装three,调整步骤顺序:
FROM python:3.12-slim AS builder WORKDIR /build COPY /one/requirements.txt /build/ # two的Dockerfile替换为/two/requirements.txt RUN python -m venv /opt/venv \ && /opt/venv/bin/pip install --upgrade pip setuptools wheel \ && /opt/venv/bin/pip install -r requirements.txt FROM python:3.12-slim WORKDIR /app COPY --from=builder /opt/venv /opt/venv # 先将three安装到虚拟环境 COPY /three /tmp/three RUN /opt/venv/bin/pip install /tmp/three # 再复制服务代码并安装剩余依赖 COPY /one /app # two的Dockerfile替换为/two/app RUN /opt/venv/bin/pip install -r requirements.txt ENV PATH="/opt/venv/bin:$PATH" CMD ["python", "main.py"]
方案2:修正three的setup.py包识别配置
修改three目录下的setup.py,将find_packages的include参数指定为具体包名,确保setuptools正确识别three模块:
from setuptools import setup, find_packages setup( name='three', version='0.1', packages=find_packages(include=['three']), # 替换原有的include=['*'] install_requires=[ 'avro-python3==1.10.2', ], zip_safe=False, )
方案3:复用three构建结果(可选,提升构建效率)
若项目频繁构建,可先构建three的基础镜像,让one和two复用其已安装的依赖:
- 修改
docker-compose.yaml,添加three基础镜像构建服务:
version: '3.8' services: three-base: build: ./three image: three-base:latest command: ["echo", "Three base image built"] one: container_name: container-one build: context: . dockerfile: ./one/Dockerfile args: THREE_BASE_IMAGE: three-base:latest image: one:latest ports: - "8881:8881" environment: - ENVIRONMENT=development depends_on: - three-base two: container_name: container-two build: context: . dockerfile: ./two/Dockerfile args: THREE_BASE_IMAGE: three-base:latest image: two:latest ports: - "8882:8882" environment: - ENVIRONMENT=development
- 修改one和two的Dockerfile,复用three的虚拟环境依赖:
ARG THREE_BASE_IMAGE FROM ${THREE_BASE_IMAGE} AS three-builder FROM python:3.12-slim AS builder WORKDIR /build COPY /one/requirements.txt /build/ # two的Dockerfile替换为/two/requirements.txt RUN python -m venv /opt/venv \ && /opt/venv/bin/pip install --upgrade pip setuptools wheel \ && /opt/venv/bin/pip install -r requirements.txt FROM python:3.12-slim WORKDIR /app COPY --from=builder /opt/venv /opt/venv # 复制three已安装的依赖到当前虚拟环境 COPY --from=three-builder /opt/venv/lib/python3.12/site-packages /opt/venv/lib/python3.12/site-packages COPY --from=three-builder /opt/venv/bin /opt/venv/bin ENV PATH="/opt/venv/bin:$PATH" COPY /one /app # two的Dockerfile替换为/two/app CMD ["python", "main.py"]
验证步骤
- 执行
docker-compose down -v清理旧容器和卷 - 执行
docker-compose up --build重新构建并启动服务 - 检查one和two容器日志,确认无
ModuleNotFoundError报错
内容的提问来源于stack exchange,提问作者Laodao
相关产品推荐
相关产品推荐

