Dock COPY проблема - «нет такого файла или каталога»


38

В моем Dockerfile у меня есть следующее выражение «COPY»:

# Copy app code
COPY /srv/visitor /srv/visitor

Само собой разумеется, что в моей хост-системе, в каталоге "/ srv / visitor", действительно есть мой исходный код:

[root@V12 visitor]# ls /srv/visitor/
Dockerfile  package.json  visitor.js

Теперь, когда я пытаюсь создать образ с помощью этого Dockerfile, он зависает на этапе, когда должно произойти «COPY»:

Step 10 : COPY /srv/visitor /srv/visitor
INFO[0155] srv/visitor: no such file or directory

Там написано, что такой директории нет, но она явно есть.

Любые идеи?

ОБНОВЛЕНИЕ 1:

Мне было указано, что я ошибался в том смысле, в каком я понимал контекст сборки. Предложение сводилось к тому, чтобы изменить выражение «КОПИЯ» на это:

COPY . /srv/visitor

Проблема в том, что у меня так было, и процесс сборки остановился на следующем шаге:

RUN npm install

Он сказал что-то вроде «файл package.json не найден», когда он явно есть.

ОБНОВЛЕНИЕ 2:

Я попытался запустить его с этим изменением в Dockerfile:

COPY source /srv/visitor/

Он остановился при попытке запустить npm:

Step 12 : RUN npm install
 ---> Running in ae5e2a993e11
npm ERR! install Couldn't read dependencies
npm ERR! Linux 3.18.5-1-ARCH
npm ERR! argv "/usr/bin/node" "/usr/sbin/npm" "install"
npm ERR! node v0.10.36
npm ERR! npm  v2.5.0
npm ERR! path /package.json
npm ERR! code ENOPACKAGEJSON
npm ERR! errno 34

npm ERR! package.json ENOENT, open '/package.json'
npm ERR! package.json This is most likely not a problem with npm itself.
npm ERR! package.json npm can't find a package.json file in your current directory.

npm ERR! Please include the following file with any support request:
npm ERR!     /npm-debug.log
INFO[0171] The command [/bin/sh -c npm install] returned a non-zero code: 34

Итак, была ли выполнена копия? Если да, то почему npm не может найти package.json?


Для тех, кто ищет проблему в 2017 году - это может быть ваша проблема github.com/docker/for-mac/issues/1922 . он рекомендует удалить ваш файл .dockerignore и провести повторное тестирование. Если это работает, вы можете изменить настройки в .dockerignore для решения проблемы.
определено

Ответы:


36

Из документации:

<src>Путь должен быть в контексте сборки ; Вы не можете скопировать ../something / что-то, потому что первый шаг сборки docker - это отправить каталог контекста (и подкаталоги) демону docker.

Когда вы используете, /srv/visitorвы используете абсолютный путь вне контекста сборки, даже если это на самом деле текущий каталог.

Вам лучше организовать контекст сборки следующим образом:

├── /srv/visitor
│   ├── Dockerfile
│   └── resources
│       ├── visitor.json
│       ├── visitor.js

И использовать:

COPY resources /srv/visitor/

Заметка:

docker build - < Dockerfile не имеет никакого контекста.

Следовательно, используйте,

docker build .


Я уже нахожусь в каталоге / srv / visitor моей хост-системы, и весь мой исходный код, а также файл Docker находятся здесь. Как мне написать свою инструкцию «COPY», чтобы весь этот источник копировался в каталог контейнера «/ srv / visitor»?
dsljanus

1
@dsljanus Исходный каталог или файл должен быть по отношению к контекстному сборки т.е. /srv/visitorдиректории.
Ксавье Лукас

Так должно ли быть "."? Потому что у меня так было, и процесс сборки остановился на следующем шаге, «RUN npm install». Он сказал что-то вроде «файл package.json не найден». Пожалуйста, смотрите мое обновление также.
dsljanus

2
@dsljanus И так откуда вы запускаете npm? Публикуйте весь свой докер-файл ... Между прочим, не изменяйте несколько обновлений, подобных этому, в вопросах, это действительно раздражает, переходя от одной проблемы к совершенно другой. Цель SF - опубликовать четкие вопросы, чтобы получить четкие ответы.
Ксавье Лукас,

1
@dsljanus Хорошо, вот в чем проблема, не используйте, RUN cdно используйте, WORKDIRчтобы текущий каталог запоминался между каждым шагом. Dockerfile - это не более чем оболочка для docker run + docker commit, поэтому каждый шаг выполняется независимо от предыдущего уровня. Это означает, что pwd равен /на каждом шаге, если вы не используете эту директиву.
Ксавье Лукас,

41

Для меня каталог был в правильном контексте, только он был включен в (скрытый) .dockerignoreфайл в корне проекта. Это приводит к сообщению об ошибке:

lstat mydir/myfile.ext: no such file or directory

3
ты имел ввиду .dockerignore? что только что случилось со мной
Мартин Колл

5
Будьте здоровы! Был целый каталог, который я игнорировал, о котором я забыл, и он сломал мою сборку. В качестве небольшой заметки вы можете игнорировать один файл в каталоге с помощью: !path/to/my/fileдаже если он pathнаходится в .dockerignore.
hjc1710

Это хороший.
Гудлаугур Эгильссон

Не могу выразить, как я вам благодарен за это, мучаю себя весь прошлый день. До сих пор не могу понять, почему VS Tools для докера включает в себя .dockerignore с * в нем
bilal.haider

Не могу проголосовать достаточно!
kmansoor

7

Для меня проблема заключалась в том, что я использовал docker build - < Dockerfile

Из документации Примечание: если вы строите с использованием STDIN ( docker build - < somefile), контекст компоновки отсутствует, поэтому COPY использовать нельзя.


1

Как сказал ответ Ксавье Лукаса [чрезвычайно полезный], вы не можете использовать COPY или ADD из каталога вне контекста сборки (папка, из которой вы запускаете «сборку докера», должна быть той же директорией, что и ваш .Dockerfile). Даже если вы попытаетесь использовать символическую ссылку, она не будет работать.

Примечание. Это относится к POSIX (Linux, Unix, Mac, возможно Linux Subsystem для Windows). Вы можете сделать подобное в Windows, используя JUNCTION.

cd ~/your_docker_project/
cp -al /subfolder/src_directory ./
echo "COPY src_directory /subfolder/" >> Dockerfile

Опасность: использование этого сделает ваш проект докера специфичным для хоста. Вы почти никогда не хотите этого делать! Обращаться осторожно.

Применение: обучение, эксперименты в среде разработки

Это помогло мне. cp -al копирует структуру каталогов и создает жесткие ссылки для всех файлов. Когда вы закончите, запустите «rm -rf ./src_directory», чтобы удалить его.


Моя цель: скопировать кэшированные пакеты из моей локальной файловой системы в мой образ докера. Установите нужные мне инструменты (он будет либо использовать кеш, либо загружать его новым). Затем я удаляю этот кеш в образе и удаляю жесткие ссылки на хосте. Если на хосте нет этих файлов, не стоит беспокоиться. Но у меня ограниченная пропускная способность и ограниченное дисковое пространство. Это приемлемое использование?
TamusJRoyce

1

Я столкнулся с этой проблемой и обнаружил, что смог добавить контекст в переменную сборки, чтобы загрузить свои файлы Dockerfile из других каталогов. Это позволило мне немного изменить мою файловую структуру Docker по умолчанию. Вот фрагмент моего docker-compose.yml:

version: '3'
services:
  webserver:
    build:
      context: .
      dockerfile: ./server/Dockerfile
    ...

Добавив контекст, я смог определить, куда следует ссылаться на файлы. Вы можете ссылаться на документы Docker здесь: https://docs.docker.com/compose/compose-file/#context

Надеюсь это поможет!


0

Для меня проблема заключалась в том, что имя файла, которое я добавлял, было завершающим. Переименование исправило это.


0

Для следующей ошибки,

COPY failed: stat

Я получил его, перезапустив докер-сервис.


0

Я наконец решил эту проблему, в моем случае был Dockerfile, который выполнял копирование на более глубоком уровне проекта. Итак, я понял, что путь сборки хоста выражается относительно расположения файла Dockerfile.


0

Это случилось со мной при попытке запустить файл докера из другого каталога.

Мне COPY failed: stat /var/lib/docker/tmp/docker-builder929708051/XXXX: no such file or directoryудалось решить эту проблему, указав файл докера.

Бег docker build . -f docker/development/Dockerfileсработал.

Но запуск Runningdocker build docker / development / Dockerfile` вызвал эту проблему.

-fили --fileуказать название и местонахождение Dockerfile.

Сначала это показалось странным, потому что, когда я находился Dockerfileв корневом каталоге приложений, он работал нормально. Это поможет, если вы хотите немного лучше управлять файлами Docker вашей среды.


0

Файл не только должен находиться в каталоге в текущем контексте сборки, но и файл не может быть мягкой ссылкой на файл вне контекста сборки.

У меня была ссылка на файл в моем домашнем каталоге, а ссылка была в каталоге проекта. После того, как я удалил ссылку и переместил связанный файл в проект ( rm mylink ; mv ~/myrealfile ./), он заработал.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.