KOPIUJESZ plik w Dockerfile, nie ma takiego pliku lub katalogu?

94

Mam plik Dockerfile skonfigurowany w moim folderze głównym (~). Pierwsze trzy wiersze mojego pliku wyglądają następująco:

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

ale zwraca następujący błąd dla każdej linii:

Nie ma takiego pliku lub katalogu

Pliki znajdują się w tym samym katalogu co mój plik Dockerfile i uruchamiam polecenie również docker build - < Dockerfilew tym samym katalogu w terminalu.

Co ja tu robię źle?

GreenGodot
źródło
Miałem ten problem, a potem zauważyłem, że plik .dockerignore ignoruje plik, który próbowałem skopiować. Rozwiązanie autorstwa jinschubert: github.com/docker/for-mac/issues/1922
JStrahl

Odpowiedzi:

35

Instrukcja COPY Dockerfilekopiuje pliki srcdo destfolderu. Wygląda na to, są albo brakuje file1, file2i file3czy staramy się budować Dockerfilez niewłaściwym folderze.

Odnieś się do Dockerfile Doc

Również polecenie budowania Dockerfilepowinno być podobne.

cd into/the/folder/
docker build -t sometagname .
askb
źródło
3
To drugie polecenie zawodzi i mówi, że „budowanie” wymaga jednego argumentu.
GreenGodot
oh - zaktualizuj teraz cmd, nie trzeba wspominać o pliku Dockerfile.
askb
3
Po poprawnym przeczytaniu twojego linku dowiedziałem się, że DockerFile nie powinien w ogóle znajdować się w folderze głównym. Przeniesiono wszystko do podkatalogu, uruchomiono polecenie kompilacji i działa. Twoja odpowiedź była bardzo pomocna, więc zaznaczę ją jako poprawną.
GreenGodot
47
Sprawdź również, czy istnieje (nie) plik ignorowania platformy Docker.
Tony
250

Sprawdź również .dockerignoreplik.

Wiem, że to bardzo rzadki przypadek, ale wspomniałem tam o tym pliku.

swateek
źródło
3
o mój boże, dziękuję. ripgrepZmieniałem nazwę projektu Java (a tym samym katalog artefaktów i kompilacji) i nie przeszukuję plików dotfiles, więc nie widziałem ostatniego nieznośnego odniesienia do starego katalogu.
Martin Lehmann
4
dzięki za headsup, w moim przypadku używałem kreatora Visual Studio dla dockera i dodałem .dockerignore z * w pierwszym wierszu :(
lacripta
Z jakiegoś powodu mój domyślny plik .dockerignore ma w sobie ** \ bin. Jestem pewien, że został wygenerowany przez Docker.
Steve Smith
ahhghgghghg nie wydaje się wcale taki rzadki przypadek !!!. Nie rozgryzłby tego za milion lat. Dodano katalog jakiś czas temu i całkowicie zapomniałem. Powodem dodania tego jest to, że każda kompilacja jest wyjątkowo powolna, myślę, że ma to związek z git ...
tahiche
1
och poważnie, co to za błąd. dziękuję bardzo za zwrócenie na to uwagi!
taiBsu
36

Prawdopodobnie jest to spowodowane tym, że odnosisz plik1 / plik2 / plik3 jako ścieżkę bezwzględną, która nie jest w kontekście kompilacji, Docker przeszukuje ścieżkę tylko w kontekście kompilacji.

Np. Jeśli używasz COPY / home / yourname / file1, Docker build interpretuje to jako $ {docker build work directory} / home / yourname / file1, jeśli nie ma tutaj pliku o tej samej nazwie, nie zostanie zgłoszony żaden błąd pliku lub katalogu.

Zobacz jeden z problemów z dokerem

Popeye
źródło
jest jakiś problem ze ścieżką bezwzględną, mogę tylko „KOPIOWAĆ ścieżkę względną / ścieżkę / x”. Nie mogę „KOPIOWAĆ / bezwzględna / ścieżka / r.”, Nikt nie wie dlaczego?
Alexander Mills,
8
Pliki @AlexanderMills Dockerfile mają być uruchamiane niezależnie na maszynie hosta i dostarczane z dodatkowymi plikami dostępnymi w ścieżkach względem Dockerfile. Używanie ścieżek bezwzględnych sprawiłoby, że działałoby to tylko na twoim komputerze.
kciesielski
To był mój problem z ADDdyrektywą, dziękuję.
vmonteco
Nie wiedziałem tego. Zmiana tak, aby plik był dołączony do pliku dockerfile, działała idealnie dla mnie. Kiedy miałem go z innej lokalizacji źródłowej (jako pełna ścieżka, np. / Dir / dir2 / file), nie działało. Działa, jeśli znajduje się w jakimś katalogu jako plik dockerfile lub jest to
plik podrzędny
22

Wygląda na to, że polecenia:

docker build -t imagename .

i:

docker build -t imagename - < Dockerfile2

nie są wykonywane w ten sam sposób. Jeśli chcesz zbudować 2 obrazy Dockera z jednego folderu z Dockerfile i Dockerfile2, nie można użyć polecenia COPY w drugim przykładzie przy użyciu stdin (<Dockerfile2). Zamiast tego musisz użyć:

docker build -t imagename -f Dockerfile2 .

Wtedy COPY działa zgodnie z oczekiwaniami.

Tallandtree
źródło
16

Uruchomienie docker build . -f docker/development/Dockerfiledziałało, co pozwala na uruchomienie pliku Dockera z określonego katalogu innego niż katalog główny aplikacji.

Użyj -flub, --fileaby określić nazwę i lokalizacjęDockerfile .

Zdarzyło mi się to podczas próby uruchomienia pliku Dockera z innego katalogu.

miałem COPY failed: stat /var/lib/docker/tmp/docker-builder929708051/XXXX: no such file or directory i udało mi się rozwiązać ten problem, określając plik dockera.

To było docker build docker/development/Dockerfile spowodowało ten problem dla mnie.

Na początku wydało mi się to dziwne, ponieważ kiedy miałem Dockerfilew katalogu głównym aplikacji, działało dobrze. Pomoże to, jeśli chcesz trochę lepiej zarządzać plikami dockera środowiska.

Gwiazda
źródło
1
docker build . -f docker/development/Dockerfileto działa
Pradeep Surale
1
Dziękuję bardzo - to też zadziałało. Doprowadzało mnie to do szału.
x0n
4

Właśnie doświadczyłem tego problemu i żadna z poniższych sugestii nie rozwiązała mojego problemu. Okazało się, że w moim pliku były niewłaściwe zakończenia linii i musiałem je zmienić na odpowiednie zakończenia linii. (W tym przypadku z CRLF do LF, więc Ubuntu 14.04 rozpoznałby skrypt, który edytowałem w systemie Windows).

Zmieniłem zakończenia linii za pomocą VSCode, a większość edytorów kodu powinna mieć możliwość wyboru końcówek linii.

Mam nadzieję, że to komuś pomoże.

LiHRaM
źródło
Tak, pomogło :)
Robert Smith
3

Czuję się trochę głupio, ale moim problemem było to, że korzystałem z docker-compose, a mój plik Dockerfile był w podkatalogu ./deploy. Moje odniesienie ADD musiało być względne w stosunku do katalogu głównego projektu, a nie do pliku Dockerfile.

Zmieniono: ADD ./file.tar.gz / etc / folder / na: ADD ./deploy/file.tar.gz / etc / folder /

W każdym razie pomyślałem, że napiszę na wypadek, gdyby ktoś napotkał ten sam problem.

fufonzo
źródło
3

Oto rozwiązanie i najlepsze praktyki:

Musisz utworzyć folder zasobów, w którym możesz przechowywać wszystkie pliki, które chcesz skopiować.

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

Polecenie do kopiowania plików należy podać w ten sposób:

COPY resources /root/folder/

gdzie

* zasoby - folder lokalny, który utworzyłeś w tym samym folderze, w którym znajduje się plik Dockerfile

* / root / folder / - folder w Twoim kontenerze

Anna van den Akker
źródło
1

W przypadku następującego błędu

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

Zrobiłem to, ponownie uruchamiając usługę Dockera.

sudo service docker restart
Vineeth
źródło
1

File not found error with Docker put_archive. Używam interfejsu API Pythona dla platformy Docker. Docker w wersji 1.12.5, kompilacja 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")

Nie mogę skopiować plików do utworzonego kontenera Dockera.

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

Jeśli zmienię kolejność operacji, nie ma błędu, a pliki są kopiowane dokładnie tam, gdzie chcę. Więc wiem, że mój kod działa i robi to, co chcę. Ale ważne jest, aby skopiować pliki konfiguracyjne do kontenera przed jego uruchomieniem. Kopiowanie plików po uruchomieniu powoduje, że kontener zaczyna się od konfiguracji domyślnej, a nie konfiguracji niestandardowej, którą należy skopiować na miejsce przed uruchomieniem kontenera. Docker twierdzi, że ten problem został zamknięty, ale nadal wpływa na moją aplikację.

To działa; Ten sam kod, inna kolejność wykonania.

con = cli.create_container(...)
cli.start(con['Id'])
cli.put_archive(...)
metadane
źródło
1

jeśli jesteś pewien, że postąpiłeś dobrze, ale docker nadal narzeka, spójrz na ten problem: https://github.com/moby/moby/issues/27134 .
Spaliłem się przez to i wygląda na to, że ponowne uruchomienie silnika Dockera service docker restartpo prostu naprawi ten problem.

linehrr
źródło
1

Szukałem rozwiązania tego problemu, a folder, który dodałem lub kopiowałem, nie znajdował się w folderze kompilacji, w wielu katalogach powyżej lub w katalogu /

Przeniesienie folderu spoza folderu kompilacji do folderu kompilacji rozwiązało mój problem.

malina
źródło
1

jednym ze sposobów, aby nie używać stdin i zachować kontekstu, jest:

1) w pliku Dockerfile, należy dodać

ADD /your_dir_to_copy /location_in_container

2) następnie powinieneś przejść do katalogu nadrzędnego / your_dir_to_copy

2), a następnie uruchom to polecenie

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

3) po utworzeniu kontenera

docker run -ti --rm cordova bash

4) Po skopiowaniu katalogu do kontenera

Walterwhites
źródło
1

Poprzednie wywołania COPY mogły powodować zmianę katalogu.

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

Dodaj na końcu ukośnik do pierwszego wywołania

COPY ./server/package.json ./server/
Isaac Pak
źródło
1

Wpadłem na to. Kopiowanie niektórych katalogów nie działało. Kopiowanie plików tak. Okazało się, że dzieje się tak, ponieważ pliki zawarte w .gitignore (nie tylko .dockerignore) są również ignorowane. Zobacz: https://github.com/zeit/now/issues/790

Jose Solorzano
źródło
dziesiątki odniesień do COPY nie można skopiować - jest to jedno z niewielu odniesień .dockerignoredo sprawcy
Alvin
1

Wiem, że to stare, ale coś, na co warto zwrócić uwagę. Jeśli uważasz, że wszystko jest tak, jak powinno, sprawdź swój plik .gitignore :)

Możesz mieć folder lokalnie, ale jeśli folder znajduje się w twoim git zignoruj, nie ma go na serwerze, co oznacza, że ​​Docker nie może znaleźć tego folderu, ponieważ nie istnieje.

TSlegaitis
źródło
1

Podobnie i dzięki odpowiedzi tslegaitisa , po

gcloud builds submit --config cloudbuild.yaml . 

to pokazuje

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

Sprawdzając ten dziennik, mówi, że docker użyje .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

Więc naprawiłem mój .gitignore (zamiast tego używam go jako białej listy) i docker skopiował plik.

[Dodałem odpowiedź, ponieważ nie mam wystarczającej reputacji, aby komentować]

Omr
źródło
1

Miałem ten problem, mimo że mój katalog źródłowy był w odpowiednim kontekście kompilacji. Okazało się, że powodem było to, że mój katalog źródłowy był symbolicznym dowiązaniem do lokalizacji poza kontekstem kompilacji.

Na przykład mój plik Dockerfile zawiera następujące elementy:

COPY dir1 /tmp

Jeśli dir1jest dowiązaniem symbolicznym, COPYpolecenie nie działa w moim przypadku.

algojohn
źródło
0

Tak więc ostatnio zdarzyło się to kilka razy. Jako programista .Net, używając VisualStudio, zmieniłem nazwę kompilacji z SomeThingna Somethingjako nazwę DLL, ale to nie zmienia pliku .csproj, który pozostajeSomeThing.csproj

Plik Dockerfile używa nazw plików w systemie Linux z rozróżnianiem wielkości liter, więc nowo wygenerowany plik Dockerfile próbował skopiować Something.csproj czego nie mógł znaleźć. Więc ręczna zmiana nazwy tego pliku (czyniąc go małymi literami) sprawiła, że ​​wszystko działało

Ale ... oto ostrzeżenie. Ta zmiana nazwy pliku na moim laptopie z systemem Windows nie jest odbierana przez Git, więc źródło repozytorium nadal znajdowało SomeThing.csprojsię w repozytorium, a podczas procesu CI / CD kompilacja Dockera nie powiodła się z tych samych powodów ...

Musiałem zmienić nazwę pliku bezpośrednio jako zatwierdzenie w repozytorium ... paskudne małe obejście, ale sprawiło, że zacząłem

tl; dr Jeśli w systemie Windows O / S sprawdź rozróżnianie wielkości liter w nazwach plików i pamiętaj, że lokalne zmiany nazw plików nie są pobierane przy zmianie Git, więc upewnij się, że repozytorium jest również zmodyfikowane, jeśli używasz CI / CD

Niebo
źródło
0

Kilka świetnych odpowiedzi już tutaj. Pomogło mi przeniesienie komentarzy do następnej linii.

ŹLE :

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

DOBRY :

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
Aleksandras Urbonas
źródło