我正在使用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: 更奇怪的是,绑定卷内的目录是在外部创建的。但是他们是空的!
答案 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
,但是您将需要相应地更新应用程序中的文件路径。
安装到容器上的非空目录
如果将绑定安装到容器上的非空目录中,则 目录的现有内容被绑定安装遮盖了。这个可以 是有益的,例如当您想测试新版本时 应用程序而无需构建新映像。但是,也可以是 令人惊讶,而且这种行为不同于docker卷的行为。
并回答为什么绑定安装对于MySQL容器的行为有所不同-并非如此。
您将空文件夹安装到仅在容器启动后由MySQL写入数据的位置,因此这里没有什么可掩盖的,因为目标开头是空的(对于python容器,同样适用您将在容器启动后向/usr/src
写一些东西,您会看到这些数据出现在./flask/flask
中的本地主机上。