Docker中的Python脚本在子目录中找不到模块

VEr*_*PhY 2 python python-module docker

我的项目结构如下:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 my_script.Dockerfile\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.rst\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 log\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_script.log\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pickles\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requirements.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requirements_my_script.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __pycache__\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 modules\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 module.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 other_scripts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_script.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 utils\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __pycache__\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logging_utils.py\n
Run Code Online (Sandbox Code Playgroud)\n

my_script.Dockerfile如下:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 my_script.Dockerfile\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.rst\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 log\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_script.log\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pickles\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requirements.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requirements_my_script.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __pycache__\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 modules\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 module.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 other_scripts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_script.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 utils\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __pycache__\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logging_utils.py\n
Run Code Online (Sandbox Code Playgroud)\n

my_script.py:

\n
# syntax=docker/dockerfile:1\n\nFROM python:3.10-slim-buster\nWORKDIR /src\nCOPY requirements_my_script.txt requirements_my_script.txt\nRUN pip3 install -r requirements_my_script.txt\nCOPY src/. .\nCMD ["python3", "other_scripts/my_script.py"]\n
Run Code Online (Sandbox Code Playgroud)\n

和logging_utils.py:

\n
import logging\n\nfrom src.utils.logging_utils import start_logger\n\n\ndef main(logger):\n    # some code here\n    logger.info(\'done\')\n    sleep(120)\n       \n    \nif __name__==\'__main__\':\n    logger = start_logger(\'my_script.log\')\n    try:\n        logger.info(\'Starting..\')\n        main(logger)\n    except Exception as e:\n        logger.critical(\'Crashed with error: {}\'.format(e))\n
Run Code Online (Sandbox Code Playgroud)\n

这在我的机器上完美运行,但是当我构建 docker 并尝试运行它时,出现以下错误:

\n
import os\nimport logging\n\nfrom logging.handlers import RotatingFileHandler\n\ndef start_logger(filename, level=\'INFO\'): # INFO or DEBUG\n    # # LOGGING\n    log_folder = os.path.join(os.path.expanduser(\'~\'), \'project_folder_name\', \'log\')\n    if not os.path.exists(log_folder):\n            os.makedirs(log_folder)\n    log_filename = filename\n\n    logger = logging.getLogger()\n    logFormatter = logging.Formatter(fmt=\'%(asctime)s :: %(levelname)s - %(message)s\')\n    if level == \'DEBUG\':\n        logger.setLevel(logging.DEBUG)\n    else:\n        logger.setLevel(logging.INFO)\n\n    # add a rotating handler\n    handler = RotatingFileHandler(os.path.join(log_folder, log_filename), maxBytes=1000000, backupCount=1)\n    handler.setFormatter(logFormatter)\n    logger.addHandler(handler)\n    return logger\n
Run Code Online (Sandbox Code Playgroud)\n

我在 dockerfile 中尝试了几种不同的 COPY 语句,但没有成功。

\n

有人可以告诉我我做错了什么吗?

\n

编辑\n我也尝试了这个 dockerfile:

\n
from src.utils.logging_utils import start_logger\nModuleNotFoundError: No module named \'src\'\n
Run Code Online (Sandbox Code Playgroud)\n

但我得到了完全相同的错误。

\n

VEr*_*PhY 5

无需重构代码即可解决此问题的方法是在 dockerfile 中添加 ENV,如下所示:

# syntax=docker/dockerfile:1

FROM python:3.10-slim-buster
WORKDIR /app
COPY requirements_my_script.txt requirements_my_script.txt
RUN pip3 install -r requirements_my_script.txt
COPY src/ src/
ENV PYTHONPATH /app
CMD ["python3", "src/other_scripts/my_script.py"]
Run Code Online (Sandbox Code Playgroud)