【问题标题】:ModuleNotFound when running an app in Docker在 Docker 中运行应用程序时发现 ModuleNotFound
【发布时间】:2019-08-08 15:03:01
【问题描述】:

我有一个 Python3 Flask 应用程序,我想把它放到容器中。我已将 Flask 添加到 requirements.txt,它在本地工作,但在容器中找不到“flask”模块。我做错了什么?

requirements.txt:

aniso8601==7.0.0
certifi==2019.6.16
chardet==3.0.4
Click==7.0
Flask==1.1.1
Flask-RESTful==0.3.7
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
pymongo==3.8.0
pytz==2019.1
requests==2.22.0
six==1.12.0
urllib3==1.25.3
Werkzeug==0.15.4

最少的工作app.py:

from flask import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8080)

Dockerfile:

FROM python:3.7-alpine
WORKDIR /usr/src/app
RUN apk add --no-cache \
        uwsgi-python3
COPY . .
ENV TESTING TRUE
RUN pip3 install --no-cache-dir -r requirements.txt
CMD [ "uwsgi", "--socket", "0.0.0.0:3031", \
               "--uid", "uwsgi", \
               "--plugins", "python3", \
               "--protocol", "uwsgi", \
               "--wsgi", "app:app", \
               "-p", "4", \
               "--enable-threads"]

错误:

*** Operational MODE: preforking ***
Traceback (most recent call last):
  File "./app.py", line 5, in <module>
    from flask import Flask, request, Response
ModuleNotFoundError: No module named 'flask'
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***

Example of app.py(太大,无法添加到问题中)

项目结构:

├── app.py
├── docker-compose.yml
├── Dockerfile
├── LICENSE
├── logging_config.ini
├── nginx.conf
├── __pycache__
│   └── utils.cpython-37.pyc
├── README.md
├── requirements.txt
├── testing_data
│   ├─- some jsons here
├── tests.py
└── utils.py

【问题讨论】:

  • 您是否介意在您的问题中也添加一个(非常)缩短的 app.py 版本?
  • 如果您在标头中声明了 python:3.7,则不需要 pip3。尝试用 pip 替换 pip3。否则,请在此处复制您项目的文件结构。你有 .dockerignore 文件吗?
  • 添加应用示例,更改 pip 版本没有区别,我没有 .dockerignore
  • 您可以将示例应用程序减少到最低限度;这很容易适合问题,并使其更具可重复性。
  • 为了它的价值:我可以重现你的错误。如果我可以在没有CMD 部分的情况下创建相同的图像并运行它(使用-ti/bin/sh,我可以运行python3 app.py。如果我改为运行uwsgi --protocol uwsgi --plugins python3 -s 0.0.0.0:3031 --wsgi app:app,我会回到ModuleNotFoundErro再次。

标签: python docker flask


【解决方案1】:

尝试使用 pip 而不是 pip3 并尝试将 requirements.txt 显式复制到 Docker 根目录。 此外,您需要在使用它之前创建一个工作目录。

类似:

FROM python:3.7-alpine

COPY requirements.txt /
RUN pip install --no-cache-dir -r requirements.txt

RUN mkdir /app
WORKDIR /app
COPY . app/

# not sure what this is doing
RUN apk add --no-cache \
        uwsgi-python3

# ENV TESTING TRUE

CMD [ "uwsgi", "--socket", "0.0.0.0:3031", \
               "--uid", "uwsgi", \
               "--plugins", "python3", \
               "--protocol", "uwsgi", \
               "--wsgi", "app:app", \
               "-p", "4", \
               "--enable-threads"]```

【讨论】:

    【解决方案2】:

    我已尝试复制错误(不走运),但您可能仍会发现这很有用。如果您可以使用 app.py 第 1-5 行编辑您的问题,我也许可以复制它并更新我的答案。

    我已经修改了你的 Dockerfile,加入了 bash(第 5 行),这样你就可以进入容器并查看发生了什么 -

    FROM python:3.7-alpine
    WORKDIR /usr/src/app
    RUN apk add --no-cache \
            uwsgi-python3 \
            bash
    COPY . .
    ENV TESTING TRUE
    RUN pip3 install --no-cache-dir -r requirements.txt
    CMD [ "uwsgi", "--socket", "0.0.0.0:3031", \
                   "--uid", "uwsgi", \
                   "--plugins", "python3", \
                   "--protocol", "uwsgi", \
                   "--wsgi", "app:app", \
                   "-p", "4", \
                   "--enable-threads"]
    

    重建图像

    $ docker build . -t soflask
    

    将容器作为守护进程运行

    $ docker run -d --rm soflask
    $ docker ps
    
    CONTAINER ID ...
    96f341e998d4 ...
    
    $ docker exec -i -t 96f bash
    $ python
    >>> from flask import Flask
    >>>
    

    没有错误... app.py 第 1 - 5 行是什么样的?

    【讨论】:

    • 在问题中添加了示例,但这里没有什么特别的
    • 仍然可以正常工作...我会尝试停止容器(确保我正在停止 right 容器),重新构建映像,然后重新运行容器。我唯一的想法是,也许您添加到 Dockerfile 并忘记重建图像。
    • 好吧,我撞到了容器中,pip list 告诉我我已经拥有了所有需要的模块,所以这似乎是某种错误。我将只使用另一个基本容器,因为它与 alpine:3.10 一起正常工作。不是真正的答案,但可以作为解决方法
    • @biryulin04 如果它确实适用于特定版本的 Alpine,我肯定会注意到这是一个答案,即使它没有解释根本原因。搜索此问题的其他人也可能会找到您的解决方案。
    【解决方案3】:

    好吧,运行 alpine:3.10 会有所帮助,但是因为它目前带有 Python 3.6(我需要 3.7),所以我以这样的 Dockerfile 结束:

    FROM alpine:3.10
    VOLUME /usr/src/app/public
    WORKDIR /usr/src/app
    RUN apk add --no-cache python3 && \
        if [ ! -e /usr/bin/python ]; then ln -sf python3 /usr/bin/python ; fi && \
        python3 -m ensurepip && \
        rm -r /usr/lib/python*/ensurepip && \
        pip3 install --no-cache --upgrade pip setuptools wheel && \
        if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi
    RUN apk add --no-cache \
            uwsgi-python3
    COPY . .
    RUN rm -rf public/*
    ENV TESTING TRUE
    RUN pip3 install --no-cache-dir -r requirements.txt
    CMD [ "uwsgi", "--socket", "0.0.0.0:3031", \
                   "--uid", "uwsgi", \
                   "--plugins", "python3", \
                   "--protocol", "uwsgi", \
                   "--wsgi", "app:app", \
                   "-p", "4", \
                   "--enable-threads"]
    

    这个 RUN apk add --no-cache python3... 魔法取自here。不知道如何,但它确实有效。

    【讨论】:

      猜你喜欢
      • 2018-02-11
      • 2021-05-08
      • 2023-03-16
      • 2017-11-09
      • 2019-09-24
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多