首页 > 解决方案 > 可以看到 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 可以看到一个文件,它就可以访问它。我需要在这里做一些特殊的魔法吗?

标签: dockerdockerfile

解决方案


我认为如果 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
    

推荐阅读