Копирование файлов с хоста в контейнер 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
Создайте новый файл Docker и используйте существующий образ в качестве своей базы.
FROM myName/myImage:latest
ADD myFile.py bin/myFile.py
Затем создайте контейнер:
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
Обычно существует три типа:
Из контейнера в хост
docker cp container_id:./bar/foo.txt .
От хоста к контейнеру
docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
Из контейнера в контейнер смешивает 1 и 2
docker cp container_id1:./bar/foo.txt .
docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
Ответ 11
С Docker 1.8, docker cp
может копировать файлы с хоста в контейнер. См. Сообщение в блоге Docker Объявление Docker 1.8: Content Trust, Toolbox и обновления для реестра и оркестровки.
Ответ 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