【问题标题】:Understanding Docker Context: Flask could not locate app.py, when run via docker-compose了解 Docker 上下文:通过 docker-compose 运行时,Flask 无法找到 app.py
【发布时间】:2021-07-20 09:39:48
【问题描述】:

我想让 docker-compose 启动一个“api”服务,它是一个烧瓶应用程序。我的文件夹结构是这样的:

foo/backend/
            Dockerfile
            app.py
            requirements.text
foo/
    docker-compose.dev.yml

还有一个前端文件夹,稍后我将在演示我认为我当前的策略应该奏效的原因时讨论它。

我的后端 Dockerfile 如下所示:

foo/backend/Dockerfile

# syntax=docker/dockerfile:1

FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt
COPY . .
RUN ls

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

我的 docker compose 文件如下所示:

foo/docker-compose.dev.yml

version: '3.8'

services:
 api:
  build:
   context: ./backend/
  ports:
  - 5000:5000
  volumes:
  - ./:/app

(为了清楚起见,我删除了其他服务,稍后我会参考它们)

我使用以下命令运行 docker-compose:

docker-compose -f docker-compose.dev.yml up --build

我的问题是各种错误,其中烧瓶找不到 app.py 文件。例如:

api_1       | Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.

我将RUN ls 命令添加到我的 Dockerfile 中,因为我不知道如何调试无法运行的 Docker 映像(这是正确的词汇吗?)并且后端映像无法运行,因为它失败了上述错误。 RUN ls 命令表示存在app.py

Step 6/7 : RUN ls
 ---> Running in f5f09e4805cc
Dockerfile
__pycache__
app.py
database.conf
requirements.txt

我尝试过两种方式设置环境变量:使用文件,然后在a stackoverflow answer 的方向直接作为Dockerfile 中的ENV 属性:

示例 1

foo/.dev.env

FLASK_APP=app.py

foo/docker-compose.dev.yml

version: '3.8'

services:
 api:
  build:
   context: ./backend/
  ports:
  - 5000:5000
  env_file:
  - .dev.env
  volumes:
  - ./:/app

示例 2

(考虑将文件恢复到示例 1 之前的状态)

foo/backend/Dockerfile

# syntax=docker/dockerfile:1

FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt
COPY . .
RUN ls
ENV FLASK_APP=app.py

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

机器人示例导致:

api_1       | Error: Could not import 'app'.

我怀疑这个问题与运行命令的上下文有关,但我不明白为什么它不适用于backend,而它适用于frontend。这是我的 docker-compose 的 frontend 部分:

foo/docker-compose.dev.yml

version: '3.8'

services:
 frontend:
   build:
     context: ./frontend/
   ports:
   - 8080:8080

还有我的前端 Dockerfile:

foo/frontend/Dockerfile

# syntax=docker/dockerfile:1
FROM node:16

WORKDIR /app
COPY package*.json ./

RUN yarn

COPY . .
CMD [ "yarn", "run", "serve" ]

前端正确运行并保持旋转。

如何确定运行 Dockerfile 命令的上下文?为什么我的 python CMD 无法找到 app.py 文件,在我看来,它似乎在正确的位置可见?

【问题讨论】:

  • 您的 volumes: 声明正在用其他内容覆盖容器的 /app 目录中的所有内容——Dockerfile COPY 行放入图像中的所有内容。鉴于您所展示的内容,绑定安装的内容具有不同的目录布局(例如,顶层的 backend 子目录)并且它正在破坏您的应用程序。删除volumes: 块有帮助吗?
  • (尝试docker-compose run api ls 有和没有volumes: 块以进一步调查。)
  • 是的!就是这样。我刚刚从 docker 介绍教程中盲目地复制了 volumes 位。甚至不确定目的是什么。作为一个实验,我还尝试将 api volumes 更改为 - ./backend/:/app 并且也有效,但也许我应该删除该行以确保安全?无论如何,如果您想添加您的评论作为答案,我会很乐意接受它

标签: python docker flask docker-compose dockerfile


【解决方案1】:

您有一个 volumes: 块,它用完全不同的内容覆盖容器中的 /app 目录。如果您删除该块,您将运行图像中内置的代码。

一些 Docker 教程会告诉您将主机内容绑定到映像中。这个想法是模拟实时开发环境,因此如果您更改应用程序代码,则不必重新启动应用程序。在您的情况下,您挂载到容器中的目录与您构建映像的目录不同,因此您的行为不一致。在大多数情况下,您应该能够使用实际的本地开发环境来构建您的应用程序,然后在 Docker 中运行它(无需volumes: bind-mount;运行映像中的实际代码)以进行集成测试和部署。

【讨论】:

    猜你喜欢
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    • 2020-04-25
    相关资源
    最近更新 更多