在本地主机的 Docker 中找不到生成的文件
Cannot find generated files in the Docker in the localhost
让我们考虑这样的目录。 (注:一个目录以\
结尾)
root\
|
-- some stuff
|
-- application\
| |
| -- app_stuff
| |
| -- out\
| |
| -- main.cpp
|
-- some stuff
我正在尝试通过 docker 构建此应用程序。
Dockerfile 看起来像:
FROM emscripten/emsdk:latest
RUN apt-get -q update
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN em++ application/main.cpp -o application/out/app.html
RUN pip3 install aiohttp
RUN pip3 install aiohttp_jinja2
RUN pip3 install jinja2
RUN ls application/out
docker-compose 看起来像:
version: '3.8'
services:
application:
build: .
volumes:
- ./application/out:/app/application/out
command: python3 application/entry.py
ports:
- "8080:8080"
正如您可能在 Dockerfile (RUN em++ application/main.cpp -o application/out/app.html
) 中注意到的那样,而 docker 正在处理它,它会在 out
目录中生成新文件。但是,完成后我找不到那些文件。
注意:这些文件出现在application\out
容器中。
...
Step 10/10 : RUN ls application/out
---> Running in 603f6b99f4b0
app.html
app.js
app.wasm
...
我哪里认错了?
一个Docker-compose卷可以link主机上的目录到容器内的目录。您正在 覆盖 容器内的 /app/application/out
目录,其中包含主机 ./application/out
的卷,有效地擦除任何内容/app/application/out
个来自您构建的图像。
鉴于上下文,我假设您的主机的 ./application/out
目录是空的,并且您正在覆盖容器的 /app/application/out
目录。您可以通过删除 volumes
标记来测试这一点,然后查看应用程序是否能够在之后找到 /app/application/out
下的文件。
与您的问题无关,考虑到您的 apt-get update
命令将在您构建的映像中缓存 Debian 远程存储库列表;这会浪费 space 到您的最终图像。请参阅 this post 关于删除缓存列表的信息。
Dockerfile 给出了如何构建 docker 图像的说明,而不是实时容器中发生的事情。
如果您通过 docker-compose 或通过 docker 运行 命令挂载卷,无论哪种方式,卷都只会在容器创建后挂载。
所以发生的事情是
- 首先docker创建镜像执行Dockerfile中的命令,并将镜像存储为镜像
- 然后 docker 将使用存储的图像创建一个容器
- 然后 docker 将装载您在 docker-compose.yml 文件中定义的卷。 (此时如果目标目录中已经存在任何东西,要么挂载失败,要么将目标目录的原始内容移动到'lost-and-found'目录)
- 那么入口点或 cmd 命令是 运行(所以这里是 python3 application/entry.py)
因此,如果您需要在主机目录中获取输出文件,您要么需要在入口点脚本中创建这些文件,要么将它们复制到入口点脚本中
因此您可以使用以下内容创建一个名为 myscript.sh
的文件
#!/bin/bash
em++ /app/application/main.cpp -o /app/application/out/app.html
python3 /app/application/entry.py
在您的 Dockerfile 中,您删除行 RUN em++ application/main.cpp -o application/out/app.html
并将其替换为
COPY ./myscript.sh /
ENTRYPOINT /myscript.sh
然后从 docker-compose.yml 文件中删除行 command: python3 application/entry.py
。
如果您愿意,可以使用 CMD 命令而不是 ENTRYPOINT,这只是个人喜好问题。
让我们考虑这样的目录。 (注:一个目录以\
结尾)
root\
|
-- some stuff
|
-- application\
| |
| -- app_stuff
| |
| -- out\
| |
| -- main.cpp
|
-- some stuff
我正在尝试通过 docker 构建此应用程序。 Dockerfile 看起来像:
FROM emscripten/emsdk:latest
RUN apt-get -q update
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN em++ application/main.cpp -o application/out/app.html
RUN pip3 install aiohttp
RUN pip3 install aiohttp_jinja2
RUN pip3 install jinja2
RUN ls application/out
docker-compose 看起来像:
version: '3.8'
services:
application:
build: .
volumes:
- ./application/out:/app/application/out
command: python3 application/entry.py
ports:
- "8080:8080"
正如您可能在 Dockerfile (RUN em++ application/main.cpp -o application/out/app.html
) 中注意到的那样,而 docker 正在处理它,它会在 out
目录中生成新文件。但是,完成后我找不到那些文件。
注意:这些文件出现在application\out
容器中。
...
Step 10/10 : RUN ls application/out
---> Running in 603f6b99f4b0
app.html
app.js
app.wasm
...
我哪里认错了?
一个Docker-compose卷可以link主机上的目录到容器内的目录。您正在 覆盖 容器内的 /app/application/out
目录,其中包含主机 ./application/out
的卷,有效地擦除任何内容/app/application/out
个来自您构建的图像。
鉴于上下文,我假设您的主机的 ./application/out
目录是空的,并且您正在覆盖容器的 /app/application/out
目录。您可以通过删除 volumes
标记来测试这一点,然后查看应用程序是否能够在之后找到 /app/application/out
下的文件。
与您的问题无关,考虑到您的 apt-get update
命令将在您构建的映像中缓存 Debian 远程存储库列表;这会浪费 space 到您的最终图像。请参阅 this post 关于删除缓存列表的信息。
Dockerfile 给出了如何构建 docker 图像的说明,而不是实时容器中发生的事情。
如果您通过 docker-compose 或通过 docker 运行 命令挂载卷,无论哪种方式,卷都只会在容器创建后挂载。
所以发生的事情是
- 首先docker创建镜像执行Dockerfile中的命令,并将镜像存储为镜像
- 然后 docker 将使用存储的图像创建一个容器
- 然后 docker 将装载您在 docker-compose.yml 文件中定义的卷。 (此时如果目标目录中已经存在任何东西,要么挂载失败,要么将目标目录的原始内容移动到'lost-and-found'目录)
- 那么入口点或 cmd 命令是 运行(所以这里是 python3 application/entry.py)
因此,如果您需要在主机目录中获取输出文件,您要么需要在入口点脚本中创建这些文件,要么将它们复制到入口点脚本中
因此您可以使用以下内容创建一个名为 myscript.sh
的文件
#!/bin/bash
em++ /app/application/main.cpp -o /app/application/out/app.html
python3 /app/application/entry.py
在您的 Dockerfile 中,您删除行 RUN em++ application/main.cpp -o application/out/app.html
并将其替换为
COPY ./myscript.sh /
ENTRYPOINT /myscript.sh
然后从 docker-compose.yml 文件中删除行 command: python3 application/entry.py
。
如果您愿意,可以使用 CMD 命令而不是 ENTRYPOINT,这只是个人喜好问题。