การคัดลอกไฟล์ใน Dockerfile ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว?


94

ฉันมี Dockerfile ที่ตั้งค่าไว้ในโฟลเดอร์ root (~) สามบรรทัดแรกของไฟล์ของฉันมีลักษณะดังนี้:

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

แต่จะส่งกลับข้อผิดพลาดต่อไปนี้สำหรับแต่ละบรรทัด:

ไม่พบไฟล์หรือโฟลเดอร์ที่คุณค้นหา

ไฟล์อยู่ในไดเร็กทอรีเดียวกับ Dockerfile ของฉันและฉันกำลังเรียกใช้คำสั่งdocker build - < Dockerfileในไดเร็กทอรีเดียวกันในเทอร์มินัลด้วย

ฉันทำอะไรผิดที่นี่?


ฉันมีปัญหานี้จากนั้นสังเกตว่าไฟล์. dockerignore ไม่สนใจไฟล์ที่ฉันพยายามคัดลอก Solution by 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 ตอนนี้ไม่จำเป็นต้องพูดถึง Dockerfile
askb

3
ฉันพบหลังจากอ่านลิงค์ของคุณอย่างถูกต้องว่า DockerFile ไม่ควรอยู่ในโฟลเดอร์รูทเลย ย้ายทุกอย่างไปยังไดเร็กทอรีย่อยรันคำสั่ง build และรัน คำตอบของคุณมีประโยชน์มากที่สุดดังนั้นฉันจะทำเครื่องหมายว่าถูกต้อง
GreenGodot

47
ตรวจสอบด้วยว่ามี (ไม่มี) ไฟล์ Docker Ignore หรือไม่
Tony

251

ตรวจสอบ.dockerignoreไฟล์ด้วย

ฉันรู้ว่านี่เป็นกรณีที่หายากมาก แต่ฉันมีไฟล์ที่กล่าวถึงที่นั่น


3
โอ้พระเจ้าขอบคุณ ฉันกำลังเปลี่ยนชื่อของโปรเจ็กต์ Java (ซึ่งเป็น artifact และ build dir) และripgrepไม่ได้ค้นหาใน dotfiles ดังนั้นฉันจึงไม่เห็นการอ้างอิงสุดท้ายที่น่ารำคาญไปยังไดเร็กทอรีเก่า
Martin Lehmann

4
ขอบคุณสำหรับ Headsup ในกรณีของฉันฉันใช้วิซาร์ดสตูดิโอวิชวลสำหรับนักเทียบท่าและได้เพิ่ม. dockerignore ด้วย * ในบรรทัดแรก :(
lacripta

ด้วยเหตุผลบางประการ. dockerignore เริ่มต้นของฉันมี ** \ bin อยู่ในนั้น ฉันแน่ใจว่ามันสร้างโดยเดสก์ท็อป Docker
Steve Smith

ดูเหมือนว่าจะไม่ใช่กรณีที่หายากเช่นนี้ !!!. จะไม่คิดออกมาเป็นล้านปี เพิ่มไดเรกทอรีในขณะที่กลับมาและลืมไปโดยสิ้นเชิง เหตุผลในการเพิ่มมันทำให้
บิลด์

1
โอ้นี่มันข้อผิดพลาดจริงๆ ขอบคุณมากที่ชี้ให้เห็น!
taiBsu

36

อาจเกิดจากคุณอ้างถึง file1 / file2 / file3 เป็นพา ธ สัมบูรณ์ซึ่งไม่ได้อยู่ในบริบทของการสร้าง Docker จะค้นหาเส้นทางในบริบทการสร้างเท่านั้น

เช่นถ้าคุณใช้ COPY / home / yourname / file1 Docker build จะแปลเป็น $ {docker build working directory} / home / yourname / file1 หากไม่มีไฟล์ที่มีชื่อเดียวกันที่นี่จะไม่มีข้อผิดพลาดของไฟล์หรือไดเร็กทอรีเกิดขึ้น

อ้างถึงหนึ่งในปัญหานักเทียบท่า


มีปัญหาเส้นทางสัมบูรณ์บางอย่างฉันทำได้แค่ "COPY relative / path / x" ฉันไม่สามารถ "COPY / absolute / path / y." มีใครรู้บ้างว่าทำไม?
Alexander Mills

8
@AlexanderMills Dockerfiles ควรจะรันได้อย่างอิสระบนเครื่องโฮสต์และมาพร้อมกับไฟล์เพิ่มเติมที่มีอยู่ในพา ธ ที่สัมพันธ์กับ Dockerfile การใช้พา ธ สัมบูรณ์จะทำให้รันได้บนเครื่องของคุณเท่านั้น
kliesielski

นั่นเป็นปัญหาของฉันเกี่ยวกับADDคำสั่งเช่นกันขอบคุณ
vmonteco

ฉันไม่ทราบเรื่องนี้ การเปลี่ยนเพื่อให้ไฟล์รวมอยู่ข้าง Dockerfile ทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน เมื่อฉันได้รับจากตำแหน่งต้นทางอื่น (เป็นเส้นทางแบบเต็มเช่น / dir / dir2 / file) มันไม่ทำงาน ใช้งานได้หากอยู่ในไดเร็กทอรีบางส่วนเป็น dockerfile หรือเป็น
ไฟล์ย่อย

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
ขอบคุณมาก - สิ่งนี้ใช้ได้ผลกับฉันด้วย มันทำให้ฉันแทบคลั่ง
x0 น

4

ฉันเพิ่งประสบปัญหานี้และไม่มีคำแนะนำใดที่ช่วยแก้ปัญหาของฉันได้ ปรากฎว่าฉันมีการลงท้ายบรรทัดที่ไม่ถูกต้องในไฟล์และต้องเปลี่ยนเป็นส่วนท้ายบรรทัดที่เหมาะสม (ในกรณีนี้จาก CRLF ถึง LF ดังนั้น Ubuntu 14.04 จะจดจำสคริปต์ซึ่งฉันได้แก้ไขบน windows)

ฉันเปลี่ยนการลงท้ายบรรทัดโดยใช้ VSCode และตัวแก้ไขโค้ดส่วนใหญ่ควรมีตัวเลือกในการเลือกการสิ้นสุดบรรทัด

หวังว่านี่จะช่วยใครบางคนได้


ใช่มันช่วยได้ :)
Robert Smith

3

ฉันรู้สึกโง่เล็กน้อย แต่ปัญหาของฉันคือฉันใช้งานนักเทียบท่าเขียนและ Dockerfile ของฉันอยู่ในไดเรกทอรีย่อย. / ใช้งานได้ การอ้างอิง ADD ของฉันจำเป็นต้องสัมพันธ์กับรูทของโปรเจ็กต์ไม่ใช่ Dockerfile

เปลี่ยนแปลง: ADD ./file.tar.gz / etc / folder / to: 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 เวอร์ชัน 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
ฉันถูกไฟไหม้และดูเหมือนว่าการรีสตาร์ทเครื่องยนต์เทียบท่าservice docker restartจะช่วยแก้ปัญหานี้ได้


1

ฉันกำลังค้นหาวิธีแก้ไขเกี่ยวกับเรื่องนี้และโฟลเดอร์ที่ฉันถูกเพิ่มหรือการคัดลอกไม่ได้อยู่ในโฟลเดอร์บิลด์หลายไดเร็กทอรีด้านบนหรืออ้างอิงจาก /

การย้ายโฟลเดอร์จากภายนอกโฟลเดอร์ build ไปยังโฟลเดอร์ build ช่วยแก้ปัญหาของฉันได้


1

วิธีหนึ่งที่จะไม่ใช้ stdin และรักษาบริบทคือ:

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


การอ้างอิงหลายสิบรายการสำหรับ COPY ที่ไม่สามารถคัดลอก - นี่เป็นหนึ่งในไม่กี่รายการที่อ้างอิง.dockerignoreว่าเป็นผู้ร้าย
Alvin

1

ฉันรู้ว่านี่เป็นเรื่องเก่า แต่มีบางอย่างที่จะชี้ให้เห็น หากคุณคิดว่าทุกอย่างเป็นไปตามที่ควรจะเป็นให้ตรวจสอบไฟล์. gitignore ของคุณ :)

คุณอาจมีโฟลเดอร์ในเครื่อง แต่ถ้าโฟลเดอร์นั้นอยู่ใน git ของคุณละเว้นแสดงว่าโฟลเดอร์นั้นไม่อยู่บนเซิร์ฟเวอร์ซึ่งหมายความว่า Docker ไม่พบโฟลเดอร์นั้นเนื่องจากไม่มีอยู่


1

คล้ายกันและขอบคุณคำตอบของtslegaitisหลังจากนั้น

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

สิ่งนี้เกิดขึ้นสองสามครั้งเมื่อไม่นานมานี้ ในฐานะที่เป็น dev สุทธิใช้ VisualStudio ผมเปลี่ยนชื่อจากการสร้างของฉันSomeThingจะSomethingเป็นชื่อ DLL แต่นี้ไม่ได้เปลี่ยนไฟล์ .csproj ที่เข้าพักSomeThing.csproj

Dockerfile ใช้ชื่อไฟล์ที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ของ linux ดังนั้น Dockerfile ที่สร้างขึ้นใหม่โดยอัตโนมัติจึงพยายามคัดลอกSomething.csprojซึ่งไม่พบ ดังนั้นการเปลี่ยนชื่อไฟล์นั้นด้วยตนเอง (ทำให้เป็นตัวพิมพ์เล็ก) ทำให้มันใช้งานได้ทั้งหมด

แต่ ... นี่คือคำเตือนที่ควรระวัง การเปลี่ยนชื่อไฟล์นี้บนแล็ปท็อป Windows ของฉันไม่ได้รับ Git ดังนั้นแหล่ง repo จึงยังคงSomeThing.csprojอยู่ใน repo และในระหว่างกระบวนการ CI / CD การสร้าง Docker ล้มเหลวด้วยเหตุผลเดียวกัน ...

ฉันต้องเปลี่ยนชื่อไฟล์โดยตรงเป็นการกระทำใน repo .... วิธีแก้ปัญหาเล็กน้อยที่น่ารังเกียจ แต่ทำให้ฉันไป

tl; dr หากใน Windows O / S ตรวจสอบความไวของชื่อไฟล์และโปรดทราบว่าการเปลี่ยนชื่อไฟล์ในเครื่องจะไม่ถูกเลือกขึ้นเนื่องจากการเปลี่ยนแปลง Git ดังนั้นโปรดตรวจสอบให้แน่ใจว่า repo ของคุณได้รับการแก้ไขด้วยเช่นกันหากใช้ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.