Копирование файла в Dockerfile, такого файла или каталога нет?


94

У меня есть файл Dockerfile в моей корневой (~) папке. Первые три строки моего файла выглядят так:

COPY file1 /root/folder/
COPY file2 /root/folder/
COPY file3 /root/folder/

но он возвращает следующую ошибку для каждой строки:

Данный файл или каталог отсутствует

Файлы находятся в том же каталоге, что и мой Dockerfile, и я запускаю команду docker build - < Dockerfileв том же каталоге в терминале.

Что я именно здесь делаю не так?


У меня возникла эта проблема, а затем я заметил, что файл .dockerignore игнорирует файл, который я пытался скопировать. Решение jinschubert: github.com/docker/for-mac/issues/1922
JStrahl

Ответы:


35

Инструкция COPY в Dockerfileкопирует файлы в srcк destпапке. Похоже , что вы либо с отсутствующим file1, file2и file3или пытаться строить Dockerfileиз той папки.

Обратитесь к документу Dockerfile

Также команда для создания Dockerfileдолжна быть примерно такой.

cd into/the/folder/
docker build -t sometagname .

3
Эта вторая команда не работает, говорит, что для "build" требуется один аргумент.
GreenGodot

о - обновите cmd сейчас, упоминать Dockerfile не нужно.
askb

3
После прочтения вашей ссылки я обнаружил, что DockerFile вообще не должен находиться в корневой папке. Переместил все в подкаталог, запустил команду сборки и она запустилась. Ваш ответ оказался очень полезным, поэтому отмечу его как правильный.
GreenGodot

47
Также проверьте, есть ли (нет) файл игнорирования Docker.
Тони

250

Также проверьте .dockerignoreфайл.

Я знаю, что это очень редкий случай, но я упоминал об этом файле.


3
Боже мой, спасибо. Я менял имя проекта Java (и, следовательно, артефакт и ripgrepкаталог сборки) и не выполнял поиск в файлах точек, поэтому я не видел последней надоедливой ссылки на старый каталог.
Мартин Леманн,

4
спасибо за заголовок, в моем случае я использовал мастер Visual Studio для докера, и он добавил .dockerignore с * в первой строке :(
lacripta

По какой-то причине в моем .dockerignore по умолчанию есть ** \ bin. Я уверен, что он был создан рабочим столом Docker.
Стив Смит

ахххххххх, кажется, не такой уж и редкий случай !!! За миллион лет не догадался бы. Некоторое время назад добавил каталог и полностью забыл. Причина его добавления в том, что он делает любую сборку чрезвычайно медленной, думаю, это связано с git ...
tahiche

1
о, серьезно, что это за ошибка. Большое спасибо за указание на это!
taiBsu

36

Возможно, это вызвано тем, что вы ссылаетесь на file1 / file2 / file3 как на абсолютный путь, который не находится в контексте сборки, Docker ищет путь только в контексте сборки.

Например, если вы используете COPY / home / yourname / file1, сборка Docker интерпретирует его как $ {docker build working directory} / home / yourname / file1, если здесь нет файла с таким же именем, ошибка файла или каталога не возникает.

Обратитесь к одной из проблем с докером


есть какая-то проблема с абсолютным путем, я могу только «КОПИРОВАТЬ относительный / путь / x». Я не могу "COPY / absolute / path / y.", Кто-нибудь знает почему?
Александр Миллс

8
@AlexanderMills Dockerfiles должны запускаться независимо на хост-машине и поставляться с дополнительными файлами, доступными в путях относительно Dockerfile. Использование абсолютных путей сделает его работоспособным только на вашем компьютере.
kciesielski

Это была моя проблема с ADDдирективой, спасибо.
vmonteco

Я этого не знал. Изменение его таким образом, чтобы файл был включен вместе с файлом докеров, на самом деле отлично сработал для меня. Когда он был у меня из другого источника (как полный путь, например / dir / dir2 / file), он не работал. Он работает, если он находится в каком-либо каталоге как файл докеров или его дочерние
элементы

22

Кажется, что команды:

docker build -t imagename .

а также:

docker build -t imagename - < Dockerfile2

не выполняются одинаково. Если вы хотите создать 2 образа докеров из одной папки с помощью Dockerfile и Dockerfile2, команду COPY нельзя использовать во втором примере с использованием stdin (<Dockerfile2). Вместо этого вы должны использовать:

docker build -t imagename -f Dockerfile2 .

Тогда COPY работает должным образом.


16

Запуск docker build . -f docker/development/Dockerfileсработал, что позволяет запускать файл докеров из указанного каталога, отличного от корня вашего приложения.

Используйте -fили, --fileчтобы указать имя и расположение файла Dockerfile.

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

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

Это было docker build docker/development/Dockerfileпричиной этой проблемы для меня.

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


1
docker build . -f docker/development/Dockerfileэто работает
Pradeep Surale

1
Большое спасибо - у меня это тоже сработало. Это сводило меня с ума.
x0n

4

Я только что столкнулся с этой проблемой, и ни одно из предложений здесь не решило мою проблему. Оказалось, что в моем файле были неправильные окончания строк , и мне пришлось заменить их на соответствующие окончания строк. (В этом случае из CRLF в LF, поэтому Ubuntu 14.04 распознает скрипт, который я редактировал в Windows.)

Я изменил окончания строк с помощью VSCode, и у большинства редакторов кода должна быть возможность выбирать окончания строк.

Надеюсь, это кому-то поможет.


Да, это действительно помогло :)
Роберт Смит

3

Я чувствую себя немного глупо, но моя проблема заключалась в том, что я запускал docker-compose, а мой Dockerfile находился в подкаталоге ./deploy. Моя ссылка ADD должна относиться к корню проекта, а не к Dockerfile.

Изменено: ADD ./file.tar.gz / etc / folder / в: ADD ./deploy/file.tar.gz / etc / folder /

Во всяком случае, подумал, что опубликую на случай, если кто-то столкнется с той же проблемой.


3

Вот решение и лучшая практика:

Вам нужно создать папку ресурсов, в которой вы можете хранить все ваши файлы, которые вы хотите скопировать.

├── Dockerfile
│   └── resources
│       ├── file1.txt
│       ├── file2.js

Команду для копирования файлов нужно указать так:

COPY resources /root/folder/

где

* ресурсы - ваша локальная папка, которую вы создали в той же папке, где находится Dockerfile.

* / root / folder / - папка в вашем контейнере


1

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

COPY failed: stat /<**path**> :no such file or directory

Я получил это, перезапустив службу докеров.

sudo service docker restart

1

Ошибка «Файл не найден» с Docker put_archive. Я использую Python API для докеров. Докер версии 1.12.5, сборка 7392c3b

docker.errors.NotFound: 404 Client Error: Not Found ("lstat /var/lib/docker/aufs/mnt/39d58e00519ba4171815ee4444f3c43d2c6a7e285102747398f6788e39ee0e87/var/lib/neo4j/certificates: no such file or directory")

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

con = cli.create_container(...)
cli.put_archive(...)
cli.start(con['Id'])

Если я изменю порядок работы, ошибки не возникнет, и файлы будут скопированы именно туда, где они мне нужны. Итак, я знаю, что мой код работает и делает то, что я хочу. Но важно скопировать файлы конфигурации в контейнер до его запуска. Копирование файлов после запуска приводит к тому, что контейнер запускается с конфигурацией по умолчанию, а не с пользовательской конфигурацией, которую необходимо скопировать на место перед запуском контейнера. Докер утверждает, что эта проблема закрыта, но все еще влияет на мое приложение.

Это работает; Тот же код, другой порядок выполнения.

con = cli.create_container(...)
cli.start(con['Id'])
cli.put_archive(...)

1

если вы уверены, что поступили правильно, но докер все еще жалуется, взгляните на эту проблему: https://github.com/moby/moby/issues/27134 .
Я обгорел от этого, и похоже, что перезапуск Docker Engine service docker restartпросто решит эту проблему.


1

Я искал исправление этого, и папка, которую я ДОБАВИЛ или КОПИРОВАЛА, не находилась в папке сборки, в нескольких каталогах выше или в /

Перемещение папки из-за пределов папки сборки в папку сборки устранило мою проблему.


1

один из способов не использовать стандартный ввод и сохранить контекст:

1) в вашем Dockerfile вы должны добавить

ADD /your_dir_to_copy /location_in_container

2) после этого вы должны перейти к родительскому элементу / your_dir_to_copy dir

2) затем запустите эту команду

sudo docker build . -t (image/name) -f path_of_your_dockerfile/Dockerfile

3) после того, как вы создадите свой контейнер

docker run -ti --rm cordova bash

4) После того, как вы скопируете каталог в свой контейнер


1

Предыдущие вызовы COPY могут быть связаны с изменением каталога.

COPY ./server/package.json ./server      # this passes, but the dest ./server is considered a file

COPY ./server/dist ./server/dist         # error, ./server/dist is not a directory

Добавьте завершающую косую черту к первому вызову

COPY ./server/package.json ./server/

1

Я столкнулся с этим. Копирование некоторых каталогов не помогло. Копирование файлов сделал. Оказалось, что это связано с тем, что файлы, содержащиеся в .gitignore (а не только .dockerignore), также игнорируются. См .: https://github.com/zeit/now/issues/790


Десятки ссылок на .dockerignore
Элвин

1

Я знаю, что это старое, но кое-что нужно указать. Если вы думаете, что все в порядке, проверьте свой файл .gitignore :)

У вас может быть папка локально, но если папка находится в вашем git ignore, то ее нет на сервере, а это означает, что Docker не может найти эту папку, поскольку она не существует.


1

Похоже и благодаря ответу Цлегайтиса , после

gcloud builds submit --config cloudbuild.yaml . 

это показывает

Check the gcloud log [/home/USER/.config/gcloud/logs/2020.05.24/21.12.04.NUMBERS.log] to see which files and the contents of the
default gcloudignore file used (see `$ gcloud topic gcloudignore` to learn
more).

Проверяя этот журнал, он говорит, что докер будет использовать .gitignore:

DATE Using default gcloudignore file:
# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
# ...

.gitignore

Поэтому я исправил свой .gitignore(вместо этого я использую его как белый список), и докер скопировал файл.

[Я добавил ответ, потому что у меня недостаточно репутации, чтобы комментировать]


1

У меня была эта проблема, хотя мой исходный каталог находился в правильном контексте сборки. Причина в том, что мой исходный каталог был символической ссылкой на место вне контекста сборки.

Например, мой Dockerfile содержит следующее:

COPY dir1 /tmp

Если dir1это символическая ссылка, то COPYв моем случае команда не работает.


0

Так что это случилось пару раз совсем недавно. Как разработчик .Net, используя VisualStudio Я изменил свое имя сборки из SomeThingв Somethingкачестве имени DLL , но это не меняет файл .csproj , который остаетсяSomeThing.csproj

Dockerfile использует имена файлов Linux с учетом регистра, поэтому вновь созданный автоматически Dockerfile пытался скопировать, Something.csprojно не смог найти. Итак, вручную переименовав этот файл (сделав его строчными буквами), все заработало

Но ... вот предостережение. Это изменение имени файла на моем ноутбуке с Windows не SomeThing.csprojобрабатывается Git, поэтому источник репо все еще находится в репо, и во время процесса CI / CD сборка Docker не удалась по тем же причинам ...

Мне пришлось изменить имя файла непосредственно в качестве фиксации репо .... неприятный небольшой обходной путь, но меня заставили

tl; dr Если в ОС Windows проверьте чувствительность к регистру имен файлов и имейте в виду, что локальные переименования файлов не обрабатываются при изменении Git, поэтому убедитесь, что ваше репо также изменено при использовании CI / CD


0

Здесь уже есть отличные ответы. Что сработало для меня, так это переместить комментарии на следующую строку.

ПЛОХО :

WORKDIR /tmp/app/src # set the working directory (WORKDIR), so we can reference program directly instead of providing the full path.
COPY src/ /tmp/app/src/ # copy the project source code

ХОРОШО :

WORKDIR /tmp/app/src
  # set the working directory (WORKDIR), so we can reference program directly instead of providing the full path.
COPY src/ /tmp/app/src/
  # copy the project source code
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.