Docker: ajouter un fichier à partir d'un répertoire parent

196

Dans mon Dockerfilej'ai:

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

Ce fichier existe et ls ../../myapp.warme renvoie le fichier correct mais lorsque je l'exécute, sudo docker build -t myapp .j'ai:

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

Quelqu'un sait-il pourquoi et comment le faire correctement?

Anthony O.
la source
2
Quelques solutions de contournement superuser.com/questions/842642
Günter Zöchbauer

Réponses:

238

Vous pouvez créer le Dockerfile à partir du répertoire parent:

docker build -t <some tag> -f <dir/dir/Dockerfile> .
Boedy
la source
3
Merci! Cela fonctionne bien sur une boîte locale, mais Docker Hub ne parvient pas à créer l'image car il essaie de le faire à partir de son même répertoire (tbh, exactement ce à quoi on s'attend normalement). Existe-t-il un moyen de faire la même chose dans Docker Hub?
Marcel Hernandez
Pas que je sache de. Vous pouvez pousser l'image vers le registre au lieu d'utiliser la génération automatisée.
Boedy
2
@ eduncan911 Je ne pense pas que cela soit obsolète au moment où j'écris mon commentaire. Ils ont peut-être changé d'avis depuis? Si je me trompe, pouvez-vous créer un lien vers la documentation où il est dit qu'elle est obsolète. Merci!
omninonsense
6
-f ne semble pas être obsolète par la documentation -> Spécifiez un fichier Docker (-f) : docs.docker.com/engine/reference/commandline/build/…
Ray
7
@ eduncan911 pouvez-vous supprimer votre commentaire puisqu'il n'est apparemment pas obsolète? J'ai sauté cette réponse au départ à cause de votre commentaire.
Chris Anderson
114

Avec docker-compose, vous pouvez définir le dossier contextuel:

#docker-compose.yml
version: '3.3'    
services:
      yourservice:
        build:
          context: ./
          dockerfile: ./docker/yourservice/Dockerfile
Nikita Kuznetsov
la source
104

Malheureusement, (pour des raisons pratiques et de sécurité je suppose), si vous souhaitez ajouter / copier du contenu local, il doit être situé sous le même chemin racine que le Dockerfile.

De la documentation :

Le chemin <src> doit être dans le contexte de la construction; vous ne pouvez pas AJOUTER ../quelque chose / quelque chose, car la première étape d'une construction de docker est d'envoyer le répertoire de contexte (et les sous-répertoires) au démon docker.

EDIT: Il y a maintenant une option ( -f) pour définir le chemin de votre Dockerfile; il peut être utilisé pour réaliser ce que vous voulez, voir la réponse de @Boedy ci-dessous.

mbarthelemy
la source
23
Existe-t-il une solution de contournement «propre» pour cela? Je préfère ne pas restructurer tout mon répertoire de projet juste pour tenir compte de cela.
ben_frankly
Comme l'a dit @ Günter, il y a une solution de contournement ici superuser.com/a/842690/136024 ... est-ce vraiment "propre"? Eh bien au moins, c'est une "solution de contournement" :)
Anthony O.
2
Voir une meilleure réponse de @Boedy stackoverflow.com/a/34300129/2950621
nmgeek
13

Ajout d'extraits de code pour prendre en charge la réponse acceptée.

Structure du répertoire:

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

Entrée de fichier 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/

Commande utilisée pour créer l'image du docker

docker build -t test:latest -f setup/docker/Dockerfile .
Binita Bharati
la source
excellente approche. Est-il possible de partager également le code de install_x.sh?
Ariful Haque le
5

Depuis -fcausé un autre problème, j'ai développé une autre solution.

  • Créer une image de base dans le dossier parent
  • Ajout des fichiers requis.
  • Utilisé cette image comme image de base pour le projet qui dans un dossier descendant.

Le -fdrapeau ne résout pas mon problème car mon onbuildimage recherche un fichier dans un dossier et a dû appeler comme ceci:

-f foo/bar/Dockerfile foo/bar

au lieu de

-f foo/bar/Dockerfile .

Notez également que ce n'est une solution que pour certains cas comme -fdrapeau

guneysus
la source
4

La solution pour ceux qui utilisent composer est d'utiliser un volume pointant vers le dossier parent:

#docker-composer.yml

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

Mais je suis presque sûr que vous pouvez jouer avec des volumes dans Dockerfile .

wikier
la source
4
Ça ne peut pas. Remarque: Le répertoire hôte est, de par sa nature, dépendant de l'hôte. Pour cette raison, vous ne pouvez pas monter un répertoire hôte à partir de Dockerfile car les images construites doivent être portables. Un répertoire d'hôtes ne serait pas disponible sur tous les hôtes potentiels. docs.docker.com/engine/tutorials/dockervolumes/…
Peeter Kokk