Одна из причин популярности Docker — это возможность контейнеризации без установки дополнительных зависимостей на локальном компьютере. Docker использует технологию виртуализации, которая создает изолированную среду для запуска приложений.
Движок Docker берет на себя роль назначения ресурсов хоста изолированному приложению в контейнере. Как только такое приложение попадает в контейнер, виртуализированные данные приложения изолируются от хоста. Это приводит к тому, что все данные приложения в контейнере остаются в нём.
Но зачастую возникает необходимость, чтобы приложение в контейнере обменивалось данными и файлами с хост-компьютером.
По умолчанию все файлы, созданные в контейнере, хранятся в нём. Когда контейнер останавливается, данные теряются. В Docker существуют тома, которые используются для хранения данных на хост-системе, чтобы данные не терялись даже после остановки контейнера.
В этой статье мы расскажем, как организовать передачу данных между хост-компьютером и контейнером Docker.
Для демонстрации передачи данных между хостом и контейнером будем использовать Nginx и HTML страницы.
В первую очередь убедимся, что Docker установлен на компьютер:
docker --version
Если Docker не обнаружен, то вы можете найти инструкции по его установке в статьях «Как установить Docker на Ubuntu 22.04: инструкция» и «Что такое Docker».
Теперь извлечем из репозитория Docker образ Nginx с помощью следующей команды:
docker pull nginx
Проверить успешность загрузки образа можно командой docker image ls
. Она выводит список загруженных образов в терминал:
В Docker том или volume
— это механизм для хранения и управления данными, которые используются внутри контейнеров. Том можно рассматривать как отдельную файловую систему, которая существует вне контейнера и может быть подключена к одному или нескольким контейнерам.
Основное преимущество использования томов в Docker заключается в том, что они позволяют сохранять данные между запусками контейнеров и даже между удалением и созданием новых контейнеров. Также тома могут использоваться для обмена данными между контейнерами, например, когда несколько контейнеров должны иметь доступ к общей файловой системе.
Docker предоставляет множество инструментов для работы с томами, включая команды для создания, удаления, подключения и отключения томов, а также возможность указать, какой том должен быть использован в контейнере при его запуске.
В Docker доступ из контейнера к хосту можно обеспечить с помощью уже существующего каталога в файловой системе хоста (bind mount
) или новой сущности volume
. Мы рассмотрим оба способа.
kube
По умолчанию приложения в Docker-контейнерах являются stateless. Это означает, приложение не оставляет данных после своей работы. Поэтому в Docker предусмотрены различные методы для хранения данных. В этом разделе расскажем о bind mount
.
Bind mount реализует следующий принцип работы: файл с данными хранится на хосте и открывается внутри контейнера. Поскольку данные хранятся на хосте, они не теряются при завершении работы контейнера.
В качестве файла с данными будем использовать HTML-страницу.
Чтобы использовать bind mount
, выполним следующие шаги:
Шаг 1. Создадим каталог с HTML-файлом:
mkdir -p /tmp/nginx/html
Шаг 2. Соберем и запустим контейнер с образом Nginx командой docker run
:
docker run -t -d -P -v /tmp/nginx/html:/usr/share/nginx/html --name nginxcont nginx:latest
Параметры этой команды запустят контейнер с именем nginxcont
с образом Nginx в фоновом режиме и передадут в контейнер каталог с HTML:
-t
выделит псевдо-TTY для интерактивного взаимодействия с контейнером;-d
запустит контейнер в фоновом режиме;-P
привяжет контейнер к случайному порту;-v
используем, чтобы в Docker примонтировать папку хоста в контейнер.После выполнения вышеуказанной команды проверим запущенные контейнеры с помощью команды:
docker container ls
Шаг 3. Узнаем IP-адрес.
Чтобы узнать IP-адрес хоста Docker, введите команду ниже:
hostname -I
Номер порта можно узнать из контейнера, который мы создали в предыдущем процессе, проверив его в колонке PORTS
или просто выполнив команду run docker container ls
. Это позволит получить номер порта, присвоенный используемому нами контейнеру.
Перейдите в браузер и введите следующий URL:
http://<ip_адрес>:<порт>
Поскольку у нас нет HTML-файла в каталоге, содержимое должно быть похоже на:
Шаг 4. Тестирование
В директории /tmp/nginx/html
создайте файл index.html
:
nano /tmp/nginx/html/index.html
И добавьте в него следующие строки кода:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>Проверяем работоспособность bind mount</title>
</head>
<body>
<h1>Этот HTML файл взят с хост машины</h1>
<p>
Если вы видите эту страницу, то всё работает. Файл взят из директории /tmp/nginx/html и передан в контейнер через консоль.
</p>
<p>
</p>
<p><em>Timeweb Cloud blog 2023</em></p>
</body>
</html>
Чтобы сохранить файл нажмите ctrl+X, а затем Y.
После создания файла обновите вкладку браузера, и вы увидите новое содержимое:
Если вы обновите файл, то снова увидите изменения после обновления страницы. Теперь вы знаете, как передавать файлы с хост-компьютера на контейнер Docker с помощью bind mount
.
Если вы видите ошибку «Сайт localhost не отправил данные Docker», то проверьте:
Чтобы использовать тома для обмена данными между хостом и контейнером, выполните следующие шаги.
Шаг 1. Создайте том.
Создать новый том можно этой командой:
docker volume create simplevol
simplevol
— название нового тома. Чтобы проверить успешность команды, можно вывести список всех томов:
docker volume ls
Результат:
Шаг 2. Запустите контейнер Docker.
Запустим новый контейнер nginxcont1
с образом NGINX этой командой:
docker run -t -d -P -v simplevol:/usr/share/nginx/html --name nginxcont1 nginx:latest
Тому на локальном хосте сопоставлена директория внутри контейнера, из которой NGINX берет HTML.
Контейнер создан и должен быть запущен. Чтобы проверить состояние контейнера, выполним эту команду:
docker container ls
Шаг 3. Узнайте IP-адрес.
Чтобы получить IP-адрес хост-компьютера, выполнив команду ifconfig
:
ifconfig
Ваш IP-адрес будет указан в параметре inet
. В нашем случае это 172.19.0.1
:
Номер порта берем из колонки PORTS
в выводе списка запущенных контейнеров.
Перейдем по адресу http://<ip_адрес>:<порт>
. Нас должна встретить стандартная страница NGINX:
Шаг 4. Тестирование.
Сначала скопируем файл index.html
из контейнера на хост-компьютер. Для этого воспользуемся следующей командой:
docker cp nginxcont1:/usr/share/nginx/html/index.html index.html
Откроем файл с помощью редактора, обновим его следующим образом и сохраним:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>Проверяем работоспособность томов</title>
</head>
<body>
<h1>Этот HTML код запущен в контейнере с образом NGINX</h1>
<p>
Если вы видите эту страницу, то всё работает. Файл index.html находится в томе и передан в контейнер через консоль.
</p>
<p>
</p>
<p><em>Timeweb Cloud blog 2023</em></p>
</body>
</html>
Переместить обратно отредактированный файл с вашего компьютера в контейнер Docker можно, выполнив эту команду:
docker cp index.html nginxcont1:/usr/share/nginx/html
Если вы обновите ранее открытую вкладку, содержимое обновится:
В этой статье мы рассмотрели два способа передачи данных между хостом и контейнером. Если вы используете тома Docker, вы можете применить использовать их и для обмена данными между различными средами, запущенным в среде Docker.