我是Docker的新手并遇到了以下问题:
在我的Dodcker文件中,我有以下几行:
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在dir中创建的,具有权限drwxr-xr-x。但第二个ls给了我: ls:“无法访问/ dir / dir1 /:没有这样的文件或目录”
我认为如果Docker可以看到一个文件,它就可以访问它。我需要在这里做一些特殊的魔法吗?
答案 0 :(得分:1)
我认为如果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并避免可能与缓存/ layes混淆...
要重新创建您的问题,这里的小测试类似于您的类似设置,具体取决于您的存档中的实际目录结构,这可能会有所不同:
创建了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