【问题标题】:"No such file or directory" immediately after creating it创建后立即“没有这样的文件或目录”
【发布时间】:2020-01-26 08:18:37
【问题描述】:

一些背景...

我正在尝试为 Ghost 博客构建 Docker 映像。我只是添加一个模块:一个存储适配器,以便图像托管在 S3 而不是本地文件系统上(默认设置)。

storage adapter plugin的README中,安装说明是将模块复制到app的工作目录中:

npm install ghost-storage-adapter-s3
mkdir -p ./content/adapters/storage
cp -r ./node_modules/ghost-storage-adapter-s3 ./content/adapters/storage/s3

这有效——但仅限于容器的内部。我想在 Docker 构建中运行这些步骤,这样如果我的容器重新启动,我就不会丢失这些更改。

问题

在我的 Dockerfile 中,我有:

FROM ghost:3
RUN npm install ghost-storage-adapter-s3
RUN mkdir -p ./content/adapters/storage
RUN cp -r ./node_modules/ghost-storage-adapter-s3/ ./content/adapters/storage/s3

它会抛出这个错误:cp: cannot create directory './content/adapters/storage/s3': No such file or directory

当我退后一步尝试一次创建一个目录并验证它是否已创建时,即

RUN ls ./content
RUN mkdir ./content/adapters
RUN ls ./content/adapters

我收到此错误:

Step 8/10 : RUN ls ./content/adapters
 ---> Running in c55848f39bb4
ls: cannot access './content/adapters': No such file or directory
The command '/bin/sh -c ls ./content/adapters' returned a non-zero code: 2

我刚刚创建后怎么可能没有“没有这样的目录”?

我在创建文件夹 mkdir -m 777 ./content/adapters 时尝试设置 chmod 权限,并将所有者更新为我当前的用户(root):RUN chown -R root ./content,但没有效果。

我至少可以通过更改 ./ 目录前缀来构建它,但这会将 /content 放在应用程序根目录中,这不是他们需要的位置。当我指定完整路径 /var/lib/ghost/content/adapters/storage 时,我得到了同样的错误。这似乎是一个权限问题,但我不知道。

任何帮助将不胜感激。

【问题讨论】:

  • 需要使用COPY/ADD指令从宿主机复制到容器。
  • @funnydman 我不希望我的 docker 镜像依赖于宿主容器,它应该能够自己构建它需要的一切

标签: linux docker unix ghost-blog


【解决方案1】:

这是基本映像declaring a VOLUME 的安装目录的典型症状。您不能创建在该目录、插件或其他内容中包含任何其他内容的派生图像。

如果您不想重复执行此操作,则可以启动附加了一些本地存储的映像副本,运行该安装一次,然后真正使用填充的数据目录。

docker run --rm -it -v $PWD/ghost:/var/lib/ghost/content ghost:3 bash
npm install ghost-storage-adapter-s3
mkdir -p ./content/adapters/storage
cp -r ./node_modules/ghost-storage-adapter-s3/ ./content/adapters/storage/s3
exit

docker run -d -p 2368:2368 -v $PWD/ghost:/var/lib/ghost/content ghost:3

如果您想重复执行此操作(如 @Wonkledge 在their answer 中的注释),您可以在启动时使用入口点脚本将其复制到容器中,然后将任何卷附加到容器。请注意图像already declares its own entrypoint,因此您需要将其包装起来。你的 Dockerfile 可能看起来像

FROM ghost:3
RUN npm install ghost-storage-adapter-s3
COPY entrypoint-wrapper.sh /usr/local/bin
ENTRYPOINT ["entrypoint-wrapper.sh"]

和包装脚本

#!/bin/sh
mkdir -p ./content/adapters/storage
cp -r ./node_modules/ghost-storage-adapter-s3/ ./content/adapters/storage/s3
exec docker-entrypoint.sh "$@"

注意影响content 目录树的这两行如何从 Dockerfile 内部移动到容器启动之后。

(如果一个镜像声明了一个 VOLUME,那么 Docker 每次创建容器时都会在该目录上挂载一个卷,无论是否有 docker run -v 选项。在 Dockerfile 期间,您会为每个 RUN 行获得一个新的匿名卷,这就是为什么对该目录树的更改实际上不会保留在映像中。)

【讨论】:

  • 第一种方法似乎对生产使用没有意义。我无法获得第二种工作方式...当我运行docker run -it --name ghost -e url=http://localhost:2368 -p 2368:2368 myimage:tag 时,Docker 没有输出,就好像它没有运行入口点脚本一样。这是我的回购,如果有人能够看一下github.com/markjackson02/ghost-blog-with-s3-adapter非常感谢
  • entrypoint-wrapper.sh 脚本是否可执行?由于它在您的控制之下,您可以添加诸如额外的 echo 语句之类的内容,以查看它是否以及如何运行。
【解决方案2】:

好吧,如果它在您的容器内工作,您可以编写一个脚本 bash 作为入口点,为您处理它。因此,每次您的容器重新启动时,您的更改都不会丢失。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 2020-08-04
    相关资源
    最近更新 更多