Docker容器运行上传Python脚本时找不到__main__模块问题排查
问题分析:Docker容器执行上传Python脚本报错找不到__main__模块
问题场景
搭建FastAPI服务接收用户上传的Python脚本,通过Docker API启动新容器执行脚本,但上传测试脚本后触发内部服务器错误,核心报错信息:
docker.errors.ContainerError: Command 'timeout 3s python /tmp/script.py' in image 'python:3.8.17-slim' returned non-zero exit status 1: b"/usr/local/bin/python: can't find '__main__' module in '/tmp/script.py'\n"
错误原因
FastAPI服务运行在独立Docker容器中,代码将上传脚本保存到容器内部的/tmp/script.py,但调用Docker API启动新容器时,volumes参数指定的/tmp/script.py是宿主机的路径。由于宿主机上不存在该文件,新启动的Python容器无法找到脚本,因此Python抛出"找不到__main__模块"的错误(本质是文件不存在)。
解决方案
1. 调整文件存储与挂载逻辑
- 修改FastAPI代码,将脚本保存到宿主机与FastAPI容器共享的目录:
import os # 替换原路径为共享目录下的文件 script_path = '/app/shared/script.py' # 确保目录存在 os.makedirs(os.path.dirname(script_path), exist_ok=True) with open(script_path, 'wb') as f: f.write(await script.read()) - 在Dockerfile中提前创建共享目录:
RUN mkdir -p /app/shared - 启动FastAPI容器时,挂载宿主机目录到容器的共享路径:
docker run -it -v /var/run/docker.sock:/var/run/docker.sock -v /宿主机临时目录:/app/shared -p 8000:8000 my-python-app - 修改Docker API调用的
volumes参数,使用宿主机的共享路径:volumes={'/宿主机临时目录/script.py': {'bind': '/tmp/script.py', 'mode': 'rw'}}
2. 避免文件覆盖(可选)
多用户同时上传时会覆盖同名文件,建议生成唯一文件名:
import uuid script_name = f"{uuid.uuid4().hex}.py" script_path = f'/app/shared/{script_name}' # 启动容器时同步修改路径和命令 container = client.containers.run( 'python:3.8.17-slim', f'timeout 3s python /tmp/{script_name}', remove=True, cpu_period=100000, cpu_quota=int(float(cpu_limit) * 100000), mem_limit=mem_limit, memswap_limit=mem_limit, volumes={f'/宿主机临时目录/{script_name}': {'bind': f'/tmp/{script_name}', 'mode': 'rw'}} )
验证
重新构建镜像并启动服务,上传测试脚本后将返回预期输出:{"output": "I am python!\n"}
内容的提问来源于stack exchange,提问作者Ouroboros
相关产品推荐
相关产品推荐

