Как скопировать папки на изображение докеров с Dockerfile?

Я попробовал следующую команду в файле Docker: COPY * / и сильно удивил результат. Кажется, что наивный код докера пересекает каталоги из glob, а затем сбрасывает каждый файл в целевой каталог, почтительно игнорируя мою структуру каталогов.

По крайней мере, так я понимаю этот билет, и это, безусловно, соответствует результату, который я получил.

Я предполагаю, что единственная причина, по которой это поведение может существовать, заключается в том, что есть и другой способ, которым это должно быть сделано. Но медведю с очень маленьким мозгом нелегко понять, как, кто-нибудь знает?

Ответ 1

Как упомянутый в вашем билете:

У вас есть COPY files/* /test/, который расширяется до COPY files/dir files/file1 files/file2 files/file /test/.
Если вы разделите это на отдельные команды COPY (например, COPY files/dir /test/), вы увидите, что (к лучшему или худшему) COPY скопирует содержимое каждого arg dir в целевой каталог. Не сам arg dir, а содержимое.

Я не в восторге от того факта, что COPY не сохраняет репертуар верхнего уровня, но теперь это было какое-то время.

поэтому во имя сохранения обратной совместимости структура COPY/ADD невозможна.

Единственным обходным решением будет серия RUN mkdir -p /x/y/z для построения целевой структуры каталогов, за которой следует серия docker COPY (по одному для каждой папки для заполнения).

Ответ 2

Как и @Vonc, нет возможности добавить команду, как сейчас. Единственным обходным решением является упоминание папки, ее создание и добавление в нее содержимого.

# add contents to folder
ADD src $HOME/src

Создал бы папку с именем src в вашем каталоге и добавил в нее содержимое вашей папки src.

Ответ 3

Замените * на /

Поэтому вместо

COPY * <destination>

использование

COPY/<destination>

Ответ 4

Используйте ADD (docs)

Команда ADD может принимать в качестве параметра <src>:

  1. Папка в папке сборки (та же папка, что и файл Docker). Затем вы добавили бы строку в свой файл Docker, например: ADD folder/path/inside/your/container

или же

  1. Однофайловый архив в любом месте вашей файловой системы хоста. Чтобы создать архив, используйте команду: tar -cvzf newArchive.tar.gz/path/to/your/folder Затем вы добавили бы строку в свой файл Docker, например: ADD/path/to/archive/newArchive.tar.gz/path/inside/your/container

Заметки:

  • ADD автоматически извлечет ваш архив.
  • наличие/отсутствие косых черт важно, см. связанные документы

Ответ 5

используйте ADD вместо COPY. Предположим, вы хотите скопировать все в каталог src из хоста в каталог dst из контейнера:

ADD src dst

Примечание: b будет автоматически создаваться в контейнере.

Ответ 6

COPY. <destination>

Что будет в вашем случае:

COPY./

Ответ 7

Я не совсем понимаю случай оригинального постера, но могу доказать, что можно скопировать структуру каталогов, используя COPY в Dockerfile.

Предположим, у вас есть эта структура папок:

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

Чтобы скопировать его в целевое изображение, вы можете использовать такой контент Dockerfile:

FROM nginx

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

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

Вывод docker build. следующее:

$ 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

Ответ 8

Для меня это работало нормально. В папке "images" есть подпапки, содержащие изображения.

cd /home/learner/images
sudo docker cp ./ f4fc13247708:/root/openface/training-images/