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

Передача данных между контейнером Docker и хостом

Команда Timeweb Cloud
Команда Timeweb Cloud
Наши инженеры, технические писатели, редакторы и маркетологи
20 апреля 2023 г.
6375
7 минут чтения
Средний рейтинг статьи: 5

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

Движок Docker берет на себя роль назначения ресурсов хоста изолированному приложению в контейнере. Как только такое приложение попадает в контейнер, виртуализированные данные приложения изолируются от хоста. Это приводит к тому, что все данные приложения в контейнере остаются в нём.

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

По умолчанию все файлы, созданные в контейнере, хранятся в нём. Когда контейнер останавливается, данные теряются. В Docker существуют тома, которые используются для хранения данных на хост-системе, чтобы данные не терялись даже после остановки контейнера. 

В этой статье мы расскажем, как организовать передачу данных между хост-компьютером и контейнером Docker.

Предварительная подготовка

Для демонстрации передачи данных между хостом и контейнером будем использовать Nginx и HTML страницы. 

В первую очередь убедимся, что Docker установлен на компьютер:

docker --version

Если Docker не обнаружен, то вы можете найти инструкции по его установке в статьях «Как установить Docker на Ubuntu 22.04: инструкция» и «Что такое Docker».

Теперь извлечем из репозитория Docker образ Nginx с помощью следующей команды:

docker pull nginx

Проверить успешность загрузки образа можно командой docker image ls. Она выводит список загруженных образов в терминал:

Image5

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

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

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

В Docker доступ из контейнера к хосту можно обеспечить с помощью уже существующего каталога в файловой системе хоста (bind mount) или новой сущности volume. Мы рассмотрим оба способа.

Bind mount

По умолчанию приложения в 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

Image3

Шаг 3. Узнаем IP-адрес.

Чтобы узнать IP-адрес хоста Docker, введите команду ниже:

hostname -I

Номер порта можно узнать из контейнера, который мы создали в предыдущем процессе, проверив его в колонке PORTS или просто выполнив команду run docker container ls. Это позволит получить номер порта, присвоенный используемому нами контейнеру.

Перейдите в браузер и введите следующий URL: 

http://<ip_адрес>:<порт>

Поскольку у нас нет HTML-файла в каталоге, содержимое должно быть похоже на:

Image6

Шаг 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.

После создания файла обновите вкладку браузера, и вы увидите новое содержимое:

Image1

Если вы обновите файл, то снова увидите изменения после обновления страницы. Теперь вы знаете, как передавать файлы с хост-компьютера на контейнер Docker с помощью bind mount.

Если вы видите ошибку «Сайт localhost не отправил данные Docker», то проверьте:

  • каталог, в котором запущен контейнер;
  • запущен ли контейнер;
  • нет ли конфликта приложений по порту: возможно, порт был закреплен за другим приложением.

Том

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

Шаг 1. Создайте том.

Создать новый том можно этой командой:

docker volume create simplevol

simplevol — название нового тома. Чтобы проверить успешность команды, можно вывести список всех томов:

docker volume ls

Результат:

Image8

Шаг 2. Запустите контейнер Docker.

Запустим новый контейнер nginxcont1 с образом NGINX этой командой:

docker run -t -d -P  -v simplevol:/usr/share/nginx/html --name nginxcont1 nginx:latest

Тому на локальном хосте сопоставлена директория внутри контейнера, из которой NGINX берет HTML. 

Контейнер создан и должен быть запущен. Чтобы проверить состояние контейнера, выполним эту команду:

docker container ls

Image3

Шаг 3. Узнайте IP-адрес.

Чтобы получить IP-адрес хост-компьютера, выполнив команду ifconfig:

ifconfig

Ваш IP-адрес будет указан в параметре inet. В нашем случае это 172.19.0.1:

Image4

Номер порта берем из колонки PORTS в выводе списка запущенных контейнеров.

Перейдем по адресу http://<ip_адрес>:<порт>. Нас должна встретить стандартная страница NGINX:

Image2

Шаг 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

Если вы обновите ранее открытую вкладку, содержимое обновится:

Image7

Заключение

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

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону