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?

dsljanus
źródło
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 .

Xavier Lucas
źródło
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
AlcaDotS
źródło
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.

Adam
źródło
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ąć.

TamusJRoyce
źródło
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!

Ron
źródło
0

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

Sokole Oko
źródło
0

W przypadku następującego błędu

COPY failed: stat

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

Vineeth
źródło
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.

EmilianoPe
źródło
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.

Gwiazda
źródło
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.

Loduwijk
źródło