Docker容器Python2.7升级3.7后运行脚本提示No module named boto3
问题核心原因
boto3被安装在了临时激活的虚拟环境中,运行脚本时未使用该虚拟环境的Python解释器,也没有将虚拟环境的执行路径加入全局环境变量。
具体错误点
- Docker的每个RUN指令都是独立shell会话,RUN内执行的
source env-env/bin/activate仅对当前RUN语句生效,RUN执行完成后环境自动重置,后续运行脚本时不会自动进入该虚拟环境 - 两处RUN指令重复执行
python3 -m venv env-env,会覆盖之前创建的虚拟环境,第一次安装的boto3会被直接清空 - 配置的PATH仅添加了
~/.local/bin,未包含虚拟环境的bin目录,系统无法识别虚拟环境内安装的依赖包
解决方案
二选一即可,推荐优先使用方案1,Docker本身已提供环境隔离能力,无需额外嵌套虚拟环境。
方案1:移除虚拟环境,全局安装依赖
修正后的Dockerfile如下:
ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1 RUN apk add --update --no-cache build-base python3-dev python3 libffi-dev libressl-dev bash git gettext ca-certificates curl groff less zip libstdc++ jq py3-pip\ && pip3 install --upgrade pip six awscli awsebcli boto3 pytz tzlocal \ && rm -rf /var/cache/apk/* RUN apk update && \ apk add --no-cache git openssh perl ENV PATH "$PATH:/root/.local/bin" ADD deployment-scripts /opt/deployment-scripts
方案2:保留虚拟环境,将虚拟环境路径加入全局PATH
如果必须使用虚拟环境,修正后的Dockerfile如下:
ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1 RUN apk add --update --no-cache build-base python3-dev python3 libffi-dev libressl-dev bash git gettext ca-certificates curl groff less zip libstdc++ jq py3-pip\ && pip3 install --upgrade six awscli awsebcli \ && rm -rf /var/cache/apk/* # 仅创建一次虚拟环境,所有依赖统一安装 RUN apk --no-cache add python3 py3-pip git openssh perl \ && python3 -m venv /opt/env-env \ && /opt/env-env/bin/pip install --upgrade pip boto3 pytz tzlocal # 虚拟环境bin目录加入全局PATH,默认调用虚拟环境内的Python/pip ENV PATH "/opt/env-env/bin:/root/.local/bin:$PATH" ADD deployment-scripts /opt/deployment-scripts
验证方法
部署完成后可执行以下命令确认配置生效:
- 执行
which python3确认使用的是预期的Python解释器路径 - 执行
python3 -c "import boto3; print(boto3.__file__)"确认boto3可正常导入
内容的提问来源于stack exchange,提问作者Ramesh Raj
相关产品推荐
相关产品推荐

