Copiando um arquivo em um Dockerfile, nenhum arquivo ou diretório?


99

Eu tenho um Dockerfile configurado na minha pasta raiz (~). As três primeiras linhas do meu arquivo são assim:

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

mas retorna o seguinte erro para cada linha:

Não existe tal arquivo ou diretório

Os arquivos estão no mesmo diretório que meu Dockerfile e estou executando o comando docker build - < Dockerfileno mesmo diretório no terminal também.

O que estou fazendo de errado aqui exatamente?


Eu tive esse problema, então notei que o arquivo .dockerignore estava ignorando o arquivo que eu estava tentando copiar. Solução de jinschubert: github.com/docker/for-mac/issues/1922
— JStrahl

Respostas:


36

A instrução COPY em Dockerfilecopia os arquivos srcpara a destpasta. Parece que estão ausentes a file1, file2e file3ou tentando construir a Dockerfilepartir da pasta errada.

Consulte Documento Dockerfile

Além disso, o comando para construir o Dockerfiledeve ser algo como.

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

3
Esse segundo comando falha para mim, diz que "construir" requer um argumento.
— GreenGodot

oh - atualize o cmd agora, não é necessário mencionar o Dockerfile.
— askb

3
Descobri depois de ler seu link corretamente que o DockerFile não deveria estar na pasta raiz. Mova tudo para o subdiretório, execute o comando build e ele é executado. Sua resposta foi muito útil, então vou marcá-la como correta.
— GreenGodot

49
Verifique também se há (não) um arquivo Docker Ignore.
— Tony

259

Verifique o .dockerignorearquivo também.

Eu sei que este é um caso muito raro, mas eu tinha aquele arquivo mencionado lá.


3
oh meu deus obrigada. Eu estava mudando o nome de um projeto Java (e, portanto, artefato e diretório de compilação), e ripgrepnão procuro em dotfiles, então não vi a última referência incômoda ao diretório antigo.
— Martin Lehmann

4
obrigado pelo headsup, no meu caso eu estava usando o assistente do visual studio para docker e ele adicionou um .dockerignore com * na primeira linha :(
— lacripta

Por alguma razão, meu .dockerignore padrão tem ** \ bin nele. Tenho certeza que foi gerado pelo desktop Docker.
— Steve Smith

ahhghgghghg parece não ser um caso tão raro afinal !!!. Não teria descoberto isso em um milhão de anos. Adicionado o diretório um tempo atrás e esqueci totalmente. A razão para adicioná-lo é que torna qualquer compilação extremamente lenta, acho que tem a ver com git ...
— tahiche

1
oh sério, que erro é esse. muito obrigado por apontar isso!
— taiBsu

37

É possível que seja causado por você estar se referindo a file1 / file2 / file3 como um caminho absoluto que não está no contexto de construção, o Docker apenas pesquisa o caminho no contexto de construção.

Por exemplo, se você usar COPY / home / seunome / arquivo1, o Docker build o interpretará como $ {docker build working directory} / home / yourname / file1, se nenhum arquivo com o mesmo nome aqui, nenhum arquivo ou erro de diretório será gerado.

Consulte Um dos problemas do docker


há algum tipo de problema de caminho absoluto, só posso "COPIAR relativo / caminho / x." Não consigo "COPIAR / absoluto / caminho / y.", Alguém sabe por quê?
— Alexander Mills

8
@AlexanderMills Dockerfiles devem ser executados independentemente na máquina host e enviados com arquivos adicionais disponíveis em caminhos relativos ao Dockerfile. O uso de caminhos absolutos o tornaria executável apenas em sua máquina.
— kciesielski

Esse era o meu problema com a ADDdiretiva também, obrigado.
— vmonteco

Eu não sabia disso. Alterá-lo para que o arquivo fosse incluído junto com o dockerfile funcionou perfeitamente para mim. Quando o obtive de algum outro local de origem (como um caminho completo, por exemplo, / dir / dir2 / arquivo), ele não estava funcionando. Funciona se estiver em algum diretório como o dockerfile ou se for filho
— Newteq Developer

22

Parece que os comandos:

docker build -t imagename .

e:

docker build -t imagename - < Dockerfile2

não são executados da mesma maneira. Se você deseja construir 2 imagens do docker de dentro de uma pasta com Dockerfile e Dockerfile2, o comando COPY não pode ser usado no segundo exemplo usando stdin (<Dockerfile2). Em vez disso, você deve usar:

docker build -t imagename -f Dockerfile2 .

Então o COPY funciona conforme o esperado.


18

Executando docker build . -f docker/development/Dockerfilefuncionou, o que permite que você execute o arquivo docker a partir de um diretório especificado diferente da raiz do seu aplicativo.

Use -fou --filepara especificar o nome e a localização do Dockerfile.

Isso aconteceu comigo ao tentar executar o arquivo docker de um diretório diferente.

Eu tinha o COPY failed: stat /var/lib/docker/tmp/docker-builder929708051/XXXX: no such file or directorye consegui resolver isso especificando o arquivo docker.

Foi docker build docker/development/Dockerfileisso que causou esse problema para mim.

Achei estranho no começo porque quando eu tinha o Dockerfileno diretório raiz do apps funcionava bem. Isso ajudará se você quiser gerenciar um pouco melhor os arquivos do docker do ambiente.


1
docker build . -f docker/development/Dockerfileisso funciona
— Pradeep Surale

1
Muito obrigado - isso também funcionou para mim. Isso estava me deixando louco.
— x0 em

4

Acabei de ter esse problema e nenhuma das sugestões aqui resolveu meu problema. Acontece que eu tinha as terminações de linha erradas em meu arquivo e tive que alterá-las para as terminações de linha apropriadas. (Neste caso, de CRLF para LF, para que o Ubuntu 14.04 reconheça o script, que eu estava editando no Windows.)

Eu mudei as terminações de linha usando VSCode, e a maioria dos editores de código deve ter a opção de escolher terminações de linha.

Espero que isso ajude alguém.


Sim, ajudou :)
— Robert Smith

3

Eu me sinto um pouco estúpido, mas meu problema era que eu estava executando docker-compose e meu Dockerfile estava em um subdiretório ./deploy. Minha referência ADD precisava ser relativa à raiz do projeto, não ao Dockerfile.

Alterado: ADD ./file.tar.gz / etc / folder / para: ADD ./deploy/file.tar.gz / etc / folder /

De qualquer forma, pensei em postar no caso de alguém ter o mesmo problema.


3

Aqui está a solução e a prática recomendada:

Você precisa criar uma pasta de recursos onde possa manter todos os arquivos que deseja copiar.

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

O comando para copiar arquivos deve ser especificado desta forma:

COPY resources /root/folder/

Onde

* resources - sua pasta local que você criou na mesma pasta onde o Dockerfile está

* / root / folder / - pasta em seu contêiner


2

Eu sei que isso é antigo, mas algo a destacar. Se você acha que tudo está como deveria, verifique seu arquivo .gitignore :)

Você pode ter a pasta localmente, mas se a pasta estiver em seu git ignore, ela não está no servidor, o que significa que o Docker não pode encontrar essa pasta porque ela não existe.


1

Para o seguinte erro,

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

Eu resolvi reiniciando o serviço docker.

sudo service docker restart

1

Erro de arquivo não encontrado com Docker put_archive. Estou usando a API Python para docker. Docker versão 1.12.5, compilação 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")

Não consigo copiar arquivos para um contêiner docker criado.

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

Se eu alterar a ordem de operação, não há erro e os arquivos são copiados exatamente para onde eu os desejo. Portanto, sei que meu código está funcionando e fazendo o que eu quero fazer. Mas é importante copiar os arquivos de configuração para um contêiner antes de ser iniciado. Copiar os arquivos após o início faz com que o contêiner comece com uma configuração padrão e não com a configuração personalizada que precisa ser copiada para o local antes de o contêiner ser iniciado. Docker afirma que esse problema foi encerrado, mas ainda está afetando meu aplicativo.

Isso funciona; Ordem de execução diferente do mesmo código.

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

1

se você tiver certeza de que fez a coisa certa, mas o docker ainda reclama, dê uma olhada neste problema: https://github.com/moby/moby/issues/27134 .
Fiquei queimado com isso, e parece que reiniciar o motor do docker service docker restartsó vai resolver o problema.


1

Eu estava procurando uma solução para isso e a pasta que estava ADICIONANDO ou COPIANDO não estava na pasta de compilação, vários diretórios acima ou referenciados em /

Mover a pasta de fora da pasta de compilação para a pasta de compilação corrigiu meu problema.


1

uma das maneiras de não usar stdin e manter o contexto é:

1) em seu Dockerfile, você deve adicionar

ADD /your_dir_to_copy /location_in_container

2) depois, você deve ir no diretório pai / your_dir_to_copy

2) em seguida, execute este comando

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

3) depois de criar seu contêiner

docker run -ti --rm cordova bash

4) Depois, você terá seu diretório copiado em seu contêiner


1

As chamadas anteriores no COPY podem estar alterando o diretório.

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

Adicione uma barra final à primeira chamada

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

1

Eu corri para isso. Copiar alguns diretórios não funcionou. Copiar arquivos sim. Acontece que os arquivos contidos em .gitignore (não apenas .dockerignore) também são ignorados. Veja: https://github.com/zeit/now/issues/790


dezenas de referências para COPY não foram copiadas - esta é uma das poucas referências .dockerignorecomo culpada
— Alvin,

1

Semelhante e graças à resposta de tslegaitis , após

gcloud builds submit --config cloudbuild.yaml . 

isto mostra

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

Verificando esse log, ele diz que o docker usará .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

Então, eu consertei meu .gitignore(uso-o como lista de permissões) e o docker copiei o arquivo.

[Eu adicionei a resposta porque não tenho reputação suficiente para comentar]


1

Tive esse problema, embora meu diretório de origem estivesse no contexto de compilação correto. O motivo foi que meu diretório de origem era um link simbólico para um local fora do contexto de construção.

Por exemplo, meu Dockerfile contém o seguinte:

COPY dir1 /tmp

Se dir1for um link simbólico o COPYcomando não está funcionando no meu caso.


0

Então, isso aconteceu algumas vezes recentemente. Como um .Net dev, usando VisualStudio mudei meu nome de compilação de SomeThingpara Somethingcomo o nome de DLL, mas isso não altera o arquivo .csproj que permaneceSomeThing.csproj

O Dockerfile usa nomes de arquivo que diferenciam maiúsculas de minúsculas do Linux, de modo que o Dockerfile recém-gerado automaticamente estava tentando copiar Something.csproje não conseguiu encontrar. Portanto, renomear manualmente esse arquivo (tornando-o minúsculo) fez com que tudo funcionasse

Mas ... aqui está um aviso preventivo. Esta mudança de nome de arquivo no meu laptop Windows não é detectada pelo Git, então a fonte do repo ainda estava SomeThing.csprojno repo e durante o processo de CI / CD, a compilação do Docker falhou pelos mesmos motivos ...

Tive que alterar o nome do arquivo diretamente como um commit no repo ... uma pequena solução desagradável, mas me ajudou a continuar

tl; dr Se no Windows O / S, verifique a distinção entre maiúsculas e minúsculas no nome do arquivo e esteja ciente de que renomeações de arquivos locais não são selecionadas conforme o Git muda, então certifique-se de que seu repo também seja modificado se usar CI / CD


0

Algumas ótimas respostas já estão aqui. O que funcionou para mim foi mover os comentários para a próxima linha.

RUIM :

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

BOM :

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.