web-dev-qa-db-fra.com

Comment copier des dossiers sur une image de menu fixe à partir de Dockerfile?

J'ai essayé la commande suivante dans mon fichier Dockerfile: COPY * / et j'ai été très surpris du résultat. Semble que le code de menu fixe naïf parcourt les répertoires à partir du glob, puis vide chaque fichier du répertoire cible en ignorant respectueusement la structure de mes répertoires. 

Du moins, c'est ainsi que je comprends ce billet et cela correspond certainement au résultat que j'ai obtenu. 

Je suppose que la seule raison pour laquelle ce comportement peut encore exister doit être qu’il existe un autre moyen de le faire. Mais il n’est pas facile pour un ours de très petite cervelle de comprendre comment sait-on?

19
jonalv

Comme @Vonc l'a dit, il n'y a aucune possibilité d'ajouter une commande comme à partir de maintenant. La seule solution consiste à mentionner le dossier, à le créer et à y ajouter du contenu.

# add contents to folder
ADD src $HOME/src

Cela créerait un dossier appelé src dans votre répertoire et ajouterait le contenu de votre dossier src dans ce dossier.

8
Balasubramani M

Comme mentionné dans votre billet :

Vous avez COPY files/* /test/ qui se développe en COPY files/dir files/file1 files/file2 files/file /test/.
Si vous divisez cela en plusieurs commandes COPY (par exemple, COPY files/dir /test/), vous verrez que (pour le meilleur ou pour le pire) COPY va copier le contenu de chaque argument dir dans le répertoire de destination. Pas l'arg dir lui-même, mais le contenu. 

Je ne suis pas enthousiasmé par le fait que COPY ne conserve pas le répertoire de haut niveau mais le reste depuis un moment.

ainsi, dans le but de préserver une compatibilité ascendante, il n'est pas possible de modifier COPY/ADD une structure de répertoire.

La seule solution de contournement serait une série de RUN mkdir -p /x/y/z pour créer la structure de répertoires cible, suivie d'une série de docker ADD (un pour chaque dossier à remplir).
(ADD, pas COPY, selon les commentaires)

7
VonC

Utilisez ADD ( docs )

La commande ADD peut accepter comme paramètre <src>

  1. Un dossier dans le dossier de construction (le même dossier que votre fichier Docker). Vous ajouteriez ensuite une ligne dans votre fichier Docker comme ceci: ADD folder /path/inside/your/container

ou

  1. Une archive à fichier unique, n’importe où dans votre système de fichiers hôte. Pour créer une archive, utilisez la commande: tar -cvzf newArchive.tar.gz /path/to/your/folder Vous ajouteriez alors une ligne à votre fichier Docker comme ceci: ADD /path/to/archive/newArchive.tar.gz /path/inside/your/container

Remarques:

  • ADD extraira automatiquement votre archive. 
  • la présence/l'absence de barres obliques de fin est importante, voir les documents liés
5
ryanrain

Remplacez le * par un /

Donc au lieu de 

COPY * <destination>

utilisation

COPY / <destination>

4
rayscott

utilisez ADD au lieu de COPY. Supposons que vous souhaitiez tout copier du répertoire src de l'hôte vers le répertoire dst du conteneur:

ADD src dst

Remarque: b sera automatiquement créé dans le conteneur.

3
Hin Fan Chan

COPY . <destination>

Quel serait dans votre cas:

COPY . /

1
Klaus

Je ne comprends pas complètement le cas de l'affiche originale, mais je peux prouver qu'il est possible de copier la structure de répertoires en utilisant COPY dans Dockerfile.

Supposons que vous ayez cette structure de dossiers:

folder1
  file1.html
  file2.html
folder2
  file3.html
  file4.html
  subfolder
    file5.html
    file6.html

Pour le copier sur l’image de destination, vous pouvez utiliser un tel contenu Dockerfile:

FROM nginx

COPY ./folder1/ /usr/share/nginx/html/folder1/
COPY ./folder2/ /usr/share/nginx/html/folder2/

RUN ls -laR /usr/share/nginx/html/*

La sortie de docker build . comme suit:

$ docker build --no-cache .
Sending build context to Docker daemon  9.728kB
Step 1/4 : FROM nginx
 ---> 7042885a156a
Step 2/4 : COPY ./folder1/ /usr/share/nginx/html/folder1/
 ---> 6388fd58798b
Step 3/4 : COPY ./folder2/ /usr/share/nginx/html/folder2/
 ---> fb6c6eacf41e
Step 4/4 : RUN ls -laR /usr/share/nginx/html/*
 ---> Running in face3cbc0031
-rw-r--r-- 1 root root  494 Dec 25 09:56 /usr/share/nginx/html/50x.html
-rw-r--r-- 1 root root  612 Dec 25 09:56 /usr/share/nginx/html/index.html

/usr/share/nginx/html/folder1:
total 16
drwxr-xr-x 2 root root 4096 Jan 16 10:43 .
drwxr-xr-x 1 root root 4096 Jan 16 10:43 ..
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file1.html
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file2.html

/usr/share/nginx/html/folder2:
total 20
drwxr-xr-x 3 root root 4096 Jan 16 10:43 .
drwxr-xr-x 1 root root 4096 Jan 16 10:43 ..
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file3.html
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file4.html
drwxr-xr-x 2 root root 4096 Jan 16 10:33 subfolder

/usr/share/nginx/html/folder2/subfolder:
total 16
drwxr-xr-x 2 root root 4096 Jan 16 10:33 .
drwxr-xr-x 3 root root 4096 Jan 16 10:43 ..
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file5.html
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file6.html
Removing intermediate container face3cbc0031
 ---> 0e0062afab76
Successfully built 0e0062afab76
0
Mike Eshva