Docker: adicionando um arquivo de um diretório pai

186

No meu Dockerfileeu tenho:

ADD ../../myapp.war /opt/tomcat7/webapps/

Esse arquivo existe como ls ../../myapp.warretorna o arquivo correto, mas quando executo sudo docker build -t myapp ., tenho:

Step 1 : ADD ../../myapp.war /opt/tomcat7/webapps/
2014/07/02 19:18:09 ../../myapp.war: no such file or directory

Alguém sabe por que e como fazê-lo corretamente?

Anthony O.
fonte
2
Algumas soluções alternativas superuser.com/questions/842642
Günter Zöchbauer

Respostas:

225

Você pode criar o Dockerfile a partir do diretório pai:

docker build -t <some tag> -f <dir/dir/Dockerfile> .
Boedy
fonte
3
Obrigado! Isso funciona bem em uma caixa local, mas o Docker Hub falha ao criar a imagem, uma vez que tenta fazê-la a partir do mesmo diretório (tbh, exatamente o que seria de se esperar). Existe alguma maneira de fazer o mesmo truque no Docker Hub?
Marcel Hernandez
Não que eu saiba. Você pode enviar a imagem para o registro em vez de usar a criação automatizada.
Boedy 29/03
2
@ eduncan911 Acho que isso não foi preterido no momento em que estou escrevendo meu comentário. Eles podem ter mudado de idéia desde então? Se eu estiver errado, você pode acessar a documentação em que está sendo preterida. Obrigado!
Omninonsense
6
-f não parece ser preterido pelos documentos -> Especifique um Dockerfile (-f) : docs.docker.com/engine/reference/commandline/build/…
Ray
6
@ eduncan911 você pode excluir seu comentário, pois ele aparentemente não foi preterido? Ignorei esta resposta inicialmente por causa do seu comentário.
Chris Anderson
103

Infelizmente (por razões práticas e de segurança, eu acho), se você deseja adicionar / copiar conteúdo local, ele deve estar localizado no mesmo caminho raiz que o Dockerfile.

A partir da documentação :

O caminho <src> deve estar dentro do contexto da construção; você não pode ADICIONAR ../algo / alguma coisa, porque a primeira etapa de uma construção do docker é enviar o diretório de contexto (e subdiretórios) para o daemon do docker.

EDIT: Agora existe uma opção ( -f) para definir o caminho do seu Dockerfile; pode ser usado para alcançar o que você deseja, veja a resposta do @Boedy abaixo.

mbarthelemy
fonte
22
Existe uma solução alternativa "limpa" para isso? Prefiro não reestruturar todo o diretório do projeto apenas para acomodar isso.
precisa saber é o seguinte
Como dito por @ Günter, existe uma solução alternativa aqui superuser.com/a/842690/136024 ... é realmente "limpo"? Bem, pelo menos é uma "solução alternativa" :)
Anthony O.
2
Ver melhor resposta de @Boedy stackoverflow.com/a/34300129/2950621
nmgeek
103

Com o docker-compose, você pode definir a pasta de contexto:

#docker-compose.yml
version: '3.3'    
services:
      yourservice:
        build:
          context: ./
          dockerfile: ./docker/yourservice/Dockerfile
Nikita Kuznetsov
fonte
9

Adicionando alguns trechos de código para dar suporte à resposta aceita.

Estrutura de diretório:

setup/
 |__docker/DockerFile
 |__target/scripts/<myscripts.sh>
src/
 |__<my source files>

Entrada de arquivo do Docker:

RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/scripts/
RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/src/
WORKDIR /home/vagrant/dockerws/chatServerInstaller

#Copy all the required files from host's file system to the container file system.
COPY setup/target/scripts/install_x.sh scripts/
COPY setup/target/scripts/install_y.sh scripts/
COPY src/ src/

Comando usado para criar a imagem do Docker

docker build -t test:latest -f setup/docker/Dockerfile .
Binita Bharati
fonte
ótima abordagem. Também é possível compartilhar o código install_x.sh?
Ariful Haque
4

A solução para quem usa o compositor é usar um volume apontando para a pasta pai:

#docker-composer.yml

foo:
  build: foo
  volumes:
    - ./:/src/:ro

Mas tenho certeza de que isso pode ser feito com volumes no Dockerfile .

mais perverso
fonte
3
Não pode. Nota: O diretório do host é, por natureza, dependente do host. Por esse motivo, você não pode montar um diretório host do Dockerfile porque as imagens criadas devem ser portáteis. Um diretório de host não estaria disponível em todos os hosts em potencial. docs.docker.com/engine/tutorials/dockervolumes/...
Peeter kokk
4

Como -fcausou outro problema, desenvolvi outra solução.

  • Crie uma imagem base na pasta pai
  • Adicionado os arquivos necessários.
  • Usou esta imagem como uma imagem base para o projeto que está em uma pasta descendente.

O -fsinalizador não resolveu meu problema, porque minha onbuildimagem procura um arquivo em uma pasta e teve que chamar assim:

-f foo/bar/Dockerfile foo/bar

ao invés de

-f foo/bar/Dockerfile .

Observe também que esta é a única solução para alguns casos, como -fsinalizador

guneysus
fonte