烧瓶容器异常行为

时间:2020-08-06 16:08:33

标签: python docker docker-compose

我正在使用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: 更奇怪的是,绑定卷内的目录是在外部创建的。但是他们是空的!

1 个答案:

答案 0 :(得分:0)

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

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

结果,您将以/usr/src/<contents of ./flask/flask-data>结尾,因此,如果本地主机上的./flask/flask-data不包含__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"

现在,FlaskApp中将同时包含FlaskData/usr/src,但是您将需要相应地更新应用程序中的文件路径。

from Docker docs

安装到容器上的非空目录

如果将绑定安装到容器上的非空目录中,则 目录的现有内容被绑定安装遮盖了。这个可以 是有益的,例如当您想测试新版本时 应用程序而无需构建新映像。但是,也可以是 令人惊讶,而且这种行为不同于docker卷的行为。

并回答为什么绑定安装对于MySQL容器的行为有所不同-并非如此。

您将空文件夹安装到仅在容器启动后由MySQL写入数据的位置,因此这里没有什么可掩盖的,因为目标开头是空的(对于python容器,同样适用您将在容器启动后向/usr/src写一些东西,您会看到这些数据出现在./flask/flask中的本地主机上。