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

Источник: «Docker Container Copy Files to/from the Host»
В этой статье мы рассмотрим два метода копирования файлов или папок в контейнеры Docker и из них.

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

В Docker часто возникает необходимость копирования файлов между хостом и контейнерами. Это удобно для файлов конфигурации, скриптов или любых других данных, которые должны быть доступны в среде контейнера. Например:

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

Метод 1: Использование команды docker cp

Обычно для копирования файлов или папок между контейнером и хостом, независимо от того, запущен контейнер или остановлен, используется команда docker cp.

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

Использование: docker cp [OPTIONS] container:src_path dest_path

Например, скопируем файл /etc/ssh/sshd_config на хост (f5732ee3d33c — идентификатор контейнера):

docker cp f5732ee3d33c:/etc/ssh/sshd_config /root/ssh-changes
Successfully copied 5.12kB to /root/ssh-changes

Скопируем папку /var/log на хост:

docker cp f5732ee3d33c:/var/log /root/ssh-changes
Successfully copied 768kB to /root/ssh-changes

Скопируем файл /etc/ssh/sshd_config в STDOUT. Это просто как печать содержимого файла:

docker cp f5732ee3d33c:/etc/ssh/sshd_config -
sshd_config0000644000000000000000000000624714606114611011466 0ustar0000000000000000
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.

Include /etc/ssh/sshd_config.d/*.conf

#Port 22
....

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

Использование: docker cp [OPTIONS] src_path container:dest_path

Например, скопируем файл /root/ssh-changes/sshd_config в файл в контейнере /etc/ssh/sshd_config (f5732ee3d33c — идентификатор контейнера):

docker cp /root/ssh-changes/sshd_config f5732ee3d33c:/etc/ssh/sshd_config
Successfully copied 5.12kB to f5732ee3d33c:/etc/ssh/sshd_config

Скопируем папку /root/ssh-changes/log в папку контейнера /tmp (f5732ee3d33c — идентификатор контейнера):

docker cp /root/ssh-changes/log f5732ee3d33c:/tmp
Successfully copied 768kB to f5732ee3d33c:/tmp

Извлечём tar из хоста в контейнер (f5732ee3d33c — идентификатор контейнера):

docker cp - f5732ee3d33c:/tmp < /root/ssh-changes/apps.tar
Successfully copied 0B to f5732ee3d33c:/tmp

docker exec f5732ee3d33c ls -d /tmp/apps
/tmp/apps

Опции

Опция: -a, --archive

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

Опция: -L, --follow-link

С помощью опции команда docker cp может следовать символическим ссылкам (symlinks) во время процесса копирования. При копировании каталога, содержащего символические ссылки, будет скопирован фактический файл или каталог, на который указывает символическая ссылка, а не сама символическая ссылка.

Опция: -q, --quiet

С помощью этой опции команда docker cp может автоматически подавлять вывод прогресса при копировании с подключением терминала. Вывод прогресса автоматически подавляется без подключения терминала. Это может быть удобно в сценарии или если вы не хотите видеть вывод прогресса.

Метод 2: Копирование с «хоста»на «хост»

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

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

Прежде чем начать, давайте посмотрим драйвер хранилища Docker, выполнив следующие команды:

docker info | grep Storage
Storage Driver: overlay2

OverlayFS — файловая система, используемая по умолчанию драйвером overlay2 Docker для управления файловыми системами контейнеров.

Теперь запустим контейнер «hello».

docker run -dit --name hello ubuntu:latest

Выполним команду docker inspect:

# docker container inspect hello | jq '.[0].GraphDriver'
{
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6-init/diff:/ci_runner/dockerHome/overlay2/595b425d150311a9c2637426cdc200d9f7509a7f26653ee203b35c171e379e89/diff",
"MergedDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged",
"UpperDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/diff",
"WorkDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/work"
},
"Name": "overlay2"
}

Мы можем увидеть 4 вида слоёв данных:

Эти 4 слоя в совокупности обеспечивают полную структуру файловой системы и рабочую среду для контейнеров. Обратим внимание на MergedDir, где мы можем увидеть все файлы внутри контейнера.

Перейдя в /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged, можно увидеть все файлы в контейнере.

cd /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
ls
bin dev home lib32 libx32 mnt proc run srv tmp var
boot etc lib lib64 media opt root sbin sys usr

Таким образом, копирование файла или папки аналогично операции копирования на хосте с помощью команд Linux cp, rync и так далее.

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

Например: скопируем файл /var/log/last из контейнера на хост в /tmp:

cd /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
cp ./var/log/lastlog /tmp/
ls -l /tmp/lastlog
-rw-r--r-- 1 root root 29492 Apr 21 21:38 /tmp/lastlog

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

Например: скопируем файл из хоста в каталог /root контейнера:

echo "hello!" > /tmp/hello.test
cd /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
cp /tmp/hello.test ./root/

Давайте проверим это, выполнив команду:

docker exec -it hello cat /root/hello.test
hello!

Мне нравится этот метод копирования файлов или папок между хостом и контейнерами. Я всегда пишу несколько скриптов для мониторинга конфигурационных файлов в контейнере. А также для резервного копирования или восстановления некоторых из них. В моих скриптах нет ни одной команды Docker. Я могу работать с tar, rync, ssh… поскольку контейнер прозрачен. Но контейнер должен быть запущен и не может быть остановлен.

Дополнительные материалы

Предыдущая Статья

Создание собственных PHP хелперов в Laravel проекте

Следующая Статья

Ваш первый веб-компонент