首页 > 解决方案 > 烧瓶容器异常行为

问题描述

我正在使用 docker-compose 运行一个由 mysql 支持的示例烧瓶应用程序。这是我的撰写文件。

version: "2"
services:
  webapp:
    build:
      context: ./flask/
      dockerfile: Dockerfile
    ports:
      - "8000:5000"
    env_file: 
      - ./.env
    depends_on:
      - mysqldb
    networks:
      - my-bridge1
    volumes:
      - "./flask/flask-data:/usr/src"

  mysqldb:
    build:
      context: ./mysql/
      dockerfile: Dockerfile
    env_file:
      - ./.env
    networks:
      - my-bridge1
    volumes:
      - "./mysql/db-data:/var/lib/mysql"


networks:
  my-bridge1:
    driver: bridge

问题是当我将我的应用程序目录挂载到容器之外时,有一个

**error**: __init__.py file is not found

可以在 WORKDIR 中找到。仅当我将代码卷挂载到容器外时才会出现此问题,如果我挂载任何其他目录,则应用程序可以正常工作。

这是我的应用程序的 docker 文件:

FROM python:3

RUN mkdir /usr/src/FlaskApp
RUN mkdir /usr/src/FlaskApp/code

WORKDIR /usr/src/FlaskApp/code


COPY ./code ./
RUN pip install -r ./requirements.txt

COPY FlaskApp.wsgi /usr/src/FlaskApp/

EXPOSE 5000

VOLUME /usr/src

CMD [ "python", "__init__.py" ]

我已经测试了 mysql 容器,它从容器中复制文件。但是python容器没有。

EDIT1:当我将 CMD arg 更改为“ls”时,目录为空。当我将 CMD arg 更改为“pwd”时,输出为:“/usr/src/FlaskApp/code”

EDIT2:更奇怪的是绑定卷内的目录是在外面创建的。但他们是空的!

标签: pythondockerdocker-compose

解决方案


数据也被复制到 python 容器中,但是您使用绑定挂载掩盖了这些数据。

首先,将文件复制到/usr/src/FlaskApp/codeDockerfile 中,然后在同一位置创建绑定挂载,这意味着/usr/src/现在将仅保存./flask/flask-data本地主机上的内容(绑定挂载的源)。

结果,您最终会得到/usr/src/<contents of ./flask/flask-data>,因此,如果./flask/flask-data您的 localhost 上不包含该__init__.py文件(以及您的应用程序所需的整个目录子结构),那么容器也不包含。

因此,只要您使用绑定挂载,Dockerfile 中的所有这些行基本上都无关紧要

RUN mkdir /usr/src/FlaskApp
RUN mkdir /usr/src/FlaskApp/code
WORKDIR /usr/src/FlaskApp/code
COPY ./code ./
COPY FlaskApp.wsgi /usr/src/FlaskApp/

我不确定您到底想要实现什么以及您的应用程序如何解析路径,但快速解决方法是在/usr/src(可能/usr/src/FlaskData)下创建另一个文件夹并将本地目录挂载在那里。

volumes:
      - "./flask/flask-data:/usr/src/FlaskData"

现在您将同时拥有FlaskAppFlaskData/usr/src但您需要相应地更新应用程序中的文件路径。

来自 Docker 文档

挂载到容器上的非空目录

如果您绑定挂载到容器上的非空目录,则该目录的现有内容会被绑定挂载遮盖。这可能是有益的,例如当您想在不构建新映像的情况下测试应用程序的新版本时。但是,这也可能令人惊讶,并且这种行为与 docker 卷的行为不同。

并回答为什么绑定挂载对 MySQL 容器的行为不同 - 它没有。

您将空文件夹安装到只有在容器启动后才由 MySQL 写入数据的位置,因此那里没有什么可以遮掩的,因为目标是空的(如果您要写的话,这同样适用于 python 容器在容器启动后,您会看到/usr/src这些数据出现在 localhost 中./flask/flask)。


推荐阅读