КОПІЮВАННЯ файлу в Dockerfile, такого файлу чи каталогу немає?


94

У мене кореневий файл Docker встановлений у моїй кореневій папці (~). Перші три рядки мого файлу виглядають так:

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 Doc

Також команда для побудови Dockerfileповинна бути щось на зразок.

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

3
Ця друга команда не вдається для мене, і каже, що "build" вимагає одного аргументу.
GreenGodot

о - оновіть cmd зараз, не потрібно згадувати файл Docker.
askb

3
Я належним чином прочитав ваше посилання, що DockerFile взагалі не повинен знаходитися в кореневій папці. Перемістив усе в підкаталог, запустив команду build і вона запускається. Ваша відповідь була найбільш корисною, тому я позначу її як правильну.
GreenGodot

47
Також перевірте, чи є (немає) файл Docker Ignore.
Тоні

251

Перевірте .dockerignoreфайл теж.

Я знаю, що це дуже рідкісний випадок, але я мав там згаданий файл.


3
о боже, дякую. Я міняв назву проекту Java (і, отже, артефакт та каталог побудови), і ripgrepне шукаю у файлах точок, тому я не бачив останнього докучливого посилання на старий каталог.
Martin Lehmann

4
дякую за headsup, у моєму випадку я використовував майстер візуальної студії для докера, і він додав .dockerignore із * у перший рядок :(
lacripta

З якихось причин у моєму .dockerignore за замовчуванням є ** \ bin. Я впевнений, що це було створено робочим столом Docker.
Стів Сміт,

ahhghgghghg здається все-таки не таким вже рідкісним випадком !!!. Не зрозумів би це за мільйон років. Додав каталог трохи назад і зовсім забув. Причиною його додавання є те, що це робить будь-яку збірку надзвичайно повільною, думаю, це пов’язано з git ...
tahiche

1
ой серйозно, яка це помилка. велике спасибі, що вказали на це!
taiBsu

36

Можливо, це спричинено тим, що ви посилаєтесь на файл1 / файл2 / файл3 як на абсолютний шлях, який не знаходиться в контексті побудови, Docker шукає лише шлях у контексті побудови.

Наприклад, якщо ви використовуєте COPY / home / yourname / file1, Docker build інтерпретує це як $ {docker build робочий каталог} / home / yourname / file1, якщо тут немає файлу з таким іменем, не виникає помилка файлу або каталогу.

Зверніться до однієї з проблем докера


існує якась проблема абсолютного шляху, я можу лише "КОПІЮВАТИ відносний / шлях / х". Я не можу "COPY / absolute / path / y.", Хтось знає чому?
Олександр Міллс

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

Це була моя проблема і з ADDдирективою, дякую.
vmonteco

Я цього не знав. Змінивши його так, щоб файл був включений поряд із файлом docker, мені це насправді вдалося. Коли він був у мене з іншого джерела (як повний шлях, наприклад / dir / dir2 / file), він не працював. Це працює, якщо він знаходиться в якомусь каталозі як файл docker або це діти
Newteq Developer

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 для docker. Docker, версія 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'])

Якщо я змінив порядок роботи, помилок не буде, а файли скопіюються саме туди, куди я їх хочу. Тому я знаю, що мій код працює і робить те, що я хочу. Але важливо скопіювати файли конфігурації в контейнер перед його запуском. Обробка файлів після запуску обумовлює, що контейнер починається із конфігурації за замовчуванням, а не спеціальної конфігурації, яку потрібно скопіювати на місце перед запуском контейнера. Docker стверджує, що ця проблема закрита, але все ще впливає на мою заявку.

Це працює; Один і той же код, інший порядок виконання.

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

1

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


1

Я шукав виправлення цього, і папка, яку я ДОДАВ або КОПІЮВАННЯ, не була в папці збірки, декількох каталогах вище або посиланнях з /

Перенесення папки з-поза папки збірки в папку збірки виправило мою проблему.


1

один із способів не використовувати stdin і зберігати контекст:

1) у своєму Dockerfile, ви повинні додати

ADD /your_dir_to_copy /location_in_container

2) після, слід перейти до батьківського каталогу / your_dir_to_copy

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

У мене була ця проблема, хоча мій вихідний каталог знаходився у правильному контексті побудови. Знайдено, що причиною було те, що моїм вихідним каталогом було символічне посилання на розташування поза контекстом збірки.

Наприклад, мій файл Docker містить наступне:

COPY dir1 /tmp

Якщо dir1це символічне посилання, COPYкоманда не працює в моєму випадку.


0

Тож нещодавно це сталося пару разів. Як розробник .Net, використовуючи VisualStudio, я змінив ім'я збірки SomeThingна Somethingяк ім'я DLL, але це не змінює файл .csproj, який залишаєтьсяSomeThing.csproj

Файл Docker використовує імена файлів, чутливі до регістру Linux, тому нещодавно автоматично сформований файл Docker намагався скопіювати, Something.csprojале не зміг знайти. Тож вручну перейменувавши цей файл (зробивши його малим), все це запрацювало

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

Мені довелося змінити ім'я файлу безпосередньо як коміт на репо .... неприємний маленький обхідний шлях, але змусив мене продовжити

tl; dr Якщо у Windows O / S перевірте чутливість регістру імен файлів та пам’ятайте, що локальні перейменування файлів не збираються під час зміни 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.