SAO CHÉP một tệp trong Dockerfile, không có tệp hoặc thư mục đó?


94

Tôi có một Dockerfile được thiết lập trong thư mục gốc (~) của mình. Ba dòng đầu tiên của tệp của tôi trông như thế này:

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

nhưng nó trả về lỗi sau cho mỗi dòng:

Không có tập tin hoặc thư mục

Các tệp nằm trong cùng thư mục với Dockerfile của tôi và tôi cũng đang chạy lệnh docker build - < Dockerfiletrong cùng một thư mục trong terminal.

Chính xác thì tôi đang làm gì sai ở đây?


Tôi gặp sự cố này, sau đó nhận thấy tệp .dockerignore đang bỏ qua tệp tôi đang cố sao chép. Giải pháp của jinschubert: github.com/docker/for-mac/issues/1922
JStrahl

Câu trả lời:


35

Các hướng dẫn COPY trong Dockerfilebản sao các tập tin trong srcvào destthư mục. Trông giống như bạn đang hoặc thiếu file1, file2file3hoặc cố gắng để xây dựng Dockerfiletừ thư mục sai.

Tham khảo Dockerfile Doc

Ngoài ra, lệnh để xây dựng Dockerfilenên là một cái gì đó giống như.

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

3
Lệnh thứ hai không thành công đối với tôi, nói rằng "xây dựng" yêu cầu một đối số.
GreenGodot

oh - cập nhật cmd ngay bây giờ, nó không bắt buộc phải đề cập đến Dockerfile.
askb

3
Tôi phát hiện ra sau khi đọc đúng liên kết của bạn rằng DockerFile hoàn toàn không nên nằm trong thư mục gốc. Đã chuyển mọi thứ vào thư mục con, chạy lệnh xây dựng và nó chạy. Câu trả lời của bạn là hữu ích nhất vì vậy tôi sẽ đánh dấu nó là đúng.
GreenGodot

48
Đồng thời kiểm tra xem có (không) tệp Docker Bỏ qua hay không.
Tony

252

Kiểm tra .dockerignoretệp quá.

Tôi biết đây là một trường hợp rất hiếm, nhưng tôi đã có hồ sơ được đề cập ở đó.


3
trời ơi cảm ơn. Tôi đã thay đổi tên của một dự án Java (và do đó tạo tác và xây dựng dir), và ripgrepkhông tìm kiếm trong dotfiles nên tôi không thấy tham chiếu pesky cuối cùng đến thư mục cũ.
Martin Lehmann

4
cảm ơn cho headsup, trong trường hợp của tôi, tôi đã sử dụng thuật sĩ visual studio cho Docker và nó thêm một .dockerignore với * trong dòng đầu tiên :(
lacripta

Vì một số lý do, .dockerignore mặc định của tôi có ** \ bin trong đó. Tôi chắc chắn rằng nó được tạo bởi Docker desktop.
Steve Smith

ahhghgghghg rốt cuộc có vẻ không phải là trường hợp hiếm như vậy !!!. Sẽ không thể tìm ra nó trong một triệu năm. Đã thêm thư mục một thời gian trở lại và hoàn toàn quên. Lý do cho việc thêm nó là nó làm cho bất kỳ xây dựng rất chậm, suy nghĩ nó đã làm với git ...
tahiche

1
Ồ, thật là lỗi. cảm ơn rất nhiều vì đã chỉ ra điều đó!
taiBsu

36

Có thể do bạn đang tham chiếu đến file1 / file2 / file3 như một đường dẫn tuyệt đối không có trong ngữ cảnh xây dựng, Docker chỉ tìm kiếm đường dẫn trong ngữ cảnh xây dựng.

Ví dụ: nếu bạn sử dụng COPY / home / yourname / file1, Docker build sẽ hiểu nó là $ {docker build working directory} / home / yourname / file1, nếu không có tệp nào có cùng tên ở đây, thì không có tệp hoặc thư mục nào bị lỗi.

Tham khảo Một trong những vấn đề về docker


có một số loại vấn đề về đường dẫn tuyệt đối, tôi chỉ có thể "SAO CHÉP tương đối / đường dẫn / x." Tôi không thể "SAO CHÉP / tuyệt đối / đường dẫn / y.", Có ai biết tại sao không?
Alexander Mills

8
@AlexanderMills Dockerfiles được cho là có thể chạy độc lập trên máy chủ và được vận chuyển với các tệp bổ sung có sẵn trong các đường dẫn liên quan đến Dockerfile. Sử dụng đường dẫn tuyệt đối sẽ chỉ chạy được trên máy của bạn.
kciesielski

Đó cũng là vấn đề của tôi với ADDchỉ thị, cảm ơn bạn.
vmonteco

Tôi không biết điều này. Thay đổi nó để tệp được bao gồm cùng với tệp dockerfile thực sự hoạt động hoàn hảo đối với tôi. Khi tôi lấy nó từ một số vị trí nguồn khác (dưới dạng đường dẫn đầy đủ, ví dụ / dir / dir2 / file), nó không hoạt động. Nó hoạt động nếu nó trong một số thư mục như dockerfile hoặc đó là trẻ em
Newteq Developer

22

Có vẻ như các lệnh:

docker build -t imagename .

và:

docker build -t imagename - < Dockerfile2

không được thực hiện theo cùng một cách. Nếu bạn muốn xây dựng 2 hình ảnh docker từ bên trong một thư mục với Dockerfile và Dockerfile2, lệnh COPY không thể được sử dụng trong ví dụ thứ hai bằng cách sử dụng stdin (<Dockerfile2). Thay vào đó bạn phải sử dụng:

docker build -t imagename -f Dockerfile2 .

Sau đó, COPY hoạt động như mong đợi.


16

Đang chạy docker build . -f docker/development/Dockerfilehoạt động, cho phép bạn chạy tệp docker của mình từ một thư mục được chỉ định khác với thư mục gốc của ứng dụng của bạn.

Sử dụng -fhoặc --fileđể chỉ định tên và vị trí của Dockerfile.

Điều này đã xảy ra với tôi khi cố gắng chạy tệp docker từ một thư mục khác.

Tôi đã có COPY failed: stat /var/lib/docker/tmp/docker-builder929708051/XXXX: no such file or directoryvà quản lý để giải quyết điều này bằng cách chỉ định tệp docker.

Đó là docker build docker/development/Dockerfilenguyên nhân gây ra vấn đề này cho tôi.

Lúc đầu tôi thấy lạ vì khi tôi có Dockerfiletrong thư mục gốc của ứng dụng, nó hoạt động tốt. Điều này sẽ hữu ích nếu bạn muốn quản lý các tệp docker môi trường của mình tốt hơn một chút.


1
docker build . -f docker/development/Dockerfileđiều này hoạt động
Pradeep Surale

1
Cảm ơn bạn rất nhiều - điều này cũng làm việc cho tôi. Nó làm tôi phát điên.
x0n

4

Tôi vừa gặp sự cố này và không có đề xuất nào ở đây giải quyết được vấn đề của tôi. Hóa ra tôi có phần cuối dòng sai trong tệp của mình và phải thay đổi chúng thành phần cuối dòng thích hợp. (Trong trường hợp này từ CRLF sang LF, vì vậy Ubuntu 14.04 sẽ nhận ra tập lệnh mà tôi đã chỉnh sửa trên windows.)

Tôi đã thay đổi phần cuối dòng bằng VSCode và hầu hết các trình chỉnh sửa mã sẽ có tùy chọn chọn phần cuối dòng.

Hy vọng điều này sẽ giúp ai đó.


Có, nó đã giúp :)
Robert Smith

3

Tôi cảm thấy hơi ngu ngốc, nhưng vấn đề của tôi là tôi đang chạy docker -omp và Dockerfile của tôi nằm trong thư mục con ./deploy. Tham chiếu ADD của tôi cần phải liên quan đến gốc của dự án, không phải Dockerfile.

Đã thay đổi: ADD ./file.tar.gz / etc / folder / thành: ADD ./deploy/file.tar.gz / etc / folder /

Nhưng dù sao, tôi nghĩ tôi sẽ đăng trong trường hợp ai đó gặp phải vấn đề tương tự.


3

Đây là giải pháp và cách thực hành tốt nhất:

Bạn cần tạo một thư mục tài nguyên, nơi bạn có thể giữ tất cả các tệp mà bạn muốn sao chép.

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

Lệnh sao chép tệp phải được chỉ định theo cách này:

COPY resources /root/folder/

Ở đâu

* resources - thư mục cục bộ mà bạn đã tạo trong cùng một thư mục chứa Dockerfile

* / root / folder / - thư mục trong vùng chứa của bạn


1

Đối với lỗi sau,

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

Tôi đã giải quyết nó bằng cách khởi động lại dịch vụ docker.

sudo service docker restart

1

Lỗi không tìm thấy tệp với Docker put_archive. Tôi đang sử dụng API Python cho docker. Docker phiên bản 1.12.5, bản dựng 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")

Tôi không thể sao chép tệp vào vùng chứa docker đã tạo.

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

Nếu tôi thay đổi thứ tự hoạt động thì không có lỗi và các tệp được sao chép chính xác như tôi muốn. Vì vậy, tôi biết mã của tôi đang hoạt động và làm những gì tôi muốn nó làm. Nhưng điều quan trọng là phải sao chép các tệp cấu hình vào một vùng chứa trước khi nó được khởi động. Việc sao chép các tệp sau khi bắt đầu sắp xếp vùng chứa để bắt đầu với cấu hình mặc định chứ không phải cấu hình tùy chỉnh cần được sao chép vào vị trí trước khi bắt đầu vùng chứa. Docker tuyên bố rằng vấn đề này đã được đóng lại nhưng nó vẫn đang ảnh hưởng đến ứng dụng của tôi.

Những công việc này; Cùng một mã lệnh thực hiện khác nhau.

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

1

nếu bạn chắc chắn rằng bạn đã làm đúng nhưng docker vẫn phàn nàn, hãy xem vấn đề này: https://github.com/moby/moby/issues/27134 .
Tôi đã bị cháy bởi điều này và có vẻ như việc khởi động lại công cụ docker service docker restartsẽ chỉ khắc phục được sự cố này.


1

Tôi đang tìm cách sửa lỗi này và thư mục tôi đã THÊM hoặc SAO CHÉP không nằm trong thư mục xây dựng, nhiều thư mục ở trên hoặc được tham chiếu từ /

Di chuyển thư mục từ bên ngoài thư mục xây dựng vào thư mục xây dựng đã khắc phục sự cố của tôi.


1

một trong những cách để không sử dụng stdin và giữ đúng ngữ cảnh là:

1) trong Dockerfile của bạn, bạn nên thêm

ADD /your_dir_to_copy /location_in_container

2) sau đó, bạn nên chuyển sang trang gốc của / your_dir_to_copy dir

2) sau đó chạy lệnh này

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

3) sau khi bạn tạo vùng chứa của mình

docker run -ti --rm cordova bash

4) Sau khi bạn sẽ nhận được thư mục được sao chép vào vùng chứa của bạn


1

Các cuộc gọi trước đây trên COPY có thể đang thay đổi danh bạ.

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

Thêm dấu gạch chéo vào cuối cuộc gọi đầu tiên

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

1

Tôi đã chạy vào điều này. Sao chép một số thư mục không hoạt động. Đã sao chép tệp. Hóa ra là do các tệp chứa trong .gitignore (không chỉ .dockerignore) cũng bị bỏ qua. Xem: https://github.com/zeit/now/issues/790


hàng chục tham chiếu cho COPY không sao chép được - đây là một trong số ít tham chiếu được .dockerignorecoi là thủ phạm
Alvin

1

Tôi biết điều này là cũ, nhưng có điều gì đó cần chỉ ra. Nếu bạn nghĩ rằng mọi thứ đúng như ý muốn, hãy kiểm tra tệp .gitignore của bạn :)

Bạn có thể có thư mục cục bộ, nhưng nếu thư mục trong git của bạn bỏ qua thì nó không có trên máy chủ, có nghĩa là Docker không thể tìm thấy thư mục đó vì nó không tồn tại.


1

Tương tự và cảm ơn câu trả lời của tslegaitis , sau

gcloud builds submit --config cloudbuild.yaml . 

nó cho thấy

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).

Kiểm tra nhật ký đó, nó nói rằng docker sẽ sử dụng .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

Vì vậy, tôi đã sửa lỗi của mình .gitignore(tôi sử dụng nó làm danh sách trắng thay thế) và docker đã sao chép tệp.

[Tôi đã thêm câu trả lời vì tôi không đủ uy tín để bình luận]


1

Tôi đã gặp sự cố này mặc dù thư mục nguồn của tôi nằm trong ngữ cảnh xây dựng chính xác. Tìm thấy lý do là thư mục nguồn của tôi là một liên kết tượng trưng đến một vị trí bên ngoài ngữ cảnh xây dựng.

Ví dụ: Dockerfile của tôi chứa những thứ sau:

COPY dir1 /tmp

Nếu dir1là một liên kết tượng trưng, COPYlệnh không hoạt động trong trường hợp của tôi.


0

Vì vậy, điều này đã xảy ra một vài lần chỉ gần đây. Là một nhà phát triển .Net, sử dụng VisualStudio, tôi đã thay đổi tên bản dựng của mình từ SomeThingthành Somethingtên DLL nhưng điều này không thay đổi tệp .csproj vẫnSomeThing.csproj

Dockerfile sử dụng tên tệp phân biệt chữ hoa chữ thường của linux, vì vậy Dockerfile mới được tạo tự động đang cố gắng sao chép Something.csprojmà nó không thể tìm thấy. Vì vậy, việc đổi tên tệp đó theo cách thủ công (đặt nó thành chữ thường) khiến nó hoạt động

Nhưng ... đây là một cảnh báo thận trọng. Thay đổi tên tệp này trên máy tính xách tay Windows của tôi không được Git tiếp nhận vì vậy nguồn repo vẫn còn SomeThing.csprojtrên repo và trong quá trình CI / CD, bản dựng Docker không thành công vì những lý do tương tự ...

Tôi đã phải thay đổi tên tệp trực tiếp dưới dạng cam kết trên repo .... giải pháp nhỏ khó chịu nhưng đã giúp tôi tiếp tục

tl; dr Nếu trên Windows O / S, hãy kiểm tra độ phân biệt chữ hoa chữ thường của tên tệp và lưu ý rằng tên tệp cục bộ không được chọn khi Git thay đổi, vì vậy hãy đảm bảo repo của bạn cũng được sửa đổi nếu sử dụng CI / CD


0

Một số câu trả lời tuyệt vời ở đây đã có. Điều có hiệu quả với tôi là chuyển các nhận xét sang dòng tiếp theo.

XẤU :

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

TỐT :

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.