Копирование файлов из хоста в контейнер 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 это было только возможно копирование файлов из контейнера на хост. Не от хозяина к контейнеру.
-
получить имя контейнера или короткий идентификатор контейнера:
$ 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
самый чистый способ-смонтировать каталог хоста на контейнере при запуске контейнера:
{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 комментарий.
очень просто
-
создайте новый файл dockerfile и используйте существующее изображение в качестве базы.
FROM myName/myImage:latest ADD myFile.py bin/myFile.py
-
затем создайте контейнер:
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
один раз попробовать!