多阶段Docker构建中的COPY操作失败,文件不存在。

5
我有一个针对一个小的Jekyll网站的多阶段Dockerfile。
Dockerfile:
FROM jekyll/minimal AS build

COPY . /srv/jekyll

RUN jekyll build

FROM pierrezemb/gostatic

COPY --from=build /srv/jekyll/_site /srv/http

Docker在最后一阶段失败,出现以下错误:
Step 5/5 : COPY --from=build /srv/jekyll/_site /srv/http
COPY failed: stat /var/lib/docker/overlay2/e6b407b63b9578dd7ae4ccba968fff3f4e28e35e50e887c09319b32ccd548356/merged/srv/jekyll/_site: no such file or directory

如果我删除第二个FROM并将exec进入构建容器,则可以看到文件存在于/srv/jekyll/_site中。
2个回答

4

我已经拿到了你的Dockerfile,并按照Jekyll快速入门教程(https://jekyllrb.com/docs/)进行操作。由于你选择了jekyll/minimal基础镜像,所以我无法实际构建你的Dockerfile,但将其更改为jekyll/builder仅需进行微小调整即可使整个过程正常运行。我在/tmp文件夹中进行构建。

Truncated...
Fetching minima 2.5.0
Installing minima 2.5.0
Bundle complete! 4 Gemfile dependencies, 29 gems now installed.
Bundled gems are installed into `/usr/local/bundle`
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux-musl]
Configuration file: /tmp/_config.yml
            Source: /tmp
       Destination: /tmp/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
                    done in 0.507 seconds.
 Auto-regeneration: disabled. Use --watch to enable.
Removing intermediate container 10159e9e7776
 ---> cab3989600a7
Step 5/6 : FROM pierrezemb/gostatic
 ---> bbc54b2880be
Step 6/6 : COPY --from=build /tmp/_site /srv/http
 ---> 860f5db9d0f3
Successfully built 860f5db9d0f3
Successfully tagged test:latest

如果您发送给我一个指向您代码的GitHub链接,我可以看一下,也许您在某个地方打错了字?
(这是我的Dockerfile,它与Jekyll教程一起使用效果很好)
FROM jekyll/builder as build
WORKDIR /tmp
COPY . /tmp

RUN jekyll build

FROM pierrezemb/gostatic

COPY --from=build /tmp/_site /srv/http

这个技巧(使用/tmp)对我很有用。被接受的答案并不是真正有用的(让上游Dockerfile的创建者修改它)。 - ibz

2
看起来/srv/jekyll在你的父镜像中被定义为一个卷。如果你从那个镜像创建一个容器,那么目录将不是来自镜像,而是来自一个临时卷,导致意外行为。在构建过程中,如果你尝试使用RUN命令更改该目录的内容,那么这些更改将在运行命令结束时全部丢失,因为匿名卷已被清理。
我建议让那个镜像的上游创建者从他们的Dockerfile中删除VOLUME定义,或者分叉该存储库并构建自己的镜像而不包含该卷。你始终可以在运行时定义一个卷,而不是在镜像中定义卷,但一旦在镜像中定义了卷,你处理该目录的能力将受到该卷的影响。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接