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

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

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

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

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

30 ответов


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

docker cp foo.txt mycontainer:/foo.txt
docker cp mycontainer:/foo.txt foo.txt

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

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

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

ссылки: докер CLI документы для cp

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


  1. получить имя контейнера или короткий идентификатор контейнера:

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

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

    $ 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

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

{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

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

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

Если вам нужно сделать это на работающем контейнере, вы можете использовать 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
root@b9b7400ddd8f:/# ls /var/www
file1  file2

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

из оболочки Докера,

root@123abc:/root#  <-- get the container ID

от ведущего

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

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


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

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

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

Edit: удалить reduntant -f, спасибо Маартенs комментарий.


очень просто

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

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

    docker build .
    

скопировать файл от хоста к работающему контейнеру

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

на основе Эрика и комментарии Микла и z0r.


С Docker 1.8, docker cp умеет копировать файлы с хоста в контейнер. Смотрите в блоге "докер" в должности объявление Docker 1.8: Content Trust, Toolbox и обновления реестра и оркестровки.


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

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

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

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

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

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


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

# 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 ...

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


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

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

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

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


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

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

например,

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

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

docker ps

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


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

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

ifconfig

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

scp user_name@ip_address:/path_to_the_file destination

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

sudo apt-get install openssh-server

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

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

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

как получить имя контейнера? (Есть . Не используйте IMAGE.)

 docker ps 

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

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

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


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

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

этот cmd скопирует все содержимое до / контейнера с идентификатором "containerid".


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


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

mount | grep <id>

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

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

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

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


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

например:

сначала узнайте идентификатор контейнера:

root@**3aed62678d54**:/home#

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

root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/

назад к контейнеру...

root@**3aed62678d54**:/home# ls cheering_nasa.gif

Если вы используете Windows в качестве хоста, вы можете использовать помощью WinSCP для подключения к Docker и передачи файлов через GUI.

Если на Linux, то также будет работать через терминал.


это onliner для копирования одного файла при запуске контейнера tomcat.

docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat

Это позволит скопировать файл War в webapps и получить ваше приложение работает в кратчайшие сроки.


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

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

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


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

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

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


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

тара

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

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

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

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

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

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

одна вещь, которую я пробовал и он работал

Как только вы развернете свой контейнер docker и создадите любой файл под этим контейнером; вы можете легко получить доступ к этому файлу из-под местоположения вашего хоста docker: -

компакт-диск /ВАР/Либ/докер/aufs/контейнеры/container_id в/tmp

один раз попробовать!