Копирование файлов с хоста в контейнер Docker

Я пытаюсь создать решение для резервного копирования и восстановления для контейнеров Docker, с которыми мы работаем.

У меня есть базовое изображение Docker, которое я создал, ubuntu:base и не хочу, чтобы каждый раз его перестраивать с помощью файла Docker для добавления файлов к нему.

Я хочу создать script, который запускается с главной машины и создает новый контейнер с использованием изображения ubuntu:base Docker, а затем копирует файлы в этот контейнер.

Как скопировать файлы с хоста в контейнер?

Ответы

Ответ 1

Команда cp может использоваться для копирования файлов.

В контейнер можно скопировать один конкретный файл, например:

docker cp foo.txt mycontainer:/foo.txt

Один конкретный файл можно скопировать из контейнера, например:

docker cp mycontainer:/foo.txt foo.txt

Для акцента, mycontainer - это идентификатор контейнера, не идентификатор изображения.

Несколько файлов, содержащихся в папке src, можно скопировать в папку target с помощью:

docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target

Ссылка: Документация по интерфейсу командной строки Docker для cp

В версиях Docker до 1.8 было возможно только копировать файлы из контейнера на хост. Не от хоста до контейнера.

Ответ 2

  • Получить имя контейнера или короткий идентификатор контейнера:

    $ docker ps
    
  • Получить полный идентификатор контейнера:

    $ docker inspect -f   '{{.Id}}'  SHORT_CONTAINER_ID-or-CONTAINER_NAME
    
  • Скопировать файл:

    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
    

Пример:

$ docker ps

CONTAINER ID      IMAGE    COMMAND       CREATED      STATUS       PORTS        NAMES

d8e703d7e303   solidleon/ssh:latest      /usr/sbin/sshd -D                      cranky_pare

$ docker inspect -f   '{{.Id}}' cranky_pare

или

$ docker inspect -f   '{{.Id}}' d8e703d7e303

d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5

$ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt

Ответ 3

Самый простой способ - смонтировать каталог хоста на контейнере при запуске контейнера:

{host} docker run -v /path/to/hostdir:/mnt --name my_container my_image
{host} docker exec -it my_container bash
{container} cp /mnt/sourcefile /path/to/destfile

Ответ 4

Ниже приведен довольно уродливый способ сделать это, но он работает.

docker run -i ubuntu /bin/bash -c 'cat > file' < file

Ответ 5

Если вам нужно сделать это на работающем контейнере, вы можете использовать docker exec (добавлено в 1.3).

Сначала найдите имя контейнера или идентификатор:

$ docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                   NAMES
b9b7400ddd8f        ubuntu:latest                "/bin/bash"         2 seconds ago       Up 2 seconds                                elated_hodgkin

В приведенном выше примере мы можем либо использовать b9b7400ddd8f, либо elated_hodgkin.

Если вы хотите скопировать все в /tmp/somefiles на хосте в /var/www в контейнере:

$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www

Затем мы можем выполнить exec /bin/bash в контейнере и проверить его работу:

$ docker exec -it elated_hodgkin /bin/bash
[email protected]:/# ls /var/www
file1  file2

Ответ 6

Решение приведено ниже,

Из оболочки Docker,

[email protected]:/root#  <-- get the container ID

От хоста

cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root

Файл должен быть скопирован непосредственно в место, где находится контейнер в файловой системе.

Ответ 7

  1. Создайте новый файл Docker и используйте существующий образ в качестве своей базы.

    FROM myName/myImage:latest
    
    ADD myFile.py bin/myFile.py
    
  2. Затем создайте контейнер:

    docker build .
    

Ответ 8

Другое решение для копирования файлов в запущенный контейнер использует tar:

tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x

Копирует файл foo.sh в /tmp контейнера.

Изменить: Удалить reduntant -f, благодаря комментарию Maarten.

Ответ 9

Чтобы скопировать файл из хоста в рабочий контейнер

docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH

На основе ответа Эрика и комментариев Mikl и z0r.

Ответ 10

Обычно существует три типа:

  1. Из контейнера в хост

    docker cp container_id:./bar/foo.txt .
    

dev1

  1. От хоста к контейнеру

    docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev2

  1. Из контейнера в контейнер смешивает 1 и 2

    docker cp container_id1:./bar/foo.txt .
    
    docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev3

Ответ 12

Это прямой ответ на вопрос "Копирование файлов из узла в контейнер Docker", поднятый в этом вопросе в заголовке.

Попробуйте docker cp. Это самый простой способ сделать это и работать даже на моем Mac. Использование:

docker cp /root/some-file.txt some-docker-container:/root

Это скопирует файл some-file.txt в каталог /root на хост-машине в контейнер Docker с именем some-docker-container в каталог /root. Он очень близок к синтаксису защищенной копии. И как показано в предыдущем посте, вы можете использовать его наоборот. I.e., вы также копируете файлы из контейнера в хост.

И перед тем, как вы поделитесь этим сообщением, введите docker cp --help. Чтение документации может быть очень полезно, иногда...

Если вам это не нравится, и вам нужны тома данных в уже созданном и запущенном контейнере, тогда отдых - это ваш единственный вариант сегодня. См. Также Как добавить том в существующий контейнер Docker?.

Ответ 13

Я попробовал большинство решений (с голосованием) здесь, но в докере 17.09 (в 2018 году) больше нет папки /var/lib/docker/aufs.

Этот простой docker cp решил эту задачу.

docker cp c:\path\to\local\file container_name:/path/to/target/dir/

Как получить имя контейнера?

 docker ps 

Есть раздел NAMES. Не используйте IMAGE.

Ответ 14

Чтобы скопировать файлы/папки между контейнером и локальной файловой системой, введите команду:

docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}

Например,

docker cp /home/foo container-id:/home/dir

Чтобы получить идентификатор contianer, введите данную команду:

docker ps

Вышеуказанное содержание взято с docker.com.

Ответ 15

Предполагая, что контейнер уже запущен, введите следующую команду:

# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"

Чтобы обмениваться файлами с помощью общего каталога, запустите контейнер, введя заданную команду:

# docker run -v /path/to/host/dir:/path/to/container/dir ...

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

Ответ 16

В среде докеров все контейнеры находятся в каталоге:

/var/lib/docker/aufs/required-docker-id/

Чтобы скопировать исходный каталог/файл в любую часть контейнера, введите следующую команду:

sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/

Ответ 17

Если хост является CentOS или Fedora, в прокси-сервере /var/lib/docker/aufs имеется прокси NOT, но оно находится под /proc:

cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root

Этот cmd скопирует все содержимое каталога data в / контейнера с id "containerid".

Ответ 18

tar и docker cp - хорошая комбинация для копирования всего в каталог.

Создайте контейнер объема данных

docker create --name dvc --volume /path/on/container cirros

Чтобы сохранить иерархию каталогов

tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container

Проверьте свою работу

docker run --rm --volumes-from dvc cirros ls -al /path/on/container

Ответ 19

Если кому-то вроде меня mycontainer что mycontainer в ответе @h3nrik, то это фактически идентификатор контейнера. Чтобы скопировать файл WarpSquare.mp4 в /app/example_scenes/1440p60 из /app/example_scenes/1440p60 контейнера докера в текущую папку, я использовал это.

docker cp 'docker ps -q -l':/app/example_scenes/1440p60/WarpSquare.mp4 .

где docker ps -q -l извлекает идентификатор контейнера последнего вышедшего экземпляра. Если это не выходной контейнер, вы можете получить его через docker container ls или docker ps

Ответ 20

Это команда для копирования данных из Docker на Host:

docker cp container_id:file path/filename /hostpath

docker cp a13fb9c9e674:/tmp/dgController.log /tmp/

Ниже приведена команда для копирования данных с хоста на докер:

docker cp a.txt ccfbeb35116b:/home/

Ответ 21

Многие из тех, кто находит этот вопрос, могут фактически иметь проблему копирования файлов в изображение Docker во время его создания (я сделал).

В этом случае вы можете использовать команду COPY в Dockerfile, которую вы используете для создания изображения.

См. документацию.

Ответ 22

Вы можете просто проследить IP-адрес своего локального компьютера, используя

ifconfig

Затем просто войдите в контейнер Docker и введите

scp [email protected]_address:/path_to_the_file destination

В любом случае, если у вас нет клиента и сервера SSH, просто установите его, используя:

sudo apt-get install openssh-server

Ответ 23

Лучший способ скопировать файлы в найденный контейнер - это установить каталог на хосте, используя команду -v команды запуска docker.

Ответ 24

Есть хорошие ответы, но слишком конкретные. Я узнаю, что docker ps - это хороший способ получить идентификатор контейнера, который вам интересен. Затем выполните

mount | grep <id>

чтобы узнать, где установлен громкость. Это

/var/lib/docker/devicemapper/mnt/<id>/rootfs/

для меня, но это может быть другой путь в зависимости от ОС и конфигурации. Теперь просто скопируйте файлы на этот путь.

Использование -v не всегда практично.

Ответ 25

Я только начал использовать docker для компиляции VLC, вот что вы можете сделать, чтобы копировать файлы туда и обратно из контейнеров:

su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt

Ищите знакомый файл в этом тексте, и у вас будет папка, перейдите к нему как root и вуаля! Скопируйте все, что вы хотите.

Там может быть путь с "слитым" в нем, я думаю, вы хотите тот, в котором есть "diff".

Также, если вы выходите из контейнера и хотите вернуться туда, где остановились:

docker ps -a
docker start -i containerid

Я думаю, это полезно, когда вы ничего не назвали с помощью команды, как

docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash

Конечно, хакерский метод, но что с того?

Ответ 26

Я просто копирую файл непосредственно из того места, где находится контейнер с главной машины.

Например:

Сначала найдите идентификатор контейнера:

[email protected]**3aed62678d54**:/home#

А затем с хоста, скажем, файл находится в домашнем каталоге:

[email protected]:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/

Вернуться в контейнер...

[email protected]**3aed62678d54**:/home# ls cheering_nasa.gif

Ответ 27

Если у вас нет каталога, определенного как тома в файле Dockerfile, работа/var/lib/docker/aufs/mnt//будет работать. Но бывают случаи, когда каталог в контейнере определяется как тома. В этом случае содержимое под aufs/mnt/*/и содержимое, видимое контейнером, различны.

Вам нужно будет осмотреть контейнер с помощью проверки докеров, а затем искать тома. Там вы найдете упоминание о чем-то вроде /var/lib/docker/vfs/dir/fe 940b... (id). Вам нужно будет добавить/изменить файлы здесь, а не под aufs/mnt/*.

Запутанная часть состоит в том, что файлы также отображаются под /aufs/mnt/ *. Я потратил немало времени, почесывая голову, почему изменения здесь не сработали для меня. Надеюсь, это поможет кому-то.

Ответ 28

Мой любимый метод:

КОНТЕЙНЕРЫ:

CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')

file.txt

mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt

или

mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt

Ответ 29

Я бы смонтировал, а затем запустил изображение с помощью демона, только как указано здесь:

docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

затем

docker exec -it mntcontainer bash

Ответ 30

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

От вашего хоста:

scp FILE_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt

В случае необходимости скопировать каталог:

scp -r DIR_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory

обязательно установите ssh в свой контейнер.

apt-get install openssh-server