docker - 可以看到 Docker 容器中的文件,但无法访问它
问题描述
我是 Docker 新手,遇到了以下问题:
在我的 Dodckerfile 我有这些行:
ADD dir/archive.tgz /dir/
RUN tar -xzf /dir/archive2.tar.gz -C /dir/
RUN ls -l /dir/
RUN ls -l /dir/dir1/
第一个 ls 正确打印出文件,我可以看到 dir1 是由存档在 dir 内创建的,具有权限 drwxr-xr-x。但是第二个 ls 给了我: ls: "cannot access /dir/dir1/: No such file or directory"
我认为如果 Docker 可以看到一个文件,它就可以访问它。我需要在这里做一些特殊的魔法吗?
解决方案
我认为如果 Docker 可以看到一个文件,它就可以访问它。
在某种程度上你是对的,但也错过了一条信息。这些 RUN 命令不一定按顺序执行,因为 docker 在层中运行,并且您的第三个 RUN 命令会执行,而您的第一个可能会被跳过。为了保持正确的执行顺序,您需要将它们放在相同的 RUN 命令中,以便它们最终位于同一层(并一起更新):
RUN tar -xzf /dir/archive2.tar.gz -C /dir/ && \ ls -l /dir/ && \ ls -l /dir/dir1/
这是一个常见的问题,最常见的是放在 Dockerfile 中时:
RUN apt-get update RUN apt-get install some-package
而不是这个:
RUN apt-get update && \ apt-get install some-package
注意:这符合在 Dockerfile 中使用 RUN 命令的最佳实践,在此处记录:https ://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run并避免可能与缓存/层混淆...
要在此处重新创建您的问题,需要进行类似于您的类似设置的小测试,具体取决于存档中的实际目录结构,这可能会有所不同:
创建了 dir/dir1/somefile.txt 的虚拟存档 2:
mkdir -p ~/test-sowf/dir/dir1 && cd ~/test-sowf && echo "Yay" | tee --append dir/dir1/somefile.txt && tar cvzf archive2.tar.gz dir && rm -rf dir
在 ~/test-sowf 中创建的 Dockerfile 具有以下内容
from ubuntu:latest COPY archive2.tar.gz /dir/ RUN tar xvzf /dir/archive2.tar.gz -C /dir/ && \ ls -l /dir/ && \ ls -l /dir/dir/dir1/
像这样构建命令:
docker build -t test-sowf .
给出以下结果:
Sending build context to Docker daemon 5.632kB Step 1/3 : from ubuntu:latest ---> 452a96d81c30 Step 2/3 : COPY archive2.tar.gz /dir/ ---> Using cache ---> 852ef4f706d3 Step 3/3 : RUN tar xvzf /dir/archive2.tar.gz -C /dir/ && ls -l /dir/ && ls -l /dir/dir/dir1/ ---> Running in b2ab281190a2 dir/ dir/dir1/ dir/dir1/somefile.txt total 8 -rw-r--r-- 1 root root 177 May 10 15:43 archive2.tar.gz drwxr-xr-x 3 1000 1000 4096 May 10 15:43 dir total 4 -rw-r--r-- 1 1000 1000 4 May 10 15:43 somefile.txt Removing intermediate container b2ab281190a2 ---> 05b7dfe52e36 Successfully built 05b7dfe52e36 Successfully tagged test-sowf:latest
请注意,提取的文件使用 1000:1000 而不是 root:root 用于存档,因此除非您不是从其他用户(非 root)运行,否则您应该不会遇到用户问题,但是,根据您的存档,您可能会运行进入路径问题(/dir/dir/dir1 如此处所示)。
测试该文件是否正确,其中包含“Yay”:
docker run --rm --name test-sowf test-sowf:latest cat /dir/dir/dir1/somefile.txt
之后清理测试混乱(故意不使用 rm -rf 而是清理单个文件):
docker rmi test-sowf && cd && rm ~/test-sowf/archive2.tar.gz && rm ~/test-sowf/Dockerfile && rmdir ~/test-sowf
推荐阅读
- powershell - VSCode 新手,无法禁用侧边栏
- python - 如何使用 Flask 和 Sqalchemy 自动创建数据库表和模式?
- c# - c# editorconfig CA1062空值检查验证方法(用于保护子句)具有可为空的引用类型
- azure-devops - 管道中的 Azure DevOps 链接工作项
- java - 如何获取我存储在 Java 对象中的变量的已知值?
- datatable - 在powerapps中对同一列使用具有多个值的过滤器函数
- c# - C#如何递归搜索类型为x的对象
- python - 用二叉搜索树求解 S 表达式
- python - Python 3D Dataframe:按列对值进行排序并获得平均值
- javascript - 如何将用于身份验证的中间件功能从主服务器模块传递到路由器文件