Проблема Docker COPY - "немає такого файлу чи каталогу"


38

У своєму Dockerfile у мене є такий вислів "КОПІР":

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

Само собою зрозуміло, що в моїй хост-системі в каталозі "/ srv / visitor" дійсно є мій вихідний код:

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

Тепер, коли я намагаюся створити зображення за допомогою цього Dockerfile, воно зависає на кроці, коли має бути "КОПІЯ":

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

Це говорить про те, що такого каталогу немає, але явно є.

Якісь ідеї?

ОНОВЛЕННЯ 1:

Мені вказувалося, що я помилявся в тому, як я розумів побудову контексту. Пропозиція була зміною заяви "COPY" на це:

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/isissue/1922 . він рекомендує видалити файл .dockerignore та повторно протестувати. Якщо це працює, ви можете вирішити проблему зі своїми налаштуваннями у .dockerignore, щоб вирішити проблему.
Не визначено

Відповіді:


36

З документації:

<src>Шлях повинен бути в контексті збірки ; Ви не можете скопіювати ../something / something, тому що перший крок побудови докера - це надіслати контекстну каталог (і підкаталоги) до демона docker.

Під час використання /srv/visitorви використовуєте абсолютний шлях поза контекстом збірки, навіть якщо це фактично поточний каталог.

Ви краще організуйте такий контекст побудови таким чином:

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

І використовуйте:

COPY resources /srv/visitor/

Примітка:

docker build - < Dockerfile не має жодного контексту.

Отже, використання,

docker build .


Я вже всередині каталогу "/ srv / visitor" моєї хост-системи, і весь мій вихідний код, а також Dockerfile тут. Як мені написати заяву "COPY", щоб все це джерело було скопійовано у каталог "/ srv / visitor" контейнера?
dsljanus

1
@dsljanus Вихідний каталог або файл повинен бути по відношенню до контекстного збірки тобто /srv/visitorдиректорії.
Ксав'є Лукас

Отже, чи повинно бути "."? Тому що я мав це саме так, і процес збирання зупинився на наступному кроці "RUN npm install". Він щось говорив у рядку "файлу package.json не знайдено". Будь ласка, дивіться також моє оновлення.
dsljanus

2
@dsljanus І так звідки ти працюєш npm? Опублікуйте весь докерфайл ... Btw не змінюйте декілька подібних оновлень у питаннях, це насправді прикро переходити з однієї проблеми до зовсім іншої. Мета SF - розміщення чітких питань, щоб отримати чіткі відповіді.
Ксав'є Лукас

1
@dsljanus Гаразд, це проблема, не використовуйте, RUN cdа використовуйте, WORKDIRщоб поточний каталог запам'ятовувався між кожним кроком. Докер-файл - це не більше ніж обгортка для запуску докер + докер-фіксація, тому кожен крок виконується незалежно над попереднім шаром. Це означає, що pwd дорівнює /на кожному кроці, якщо ви не використовуєте цю директиву.
Ксав'є Лукас

41

Для мене каталог був у правильному контексті, лише він був включений у (прихований) .dockerignoreфайл у корені проекту. Це призводить до повідомлення про помилку:

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

3
ти мав на увазі .dockerignore? що щойно сталося зі мною
Мартін Колл

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

Це добре.
Gudlaugur Egilsson

Не можу висловити, наскільки я вдячний тобі за це, що мучив себе за останній цілий день. Ще не можу зрозуміти, чому інструменти VS для докера включають .dockerignore з * у ньому
bilal.haider

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

7

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

З документації Примітка. Якщо ви docker build - < somefileстворюєте за допомогою STDIN ( ), немає контексту збірки, тому COPY не можна використовувати.


1

Як заявив відповідь Ксав'є Лукаса [надзвичайно корисна], ви не можете використовувати COPY або ADD з каталогу за межами контексту збирання (папка, з якої ви запускаєте "docker build", повинна бути тим самим каталогом, що і ваш .Dockerfile). Навіть якщо ви спробуєте скористатися символьним посиланням, це не вийде.

Примітка. Це специфічно для POSIX (Linux, Unix, Mac, можливо, підсистема Linux для 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 (s) з інших каталогів. Це дозволило мені трохи змінити структуру файлів Docker за замовчуванням на свій смак. Ось фрагмент з мого docker-compose.yml:

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

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

Сподіваюся, це допомагає!


0

Для мене проблема полягала в тому, що ім'я файлу, яке я додавав, містило пробіли. Перейменування виправлено.



0

Нарешті я вирішив це питання, в моєму випадку Dockerfile, який виконує копію, знаходився на більш глибокому рівні проекту. Тому я зрозумів, що шлях збирання хоста виражається відносно розташування файлів Dockerfile.


0

Це сталося зі мною при спробі запуску файлу docker з іншого каталогу.

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

Біг docker build . -f docker/development/Dockerfileпрацював.

Але запущена Runningdocker build docker / development / Dockerfile` викликала цю проблему.

-fабо --fileвказати ім'я та місцезнаходження Dockerfile.

Спочатку це здалося дивним, оскільки коли у мене був Dockerfileкорінний каталог додатків, він працював чудово. Це допоможе, якщо ви хочете трохи краще керувати файлами докерних середовищ.


0

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

Я мав посилання на файл у своєму домашньому каталозі, а посилання - у каталозі проектів. Після того як я видалив посилання та перемістив зв'язаний файл у проект ( rm mylink ; mv ~/myrealfile ./), він працював.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.