Problem Docker COPY - „brak takiego pliku lub katalogu”


36

W moim Dockerfile mam następujące oświadczenie „COPY”:

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

Nie trzeba dodawać, że w moim systemie hosta, w katalogu „/ srv / visitor”, rzeczywiście jest mój kod źródłowy:

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

Teraz, gdy próbuję zbudować obraz przy użyciu tego pliku Docker, zawiesza się on na etapie, kiedy ma nastąpić „KOPIUJ”:

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

Mówi, że nie ma takiego katalogu, ale jest wyraźnie.

Jakieś pomysły?

AKTUALIZACJA 1:

Wskazano mi, że się myliłem w sposobie, w jaki rozumiałem kontekst budowania. Sugestia polegała na zmianie wyrażenia „KOPIUJ” na:

COPY . /srv/visitor

Problem polega na tym, że miałem to w ten sposób, a proces kompilacji został zatrzymany na następnym etapie:

RUN npm install

Napisał coś w stylu „nie znaleziono pliku package.json”, kiedy wyraźnie istnieje.

AKTUALIZACJA 2:

Próbowałem uruchomić go z tą zmianą w Dockerfile:

COPY source /srv/visitor/

Zatrzymał się podczas próby uruchomienia 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

Czy kopia została wykonana? Jeśli tak, dlaczego npm nie może znaleźć pliku package.json?


Dla tych, którzy szukają problemu w 2017 r. - może to być twój problem github.com/docker/for-mac/issues/1922 . zaleca usunięcie pliku .dockerignore i ponowne przetestowanie. Jeśli to zadziała, możesz poprawić swoje ustawienia w .dockerignore, aby rozwiązać problem.
— Niezdefiniowany

Odpowiedzi:


35

Z dokumentacji:

<src>Ścieżka musi być wewnątrz kontekście budowy ; nie można KOPIOWAĆ ../something / coś, ponieważ pierwszym krokiem kompilacji dokera jest wysłanie katalogu kontekstowego (i podkatalogów) do demona dokera.

Kiedy używasz /srv/visitor, używasz ścieżki bezwzględnej poza kontekstem kompilacji, nawet jeśli faktycznie jest to bieżący katalog.

Lepiej uporządkuj kontekst kompilacji w następujący sposób:

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

I użyć :

COPY resources /srv/visitor/

Uwaga:

docker build - < Dockerfile nie ma żadnego kontekstu.

Stąd użycie,

docker build .


Jestem już w katalogu „/ srv / visitor” mojego systemu hosta i cały mój kod źródłowy oraz plik Docker znajdują się tutaj. Jak mam napisać moją instrukcję „COPY”, aby całe to źródło zostało skopiowane do katalogu „/ srv / visitor” kontenera?
— dsljanus

1
@dsljanus Katalog lub plik źródłowy musi być względny do kontekstu kompilacji, tj /srv/visitor. katalogu.
— Xavier Lucas

Czy to powinno być „.”? Ponieważ miałem to w ten sposób, a proces kompilacji został zatrzymany w następnym kroku: „Uruchom RUN npm install”. Napisał coś w stylu „nie znaleziono pliku package.json”. Zobacz także moją aktualizację.
— dsljanus

2
@dsljanus A więc skąd uruchamiasz npm? Opublikuj cały plik docker ... Btw nie zmieniaj wielu takich aktualizacji w pytaniach, to naprawdę denerwujące, aby przejść od jednego problemu do zupełnie innego. Celem SF jest wysyłanie jasnych pytań w celu uzyskania jasnych odpowiedzi.
— Xavier Lucas

1
@dsljanus Ok, więc to jest problem, nie używaj, RUN cdale używaj, WORKDIRaby bieżący katalog był zapamiętywany między każdym krokiem. Plik dokera jest niczym więcej niż opakowaniem dla polecenia dokera + zatwierdzenia dokera, więc każdy krok jest uruchamiany niezależnie na poprzedniej warstwie. Oznacza to, że pwd jest równy /na każdym kroku, jeśli nie korzystasz z tej dyrektywy.
— Xavier Lucas

39

Dla mnie katalog był w odpowiednim kontekście, tyle że był zawarty w (ukrytym) .dockerignorepliku w katalogu głównym projektu. Prowadzi to do komunikatu o błędzie:

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

3
miałeś na myśli .dockerignore? to właśnie mi się przydarzyło
— Martín Coll

5
Na zdrowie! Miałem cały katalog, który ignorowałem, o którym zapomniałem i to zepsuło moją kompilację. Krótko mówiąc, możesz zignorować pojedynczy plik w katalogu za pomocą: !path/to/my/filenawet jeśli pathjest w .dockerignore.
— hjc1710

Ten jest dobry.
— Gudlaugur Egilsson

Nie mogę wyrazić, jak jestem ci wdzięczny za to, że torturowałem się przez cały dzień. Nadal nie mogę zrozumieć, dlaczego VS Tools for Docker zawiera .dockerignore z * w nim
— bilal.haider

7

Dla mnie problemem było to, że używałem docker build - < Dockerfile

Z dokumentacji Uwaga: Jeśli budujesz przy użyciu STDIN ( docker build - < somefile), nie ma kontekstu kompilacji, więc nie można użyć COPY.


1

Jak stwierdził Xavier Lucas [niezwykle pomocna] odpowiedź, nie można używać funkcji KOPIUJ ani DODAJ z katalogu poza kontekstem kompilacji (folder, z którego uruchamiasz „kompilację dokera”, powinien być tym samym katalogiem, co plik .Dockerfile). Nawet jeśli spróbujesz użyć dowiązania symbolicznego, to nie zadziała.

Uwaga: Dotyczy to POSIX (Linux, Unix, Mac, prawdopodobnie Linux Subsystem dla Windows). Możesz zrobić podobnie w systemie Windows za pomocą JUNCTION.

cd ~/your_docker_project/
cp -al /subfolder/src_directory ./
echo "COPY src_directory /subfolder/" >> Dockerfile

Niebezpieczeństwo: użycie tego spowoduje, że projekt dokowania będzie specyficzny dla hosta. Prawie nigdy nie chcesz tego robić! Ostrożnie.

Zastosowanie: nauka, eksperymentowanie w środowisku programistycznym

To załatwiło sprawę. cp -al kopiuje strukturę katalogów i tworzy twarde dowiązania dla wszystkich plików. Po zakończeniu uruchom „rm -rf ./src_directory”, aby go usunąć.


Mój cel: skopiuj pakiety z pamięci podręcznej w moim lokalnym systemie plików do obrazu dokera. Zainstaluj potrzebne mi narzędzia (albo użyje pamięci podręcznej, albo pobierze ją jako nową). Następnie usuwam tę pamięć podręczną z obrazu i usuwam twarde łącza na hoście. Jeśli host nie ma tych plików, nie martw się. Ale mam ograniczoną przepustowość i ograniczone miejsce na dysku. Czy jest to dopuszczalne użycie?
— TamusJRoyce

1

Natrafiłem na ten problem i odkryłem, że byłem w stanie dodać kontekst do zmiennej kompilacji, aby załadować moje pliki Docker z innych katalogów. To pozwoliło mi nieco zmienić moją domyślną strukturę plików Dockera. Oto fragment mojego dokera-compose.yml:

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

Dodając kontekst, byłem w stanie zdefiniować, gdzie pliki powinny się odnosić. Dokumenty Dockera można znaleźć tutaj: https://docs.docker.com/compose/compose-file/#context

Mam nadzieję że to pomoże!


0

Dla mnie problem polegał na tym, że dodawana nazwa pliku miała spację końcową. Zmiana nazwy to naprawiła.


0

W przypadku następującego błędu

COPY failed: stat

Rozwiązałem problem, uruchamiając ponownie usługę dokowania.


0

W końcu rozwiązałem ten problem w moim przypadku, że plik Dockerfile, który wykonuje kopiowanie, znajdował się na głębszym poziomie projektu. Uświadomiłem sobie, że ścieżka kompilacji hosta jest wyrażona w stosunku do lokalizacji pliku Dockerfile.


0

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

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

Bieganie docker build . -f docker/development/Dockerfiledziałało.

Ale uruchomienie Runningdokera kompilacji / rozwoju / Dockerfile` spowodowało ten problem.

-flub w --filecelu określenia nazwy i lokalizacji Dockerfile.

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


0

Plik musi nie tylko znajdować się w katalogu w bieżącym kontekście kompilacji, ale również nie może być miękkim łączem do pliku poza kontekstem kompilacji.

Miałem link do pliku w moim katalogu domowym, a link znajdował się w katalogu projektu. Po usunięciu łącza i przeniesieniu połączonego pliku do projektu ( rm mylink ; mv ~/myrealfile ./), to zadziałało.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.