«Нет такого файла или каталога» сразу после его создания - PullRequest
0 голосов
/ 26 января 2020

Некоторый фон ...

Я пытаюсь создать Docker образ для блога Ghost. Я просто добавляю один модуль: адаптер хранения, чтобы изображения размещались на S3 вместо локальной файловой системы (настройка по умолчанию).

В README плагина адаптера хранения , инструкции по установке должны скопировать модуль в рабочий каталог приложения:

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

, и это работает - но только внутри контейнера. Я хочу выполнить эти шаги в сборке Docker, чтобы при перезапуске моего контейнера я не потерял эти изменения.

Проблема

В моем файле Docker у меня есть:

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

Как возможно, что "такого каталога не существует" после того, как я его только что создал?

Я пытался установить разрешения chmod при создании папки mkdir -m 777 ./content/adapters и обновлении владельца до текущего пользователя (root): RUN chown -R root ./content, но без эффекта.

Мне не удалось заставить его хотя бы собрать, изменив префиксы каталога ./, но это помещает / content в приложение root, что не там, где нужно. Когда я указываю полный путь /var/lib/ghost/content/adapters/storage, я получаю ту же ошибку. Кажется, это проблема с разрешениями, но я не знаю.

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 26 января 2020

Это типичный признак базового образа , который объявляет 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 отмечает в их ответ ) Вы можете использовать сценарий точки входа, чтобы скопировать его при запуске, после того, как какие-либо тома были присоединены к контейнеру. Обратите внимание, что изображение уже объявляет свою собственную точку входа , поэтому вам нужно это обернуть. Ваш 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, поэтому изменения в этом дереве каталогов фактически не сохраняются в образе.)

0 голосов
/ 26 января 2020

Ну, если он работает внутри вашего контейнера, вы можете написать сценарий bash в качестве точки входа, который обрабатывает это для вас. Поэтому каждый раз, когда ваш контейнер перезагружается, вы не теряете свои изменения.

...