Docker volumes are the preferred way of handling persistent data created by and used by Docker containers. Let’s take a look at how this works by covering how to create Docker volumes on Windows. You’ll also learn how to manage them too!
Not a reader? Watch this related video tutorial!
Not seeing the video? Make sure your ad blocker is disabled.
This blog post has a companion video created by TechSnips contributor, Matt McElreath. Feel free to have a watch or, if you prefer text, read on!
Storing Persistent Data
If you want to store persistent data for containers, there are a couple of options. First, I’ll show you how to use a bind mount. I’m currently in a folder called data on my C:\. If I list the contents of this folder, you can see that I have five text files.
If I want to make this folder available to a container, I can mount it when starting the container.
Let’s go ahead and run a container using docker run
. I’m going to run this container in interactive mode, then specify -V
. Here, I’m going to put the path to my data folder, followed by a colon, then I will specify the path inside the container where I would like this folder to be mounted.
For this, I’m going to specify the C:\shareddata folder. Then I’ll specify the Windows server core image and finally, I’ll specify that I want to run PowerShell once I’m inside the container.
docker run -it -v c:\Data:c:\shareddata microsoft/windowsservercore powershell
Now that I’m inside the new container, if I list the contents of C:\, you can see that I have a shareddata folder.
Let’s go into that folder and list the contents. Here are my five test files that are located on my container host.
I can also create files in this folder, which will be available to other containers or my container host. Let’s go ahead and run a new item to create a file called containertest.
We can see above that the new file has been created from within the container. Now I’ll exit this container which will shut it down by running exit
.
If I run docker ps
, you can see that there are currently no running containers.
Enumerating Data in Docker Volumes
Now let’s list the contents of the data folder again from my container host.
We can see the new file that was created from inside the container called containertest. Bind mounts have some limited functionality, however, so volumes are the preferred way to accomplish what we are trying to do. To get started with volumes, we can run the same command to start up a container, but this time with a couple of small differences. Where we specified the volume, instead of using the path on the container hosts’ file system, I’m going to use the word hostdata as the name of a volume I want to create and use.
From inside the new container, if I list the contents of C:\, you can see again that I have a folder called shareddata.
If I list the contents of that folder, it is currently empty because we created a blank volume. Now let’s run Ctrl-P-Q which will take us out of the running container, but keep it running in the background.
From the container host, run docker volume ls
. This will list the current volumes on this container host. I have a volume called hostdata, which was created when I specified it in the docker run
command.
If I run docker ps
we can see our running container.
Stop that container using docker stop
. Now we have no running containers.
Remove the stopped containers by running docker rm
. If I list the volumes again, you can see that the hostdata volume is still available and can be mounted to new containers.
Creating Docker Volumes
Another way to create a volume is to use the docker volume create
command. If you don’t specify a name, docker will give it a name which is a long list of random characters. Otherwise, you can specify a name here. I’m going to call this volume logdata. Now we can see it is in the list when we list the volumes again.
You’ll now mount that to a new container. Use docker run
again and for the volume specify the volume that just created and mount it to c:\logdata.
> docker run -it -v logdata:c:\logdata microsoft/windowsservercore powershell
From inside the container, go into the logdata folder and create a couple of files. Right now, there are no files in this directory, so go ahead and create some.
PS> New-Item -Name Log1.txt -ItemType File
PS> New-Item -Name Log2.txt -ItemType File
Now I have two log files in this directory.
Run Ctrl-P-Q again to exit this container while it is still running. While that container’s running, start up a new container with the same volume mounted.
> docker run -it -v logdata:c:\logdata microsoft/windowsservercore powershell
If we run a listing on the logdata folder in the new container we can see the two log files being shared.
Now, exit this container. You should still have one running container and two exited containers.
Now stop all running containers, then run docker rm
to remove all exited containers.
List the volumes again. The logdata volume is still available to be mounted to future containers.
If you run run docker volume
, you’ll get some usage help for the command.
Inspecting Docker Volumes
We already looked at create
, so let’s move on to inspect
. If I run docker volume inspect
against the logdata volume, it will return the properties for that volume, including the mount point which is the physical path to the volume on the container host.
Let’s open that folder using Invoke-Item
and have a look. Under the logdata folder, there’s a folder called data. If we open that, we can see the files that were created from the container earlier.
Deleting Docker Volumes
To delete a volume, we can run docker volume rm
, followed by the name of the volume you want to delete.
> docker volume rm logdata
Now if I list the volumes, logdata is no longer there.
Finally, we can use prune
to remove all unused local volumes. This will delete all volumes that are not mounted to a running or stopped container.
You want to be careful with this command, so there’s a warning and a prompt to make sure that you are sure that you want to do this. If I type Y
and hit enter, it will show me which volumes were deleted.
And if I list my volumes again you can see that they have all been deleted.
Summary
In this blog post, you should have gotten a good overview of managing Docker volumes in Windows. Docker is a great container platform. With its support for Windows and your newfound skills at managing Docker volumes, you will be unstoppable!
Запуская контейнер Docker нам может понадобится сохранить где-то данные или наоборот добавить их в контейнер. Для реализации этой задачи, в Docker, был создан объект томов и возможность проброса папок. Рассмотрим как это работает на примерах.
Когда использовать Docker Volume
Понимание надобности проброса папок и создания томов появляется при первом ознакомлении работы контейнеров в целом.
Если у вас есть файл «code.py», который подразумевает работу какого-то приложения, вы можете положить его в образ (image), но это создаст некоторые проблемы. Например вам нужно будет выполнять пересоздание образа (build) каждый раз, как «code.py» изменится. Сборка образа может происходить десятки минут. Образ Docker становится read-only после его создания т.е. не рассчитан на изменения.
Если вы не положили «code.py» в образ, а решили скопировать его внутрь контейнера — это так же создаст проблему. Контейнер является дополнительным слоем/snapshot над выбранным образом и имеет возможность записи. Время жизни контейнера равно времени жизни сервису, который запущен внутри него. Т.е. если у вас будет ошибка в приложении, то вам нужно будет пересоздавать контейнер и копировать файл еще раз. Все еще больше усугубиться, если вы запускаете 10 контейнеров, а вес файлов исчисляется в Гб.
Похожая проблема есть, если вы хотите получить данные из контейнера (например логи). Вы можете написать скрипт, который будет копировать большой объем файлов с 1 или 100 контейнеров, но этой будет занимать много времени.
Проброс папок и томов в Docker решает эти проблемы позволяя монтировать директории хоста внутри контейнера либо создавая централизованное хранилище. Таким образом мы получаем следующие преимущества:
- Мы не копируем данные, они хранятся в одно месте для всех контейнеров;
- Т.к. копирование отнимало время, а сейчас это делать не нужно, контейнеры запускаются быстрее;
- У нас появляется больше возможностей для управления данными.
Типы томов Docker
Есть два основных способа обмена данными с контейнером, которые часто называют томами:
- перенаправление какой-то папки или файла с хоста в контейнер (так же называется bind mount);
- создание специального объекта — volume (так же называется named volume), который имеет больше возможностей управления данными через Docker.
Основное различие этих двух типов в том, что для «volume» есть отдельные команды по его созданию, просмотру и удалению в самом Docker. Он так же представляет собой папку в файловой системе хоста, которая, по умолчанию, определена настройками Docker.
Еще одно, незначительно, отличие это поведение по умолчанию bind mount и volume. Для примера, внутри контейнера, по пути «/usr/share/nginx/html/» лежит файл «index.html». В случае проброса томов в эту папку поведение будет разным:
- В случае монтирования папки — «index.html», внутри контейнера, будет удален. Это произойдет даже если папка хоста пустая;
- В случае volume — при первом использовании тома файл «index.html» будет скопирован. При последующих — удален.
Есть еще один тип томов — tmpfs, который работает только под Linux. Он подразумевает хранение данных в ОЗУ и с ограничением в 1 контейнер.
Монтирование через docker run
Для монтирования данных используются следующие параметры:
- -v или —volume
- —mount
Их различие в том, что mount более явно заставляет указывать источник и цель монтирования папки. Вы можете использовать эти параметры совместно, отдельно, повторяя несколько раз — ограничений нет
Папки и файлы
Для примера — у меня есть следующая папка на хосте:
/home/alex/docker_data
В случае параметра «-v» указывается два пути «откуда:куда». В случае «—mount» это именованные параметры разделенные запятыми. Пример работы обоих:
-v /home/alex/docker_data:/usr/share/nginx/html
# или
--mount type=bind,source=/home/alex/docker_data,destination=/usr/share/nginx/html
В mount мы используем следующие параметры:
- type — со значением ‘bind’ говорит, что мы монтируем папку или файл;
- source — источник т.е. папка или файл, который мы хотим подключить к контейнеру;
- destination — папка или файл внутри контейнера.
В обоих случаях мы можем монтировать данный доступные только для чтения (read-only) добавив «ro» в конце:
-v /home/alex/docker_data:/usr/share/nginx/html:ro
--mount type=bind,source=/home/alex/docker_data,destination=/usr/share/nginx/html,ro
Так выглядит запуск контейнера с проброшенной папкой:
docker run -d --name nginx_vol1 -v /home/alex/docker_data:/usr/share/nginx/html:ro nginx
# или
docker run -d --name nginx_vol2 --mount type=bind,source=/home/alex/docker_data,destination=/usr/share/nginx/html,ro nginx
Вы можете проверить работу смонтированной папки создав файл на хосте с последующим выводом внутри контейнера:
# тестовый файл
touch /home/alex/docker_data/testfile
# проверяем, что он виден внутри контейнеров
docker exec nginx_vol1 ls /usr/share/nginx/html
docker exec nginx_vol2 ls /usr/share/nginx/html
Подключение volume
При монтировании тома нужно учитывать следующие моменты:
- название тома указывается без слешей;
- если тома с этим названием нет, то он будет создан;
- в случае с mount, в параметре type, указывается volume.
При использовании docker run использование томов будет выглядеть так:
docker run -d --name nginx_vol1 -v docker_volume:/usr/share/nginx/html nginx
# или
docker run -d --name nginx_vol2 --mount type=volume,source=docker_volume,destination=/usr/share/nginx/html nginx
Так же как и с папками мы можем добавить «:ro» или «,ro» в конец значения, что бы дать права только на чтение директорий.
В предыдущем примере один том был подключен к двум контейнерам. Их совместную работу можно проверить создав файл в одном контейнере, а вывести через другой:
# создаем файл в одном контейнере
docker exec nginx_vol1 touch /usr/share/nginx/html/file1
# проверяем файл через другой контейнер
docker exec nginx_vol2 ls /usr/share/nginx/html
При остановке контейнера и его удалении — том (вместе с данными) остается. Это часто создает проблему т.к. наличие томов смотрится через отдельную команду и про это можно забыть, а данные в томах занимают место.
Вложенные тома и папки
Вы можете объявлять тома внутри смонтированных папок и наоборот. Это может создавать путаницу, но это требуется в определенных ситуациях. Например некоторые фреймворки используют следующую структуру хранение модулей и приложений:
- «/usr/src/app» — папка с приложением, которое разрабатывает один или несколько разработчиков;
- «/usr/src/app/node_modules» — содержит модули, которые компилируются под определенную систему.
Сложность с «node_modules» в следующем:
- так как некоторые модули компилируются — они могут быть связаны с конкретной ОС и компилятором. Ошибки, в случае запуска на другой ОС, могут быть непредсказуемы;
- папка создается долго, имеет большой объем и множество файлов;
- папка может быть использована несколькими контейнерами.
Мы можем положить «node_modules» в том, что улучшит организацию. В то же время, папка «app», обновляется через GIT, который редко используется в контейнерах.
Один из оптимальных способов решения этих проблем является проброс «app» как папки, а «node_modules» как тома. Для начала мы создаем том и устанавливаем в него модули примерно так:
docker run -v $(pwd)/app/package.json:/usr/src/app/package.json \
-v node_modules:/usr/src/app/node_modules \
node \
npm install
После того как том создан — мы можем использовать его с нашим приложением:
docker run -v $(pwd)/app:/usr/src/app \
-v node_modules:/usr/src/app/node_modules \
node
Просмотр привязанных томов
Что бы посмотреть тома уже в запущенном или остановленном контейнере — можно использовать команду ‘docker inspect’. В следующем примере будут выведена только часть относящаяся к томам:
docker inspect nginx_vol2 --format "'{{json .Mounts}}'"
Привязка томов из другого контейнера
С помощью параметра «—volumes-from» мы можем скопировать тома у запущенного или остановившегося тома. В значении мы указываем контейнер:
# контейнер 1
docker run -v $(pwd)/app:/usr/src/app \
-v node_modules:/usr/src/app/node_modules \
--name node1 \
node
# контейнер 2
docker run --volumes-from node1 --name node2 node
Создание volume
Т.к. volume — это отдельны объект у docker есть команды, с помощью которых можно им управлять:
- docker volume ls — выведет список томов;
- docker volume inspect — покажет подробную информацию о томе в т.ч. его расположение на хосте;
- docker volume create — создание нового тома;
- docker volume prune — удалит все тома, которые не используются контейнерами;
- docker volume rm — удалит один том.
Для примера создадим том, выведем все существующие и посмотрим детальную информацию о нем:
docker volume create some_nginx
docker volume ls
docker volume inspect some_nginx
Можно легко не заметить как тома начнут занимать много места на диске. Что бы удалить тома, которые не смонтированы — можно использовать следующую команду:
docker volume prune
Параметр ‘-f’ сделает то же самое, но без подтверждения.
Драйвера и options
В скриншоте выше можно было увидеть значения «Driver: local». Это значение говорит, что вы будете использовать функционал практически идентичным команде «mount» в Linux. Такой «mount» позволяет использовать nfs и cifs директории, а так же многие другие указывая их в опциях (параметры «-o» или «-opt»).
Пример с nfs:
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.2.60,rw \
--opt device=:/home/alex \
nfs-volume
Драйвера так же могут быть разными. В основном они говорят о местоположении тома. Например облачные провайдер и различные приложения могут предоставлять свои драйвера, обеспечивающие шифрование и удаленный доступ. О некоторых плагинах можно почитать на официальном сайте Docker.
Опции и драйвера напрямую используются редко. Мною лично только через другие приложения. Кроме этого они отличаются от ОС, которые вы используете. В Windows, например, опции не доступны по умолчанию.
Размещение томов в другой директории
Есть два способа с помощью которых вы можете изменить местоположение тома.
В первом случае вы должны указывать местоположение тома при его создании. В примере ниже он будет храниться по пути «/home/alex/somevol»:
docker volume create --driver local \
--opt type=none \
--opt device=/home/alex/somevol \
--opt o=bind \
home-vol2
Пример смонтированного тома:
Второй способ затрагивает не только «volume», но и все данные которые использует docker (образы, сеть, контейнеры и т.д.). Перед тем как начать — нужно остановить сервис docker:
sudo systemctl stop docker
После этого мы должны отредактировать или создать файл «daemon.json»:
vi /etc/docker/daemon.json
Если у вас этого файла нет или он пустой, то содержимое должно быть следующим:
{
"data-root": "путь до директории"
}
Если какие-то данные в этом файле были, то вам нужно добавить запятую и убрать скобки.
Данные с предыдущей директории так же нужно скопировать в новую директорию (в примере ниже это «/docker_data»):
sudo rsync -aP /var/lib/docker/ /docker_data
Папку по старому пути стоит переименовать что бы убедиться, что она более не используется. После успешной работы Docker ее можно будет удалить.
Можно запустить сервис и проверить, что все работает:
sudo systemctl start docker.service
docker volume create vol1
docker inspect vol1
Подключение тома и папки через Dockerfile
При создании образа через Dockerfile у вас так же есть возможность создать том, но не использовать существующий. Смонтировать папку, через Dockerfile, так же нельзя.
Создание тома будет иметь ряд ограничений:
- Вы не сможете указать имя тома или выбрать существующий. Имя будет сгенерировано автоматически;
- В любом случае том будет создан во время запуска контейнера т.е. так же как и в случае использования ‘-v’;
- Каждое создание контейнера будет создавать новый том.
Для создания тома есть инструкция VOLUME. Пример синтаксиса:
FROM nginx
# указываем точку монтирования внутри контейнера
VOLUME /somedata1
Примерный результат где запускаются 2 контейнера с одного образа:
Аналогичный результат можно получить используя одну из следующих команд:
docker run -v /somedata1 nginx
# или
docker run -v $(docker volume create):/somedata1 nginx
Если вы используете инструкцию «VOLUME» и параметр «-v» указывающий на одну и ту же директорию, то «-v» возьмет верх.
Volume в docker-compose
Docker-compose позволяет запускать несколько контейнеров используя один файл инструкций. Синтаксис монтирования томов может быть ограниченным и расширенным так же как «-v» и «—mount».
Для монтирования тома, кроме инструкции в самом контейнере, нужно указать дополнительную инструкцию ‘volumes’ в верхнем уровне. Для папки этого делать не нужно:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
# том
- somevol:/app
# папка
- /home/alex:/app2
# для тома
volumes:
somevol:
Том ‘somevol’ может использоваться совместно в нескольких контейнерах.
Если нам нужно дать права на том или папку, то мы просто добавляем ‘ro’ или ‘rw’ в коней пути:
...
volumes:
# том
- somevol:/app:ro
# папка
- /home/alex:/app2:rw
...
Для монтирования так же есть расширенный синтаксис, похожий на команду mount в docker. Следующий пример аналогичен предыдущем по эффекту:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
# том
- type: volume
source: somevol
target: /app1
# папка
- type: bind
source: /home/alex
target: /app2
volumes:
somevol:
Есть еще инструкции, которые вы можете использовать. Ниже только их часть, но они используются редко:
volumes:
- type: volume
source: somevol
target: /app1
# папка только для чтения
read_only: true
# не будет копировать файлы в том, которые уже находятся в контейнере
volume:
nocopy: true
# папка
- type: bind
source: /home/alex
target: /app2
# папка только для чтения
read_only: true
# создаст папку на хосте если ее нет
create_host_path: true
Как уже говорилось выше — мы можем использовать один и тот же том в нескольких контейнерах (сервисах). Кроме этого есть инструкция «volumes_from», которая использует тома с указанного контейнера. Ниже оба примера:
version: "3.8"
services:
container1:
image: nginx:alpine
volumes:
- somevol:/app1
- /home/alex:/app2
container2:
image: nginx:alpine
volumes:
# тот же том, но в другом контейнере
- somevol:/app2
container3:
image: nginx:alpine
# берем тома из сервиса container1
# с доступностью только на чтение
volumes_from:
- container1:ro
volumes:
somevol:
Ниже результат работы таких инструкций. Как видно у контейнера 1 и контейнера 3 одни и те же тома:
Если вам нужно удалить тома, которые были использованы или созданы при выполнении «docker compose up», можно добавить параметр «—volumes»:
docker compose down --volumes
По умолчанию, в compose, тома используют приставку с названием проекта в названии. Если название тома «some_vol«, а путь, в котором лежит файл docker-compose.yml следующий «/home/alex/project_name/», то том будет иметь название «project_name_some_vol».
Использование внешних томов
Если вам нужно использовать том, который был создан не в текущем файле docker-compose.yml, то вы можете его указать через параметр «external». Автоматический такой том не создается:
...
volumes:
somevol:
external: true
Создание тома в другой директории
Через compose мы так же можем указывать драйвера и опции. Так, например, мы создадим тома в другой директории по аналогии с тем, что делали выше:
...
volumes:
my_test_volume:
driver: local
driver_opts:
o: bind
type: none
device: /home/alex/compose_vol1
Tmpfs
Еще одним способом монтирования томов является tmpfs. Данные этого тома хранятся в оперативной памяти. При остановке контейнера, в отличие от других томов, данные будут удалены. Эти данные просто не выгружаются из оперативной памяти. Такой тип тома вы можете создать только на одном контейнере и только в Linux.
Такие типы хранилищ редко используются. Их можно использовать для хранения чувствительных данных (для безопасности) или что бы ускорить работу какого-то приложения, но оба варианта, обычно, реализовываются на стороне приложения.
Есть два способа создания tmpfs:
docker run \
--tmpfs /app \
nginx:latest
# или
docker run -d \
--mount type=tmpfs,destination=/app,tmpfs-size=400,tmpfs-mode=1777 \
nginx:latest
При использовании параметра «—tmpfs» вы можете указать только директорию, которую планируете использовать.
При использовании «mount» у вас появляются не обязательные параметры:
- tmpfs-size — размер в байтах. По умолчанию не ограничен;
- tmpfs-mode — права на файлы. По умолчанию 1777. Можно не указывать специальные разрешения (т.е. 700, например).
Через Docker Compose мы так же можем создать и использовать tmpfs:
volumes:
foo:
driver: local
driver_opts:
type: "tmpfs"
o: "o=size=100m,uid=1000"
device: "tmpfs"
…
Теги:
#docker
#volume
We’re Earthly. We make building software simpler and therefore faster. This article is about container volume management. If you’re interested in a simple and containerized approach to building software then check us out.
Docker is a common containerization solution that offers a user-friendly interface. It allows you to deploy your application as a lightweight process set rather than a complete virtual machine.
Docker images are like a snapshot of a container’s file system and contain both your application and its dependencies. When you run it, you recreate the container’s state. You don’t have to be concerned about setting up your environment because running an image recreates everything for you and is isolated from your operating system and other running containers.
The Docker interface is simple and users can easily create and implement applications into their containers or carry out version management, copy, share, and modify, just like managing ordinary code.
However, containers often need to use data beyond their container or share data between containers. While it may be tempting to rely on the host file system, a better solution is to work with persistent data in a container, namely Docker volumes.
A Docker volume is an independent file system entirely managed by Docker and exists as a normal file or directory on the host, where data is persisted.
In this guide, you’ll learn how volumes work with Docker, what they do, and what the best practices are for keeping them secure and effective.
What Are Docker Volumes
The purpose of using Docker volumes is to persist data outside the container so it can be backed up or shared.
Docker volumes are dependent on Docker’s file system and are the preferred method of persisting data for Docker containers and services. When a container is started, Docker loads the read-only image layer, adds a read-write layer on top of the image stack, and mounts volumes onto the container filesystem.
Why Docker Volumes?
If you are using Docker for development, you must be familiar with the -v
or --volume
flag that lets you mount your local files into the container. For instance, you can mount your local ./target
onto the /usr/share/nginx/html
directory container or an nginx container to visualize your html files.
echo "<h1>Hello from Host</h1>" > ./target/index.html
docker run -it --rm --name nginx -p 8080:80 -v "$(pwd)"/target:/usr/share/nginx/html nginx
Navigate to http://localhost:8080/
and you should see “Hello from Host”.
This is called a bind mount and is commonly used by developers. But, if you are using Docker Desktop on Windows or MacOS bind, mounts have significant performance issues. As a result, using volumes may be the best alternative for holding state between container runs.
Unlike bind mount, where you can mount any directory from your host, volumes are stored in a single location (most likely /var/lib/docker/volumes/ on unix systems) and greatly facilitates managing data (backup, restore, and migration). Docker volumes can safely be shared between several running containers.
You can also save data to a remote server or in cloud Docker volumes with alternative volume drivers like sshfs
.
In addition, Docker enables you to manage volume with the command line docker volume
, making their management simple.
Creating and Managing Docker Volumes
In this section, you’ll learn how to create a Docker volume implicitly and explicitly and then declare it from a Docker file. Then you’ll learn how to view a data volume, mount it to a container, and configure it using docker-compose
.
Create a Docker Volume Implicitly
The easiest way to create and use a volume is with docker run
and the -v
or --volume
flag. This flag takes three arguments separated by :
:
-v <source>:<destination>:<options>
If the “source” is a path that was used in the previous example, Docker will use a mount bind. If the “source” is a name, then Docker tries to find this volume or creates one if one cannot be found. Below, the previous example has been updated to use a volume instead of a mount bind:
docker run -it --rm --name nginx -p 8080:80 -v demo-earthly:/usr/share/nginx/html nginx
You can check to make sure the container was properly created with docker volume ls
which lists all existing volumes.
docker volume ls
Note that the volume in question is not empty. If a volume is completely empty, the container’s content is copied to the volume.
You can check the status of your volumes on Linux. This gives you a chance to see where volumes are stored:
ls /var/lib/docker/volumes/target/_data/demo-earthly
On Mac and Windows it’s a bit more tricky. In order to keep things simple, you can mount the volume on an ubuntu container and use ls
to see the content of your volume:
docker run -it --rm -v demo-earthly:/opt/demo-earthly ubuntu ls /opt/demo-earthly
Create a Docker Volume Explicitly
Alternatively you can use the docker volume create
command to explicitly create a data volume. This command gives you the option to choose and configure the volume driver. The implicit creation of volumes always uses the local
driver with default settings.
docker volume create --name demo-earthly
Declare a Docker Volume from Dockerfile
Volumes can be declared in your Dockerfile using the VOLUME
statement. This statement declares that a specific path of the container must be mounted to a Docker volume. When you run the container, Docker will create an anonymous volume (volume with a unique id as the name) and mount it to the specified path.
FROM nginx:latest
RUN echo "<h1>Hello from Volume</h1>" > /usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html
Lets build and run your new image:
docker build -t demo-earthly .
docker run -p 8080:80 demo-earthly
You can now validate that nginx serves your message at http://localhost:8080/
.
More importantly, an anonymous Docker volume has been created, and every time you start a new container, another volume is created with the content of /usr/share/nginx/html
.
From the above example, a volume directory data
with the text file test
containing “Hello from Volume” is created.
View a Data Volume
To manage your data, sometimes you need to list data volumes from the command line as a point of reference, which is faster than repeatedly checking the configuration files. You can use the docker volume ls
command to view a list of data volumes.
docker volume ls
Use the docker volume inspect
command to view the data volume details.
docker volume inspect
Mount a Volume to a Container
As you have seen through the various examples -v
and --volume
are the most common way to mount a volume to a container using the syntax:
-v <name>:<destination>:<options>
One notable option is ro
which means that the volume will be mounted as read-only:
docker run -it -v demo-volume:/data:ro ubuntu
Try to write into the folder/data to validate that the volume is in read-only mode:
An alternative to -v
is to add the —mount
option to the docker run
command. --mount
is the more verbose counterpart of -v
.
To launch a container and mount a data volume to it, follow this syntax:
docker run --mount source=[volume_name],destination=[path_in_container] [docker_image]
Replace [path in container]
with the path to attach the Docker volume [volume_name]
in the container.
For example, run the following command to start an Ubuntu container and mount the data volume to it.
docker run -it --name=example --mount source=demo-volume,destination=/data ubuntu
Remember if the volume doesn’t exist Docker will create it for you.
List the contents of the container to see if the volume is mounted successfully. You should find the Docker volume name defined in the above data syntax.
Configure a Volume Using docker-compose
Although there are many ways to create a volume, it’s more convenient to use the docker-compose
command to easily share data between multiple containers.
The use of the volume
property in compose files is very similar to -v
and --volume
. That being said, to perform a bind mount (mount a directory from your local machine), you can use a relative path unlike -v
with the command docker run
that requires an absolute path.
version: "3.2"
services:
web:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./target:/usr/share/nginx/html
The containers and hosts in the above configuration use volumes
in the services
definition (web
) to mount ./target
from the host to /usr/share/nginx/html
of the container. As with the first example, if you navigate to http://localhost:8080/
you should read “Hello from Host”.
With docker-compose
, volumes must be declared at the same level as services
. Then you can refer to them by their name.
version: "3.2"
services:
web:
image: nginx:latest
ports:
- 8080:80
volumes:
- html_files:/usr/share/nginx/html
web1:
image: nginx:latest
ports:
- 8081:80
volumes:
- html_files:/usr/share/nginx/html
volumes:
html_files:
In this example, you declared a volume named html_files
and used it in both web
and web1
service. Multiple containers can mount the same volume.
Running docker-compose up
will create a volume named <project_name>_html_files
if it doesn’t already exist . Then run docker volume ls
to list the two volumes created, starting with the project name.
You can also manage container outside of you docker-compose file, but you still need to declare them under volumes
and set the property external: true
.
version: "3.2"
services:
web:
image: nginx:latest
ports:
- 8080:80
volumes:
- html_files:/usr/share/nginx/html
volumes:
html_files:
external: true
If you don’t have html_files
, you can use docker volume create html_files
to create it. When you add external
, Docker will find out if the volume exists; but if it doesn’t, an error will be reported.
Copy Files Between Containers from a Shared Volume
Let’s look at how Docker volumes enable file sharing across containers.
In this example, use the volume and container we previously defined and execute the following commands:
docker create volume demo-earthly
docker run -it --name=another-example --mount source=demo-volume,destination=/data ubuntu
Navigate to the data volume directory and create a file using the command touch demo.txt
. Exit the container, then launch a new container another-example-two
with the same data volume:
docker run -it --name=another-example-two --mount source=demo-volume,destination=/data ubuntu
The demo.txt
file you created in the preceding container should list another-example
in the output.
Docker Volume Best Practices
Now that you’ve learned how to implement Docker volumes, it’s important to keep in mind a few best practices:
- Always mount volumes as read-only if you only need to read from them.
- Always set the permissions and ownership on a volume.
- Always use environment variables for the host path or volume name in a production environment.
Conclusion
Often, you want your containers to use or persist data beyond the scope of the container’s lifetime. You can use volumes to solve this problem by working with Docker to mount, create, and share volumes between containers.
In this guide, you looked at how volumes work with Docker, what they do, and where volumes are the preferred solution.
Docker plays an important role in the DevOps ecosystem, so if you want to improve your continuous integration process, consider Earthly. Earthly is a build automation tool that allows you to build anything via containers, making your builds self-contained, repeatable, portable, and parallel.
Earthly makes builds simple
Fast, repeatable builds with an instantly familiar syntax – like Dockerfile and Makefile had a baby.
Learn More
Approach #1 — COPY
To copy the file from the host to the container
docker cp /path/of/the/file <Container_ID>:/path/of/he/container/folder
Issue with the above approch is, it will not persists the volume or file or dir, as you remove the container it will be lost. This is suggested only for temporary pupose.
Approach #2 — Volume Mounting
Mouting the volume from the host to container
Step1: Create the volume with the custom path
docker volume create --name my_test_volume --opt type=none --opt device=/home/jinna/Jinna_Balu/Test_volume --opt o=bind
Step2 : Mount to the container or swarm service
docker run -d \
--name devtest \
--mount source=my_test_volume,target=/app \
nginx:1.11.8-alpine
We can do both of the above steps with below .yaml files
version: '3'
services:
nginx:
image: nginx:1.11.8-alpine
ports:
- "8081:80"
volumes:
- my_test_volume:/usr/share/app
volumes:
my_test_volume:
driver: local
driver_opts:
o: bind
type: none
device: /home/jinna/Jinna_Balu/Test_volume
RUN the above yml with docker-compose
docker-compose up -d
NOTE: create the folder path before you do docker-compose.
Good practice to have files mouted to maintain the persistency.
Tags:
Windows, Docker, Linux
Это последняя статья в этой серии о контейнерах Windows и Docker. Прежде чем углубиться в тему, мы хотим просто описать различные версии Docker, которые существуют сегодня, если вы не работали в сфере Docker, или если вы только что начали использовать Docker. 2 марта 2017 года Docker изменил формат своей версии, а также изменил название пакета Docker Engine на Docker Community Edition или Docker Enterprise Edition.
Установка Docker Community Edition в Windows 10
Первое издание называется Docker Community Edition (CE). Docker (CE) — новое название для бесплатных продуктов Docker. Docker CE совместим со следующей платформой ОС: Mac OS, Windows 10, Amazon AWS, Azure, CentOS, Debian, Fedora и Ubuntu. Вдобавок к этому, Docker CE поставляется в двух вариантах: Edge и Stable:
- Edge предназначен для пользователей, которые хотят каждый месяц получать последние и самые лучшие функции
- Stable выпускается ежеквартально и предназначен для пользователей, которым требуется более легкая в обслуживании скорость выпуска
Как заявляют Docker, Community Edition отлично подходит для разработчиков и команд ops, которые начинают создавать приложения для контейнеров. Если вы хотите загрузить эту версию, перейдите в Docker Store. После завершения загрузки и установки вы можете запустить пакет под названием Docker For Windows. На момент написания этой статьи был установлен Docker CE v18.03.
PS > Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All PS > Get-Service *docker* Status Name DisplayName ——— —— —————— Running com.docker.service Docker for Windows Service |
Убедитесь, что вы можете запустить простой контейнер:
PS > Docker run —rm -v c:/Users:/data alpine ls /data Unable to find image ‘alpine:latest’ locally latest: Pulling from library/alpine ff3a5c916c92: Pull complete Digest: sha256:7b848083f93822dd21b0a2f14a110bd99f6efb4b838d499df6d04a49d0debf8b Status: Downloaded newer image for alpine:latest All Users Default Default User Nicolas Public defaultuser0 desktop.ini |
Если вы работаете с Docker v18.03, то одной из основных функций является возможность запуска изображений Windows и Linux бок о бок, вместо того, чтобы переключать Docker из Linux в режим Windows. Давайте подтвердим, что вы запускаете Daemon в экспериментальном режиме:
PS > docker version -f ‘{{.Server.Experimental}}’ True |
Или через графический интерфейс:
Теперь используйте параметр platform=linux в режиме Windows Container для запуска образов Linux.
Если вы работаете с предыдущей версией Docker, она будет запускать контейнеры Linux по умолчанию. Таким образом, вы должны изменить этот параметр и переключиться в режим Windows Container с помощью меню лотка Docker:
или выполнив следующую команду в приглашении PowerShell
& $Env:ProgramFiles\Docker\Docker\DockerCli.exe –SwitchDaemon |
И это все. Docker CE работает и работает на Windows 10!
Теперь вы можете пойти в Docker Hub, чтобы узнать, какие изображения контейнера доступны. Например, вы можете запустить простой контейнер Windows, содержащий PowerShell Core:
PS > docker pull microsoft/powershell Using default tag: latest latest: Pulling from microsoft/powershell 1be7f2b886e8: Pull complete 6fbc4a21b806: Pull complete […] 74ebbb198c87: Pull complete Digest: sha256:38ac64ecec7e36b1868458b6b49e9d41332de56da2053c14830ef4915d909813 Status: Downloaded newer image for microsoft/powershell:latest PS > docker run —name PSCore -it microsoft/powershell PowerShell v6.0.1 Copyright (c) Microsoft Corporation. All rights reserved. https://aka.ms/pscore6-docs Type ‘help’ to get help. PS > $PSVersionTable Name Value —— ——— PSVersion 6.0.1 PSEdition Core GitCommitId v6.0.1 OS Linux 4.9.75-linuxkit-aufs #1 SMP Tue Jan 9 10:58:17 UTC 2018 Platform Unix PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0 |
И вы можете легко настроить свой движок Docker с помощью GUI Docker For Windows:
Установка Docker Enterprise Edition на Windows Server 2016
Второе издание называется Docker Enterprise Edition (EE) и является сертифицированной контейнерной платформой для: CentOS, Red Hat Enterprise Linux (RHEL), Ubuntu, SUSE Linux Enterprise Server (SLES), Oracle Linux, Windows Server 2016, IBM Z, Amazon AWS и Azure (Docker EE для Azure). Docker EE доступен в трех уровнях: базовом, стандартном и расширенном. Стандартные и расширенные уровни добавляют расширенное управление контейнерами (Docker Datacenter) и сканирование безопасности Docker. Вы можете найти дополнительную информацию о Docker EE в Docker Store и о том, как установить его в других операционных системах. В этом случае вам просто нужно запустить следующие команды в качестве администратора для установки Docker EE на Windows Server 2016:
PS > Install-Module DockerProvider PS > Install-Package Docker -ProviderName DockerProvider -RequiredVersion preview -Force WARNING: A restart is required to enable the one or more features. Please restart your machine. Name Version Source Summary —— ———— ——— ———— Docker 17.10.0-ee-pr... Docker Docker Enterprise Edition for Windows Server... PS > Restart-Computer |
Как вы можете заметить, параметр -Force используется для установки самой последней версии Docker EE. И затем выполняется перезапуск хоста Windows-контейнера Windows. В этой статье будет показано использование Docker EE v17.10 на Windows Server 2016.
Ниже приведен цикл выпуска для Docker в 2017 году. Например, v17.03 означает, что этот выпуск был выпущен в марте 2017 года.
Цикл выпуска Docker с веб-сайта Docker
Подводя итог, Docker CE имеет те же основные функции, что и Docker Enterprise Edition, поэтому не бойтесь, вы можете использовать Docker CE вместо Docker EE. Тем не менее, если вы хотите запустить Docker на производстве, мы рекомендуем установить как минимум Docker EE Basic.
Где мои данные?
Представьте, что вы запускаете Windows Container и имеете некоторые важные данные внутри контейнера. Да, контейнеры эфемерны, но вы можете сохранить эти данные за пределами контейнера по многим причинам. Ну, вы можете легко обмениваться данными между Container Host и Windows Container. Кроме того, вы можете также обмениваться данными между двумя контейнерами Windows, если вам нужно. Эта функция очень полезна для многоконтейнерных приложений. Например, приложения должны предоставлять доступ к данным или сохранять данные после удаления контейнера, например, для баз данных или файлов журналов. Эта функция называется Docker Volumes.
В этом разделе я опишу, как работают Docker Volumes и объясняют четыре разных способа обмена данными с контейнерами:
- Создание независимого Docker Volume
- Совместное использование Docker Volume с несколькими контейнерами
- Копирование данных из Container Host в контейнер
- Создание Docker Volume из Dockerfile
При использовании контейнеров Windows по-прежнему рекомендуется использовать Docker Volumes для хранения данных на контейнерном хосте, а не на контейнере. Вы также можете создать несколько контейнеров, которые будут использовать один и тот же Docker Volume. Docker Volume будет отображаться как на хосте контейнера, так и на контейнере. Первое, что нужно знать, это то, что объемы докеров сохраняются в следующем скрытом пути на хосте контейнера:
Примечание. Учитывая, что мы переключаемся между хосте контейнера и контейнерами, мы добавим комментарий перед каждой командой.
Создание независимого Docker Volume
Чтобы создать Docker Volume, введите следующую команду:
#On the container host Docker volume create —name vol01 Vol01 |
Чтобы просмотреть все существующие Docker Volume на узле контейнера, введите:
#On the container host PS > Docker volume ls DRIVER VOLUME NAME local vol01 |
Теперь вы можете подключить существующий Docker Volume к новому контейнеру iis01, используя параметр -v. Синтаксис прост, вы должны указать папку на узле контейнера, а затем папку в контейнере:
#On the container host PS > Docker run —name iis01 -it -v C:\ProgramData\Docker\Volumes\Vol01:C:\Vol01 nanoserver/iis PowerShell |
Включив ключ -it и указав PowerShell, текущая консоль PowerShell будет использоваться для автоматического подключения к вашему контейнеру после его создания. Если вы хотите выйти из своего контейнера, введите Exit и ваш контейнер будет остановлен. Чтобы оставить контейнер в фоновом режиме, используйте CTRL + P + Q. Чтобы открыть новый сеанс PowerShell, запущенный в контейнере, используйте Docker attach <имя контейнера> и дважды нажмите ENTER. Когда в сеансе PowerShell для существующего контейнера, Exit просто вернется к хосту, но оставит контейнер включенным. Для запуска контейнера используйте Docker start <имя контейнера>.
Теперь создайте простой текстовый файл на хосте контейнера:
Убедитесь, что файл существует и в контейнере:
#On the iis01 container
PS C:\> Get-ChildItem .\vol01\_data
Directory: C:\vol01\_data
Mode LastWriteTime Length Name
—- ————- —— —-
-a—- 3/2/2018 8:49 PM 19 TestFile.txt
Чтобы проверить контейнер, выполните следующую команду и проверьте раздел Mounts:
#On the container host PS > Docker inspect iis01 |
Некоторым из вас, вероятно, интересно, можно ли переместить место хранения? К счастью, да! Чтобы выполнить эту задачу, вам необходимо создать файл конфигурации с именем daemon.json:
#On the container host PS > New-Item -Type File -Path «C:\ProgramData\Docker\config» -Name daemon.json Directory: C:\ProgramData\Docker\config Mode LastWriteTime Length Name —- ————- —— —- -a—- 3/2/2018 9:00 PM 0 daemon.json |
Затем укажите новое место хранения, добавив его в файл daemon.json:
{ «data-root»: «D:\\DockerVolumes» } |
Затем перезапустите службу Docker. Создайте новый том, чтобы подтвердить, что том создается в новой папке Root Data:
#On the container host PS > Get-Service *Docker* | Restart-Service PS > Docker volume create —name newvolume |
Папка для новой папки Data Root будет создана автоматически. Будьте осторожны, старые тома не перемещаются автоматически, и существующие контейнеры и тома больше не будут видны Docker. Обратите внимание, что вы можете удалить существующий Docker Volume с помощью Docker volume rm <имя тома>.
Совместное использование Docker Volume с несколькими контейнерами
Начните с создания нового контейнера под названием iis02 на основе изображения nanoserver/iis и прикрепите к нему том. Обратите внимание, что вам не нужно указывать папку Data Root, потому что Docker создаст каталог со случайным именем папки. Затем создайте файл на новом томе.
#On the container host PS > Docker run -it —name iis02 —volume c:/vol03 nanoserver/iis powershell #On the «iis02» Container PS > «Welcome vol03» > .\vol03\vol03.txt PS > dir .\vol03 Directory: C:\vol03 Mode LastWriteTime Length Name —— ——————— ——— —— -a—— 3/3/2018 2:24 PM 32 vol03.txt |
Убедитесь, что файл существует на хосте контейнера:
Во время последнего шага вы создали новый контейнер и добавили новый Docker Volume. Теперь вы создадите второй контейнер iis03 и присоедините тот же самый Docker Volume C:/vol03, используя параметр -volumes-from:
#On the container host
PS > docker run -it —name iis03 —volumes-from iis02 nanoserver/iis powershell
Убедитесь, чтотом установлен. Создайте новый текстовый файл с именем vol03-from-iis03.txt:
#On the iis03 container PS C:\> dir .\vol03 Directory: C:\vol03 Mode LastWriteTime Length Name —- ————- —— —- -a—- 3/3/2018 2:24 PM 32 vol03.txt #The text file created on iis02 is visible on iis03 thanks to the «—volumes-from» parameter #On the «iis03» Container PS C:\> «Hello» > .\vol03\vol03-from-iis03.txt |
На узле контейнера отображаются оба файла:
По умолчанию доступ к Docker Volume осуществляется в режиме чтения / записи. В некоторых случаях вам необходимо ограничить доступ к Docker Volume. Вы можете установить том как только для чтения. Создайте контейнер под названием db01 и добавьте том с доступом только для чтения (RO):
#On the container host
PS > Docker run -it —name db01 —volumes-from iis02:ro nanoserver/iis powershell
Теперь попробуйте создать файл на этом томе, но задача не будет выполнена:
#On the db01 container PS C:\> dir .\vol03 Directory: C:\vol03 Mode LastWriteTime Length Name —- ————- —— —- -a—- 3/3/2018 2:36 PM 16 vol03-from-iis03.txt -a—- 3/3/2018 2:24 PM 32 vol03.txt PS C:\> «Welcome» > .\vol03\vol03-from-db01.txt out-file : Access to the path ‘C:\vol03\vol03-from-db01.txt’ is denied. At line:1 char:1 + «Welcome» > .\vol03\vol03-from-db01.txt + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OpenError: (:) [Out-File], UnauthorizedAccessException + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand |
Копирование данных из хоста контейнера в контейнер
Вот еще один интересный способ обмена данными между хостом контейнера и контейнером Windows. Утилита docker cp копирует из файловой системы контейнера в хост контейнера или обратно, от хоста контейнера до контейнера. Создайте новый файл MyPackage.zip в папке C:\Packages. Затем скопируйте файл Zip из контейнера в контейнер iis02:
#On the container host PS > Docker cp C:\Packages\MyPackage.zip iis02:/inetpub PS > Docker attach iis02 |
Команда Docker Attach будет подключаться к контейнеру iis02. Будьте осторожны, вы должны дважды нажать ENTER, чтобы подключиться к вашему контейнеру. Проверьте, существует ли пакет в контейнере:
Создание Docker Volume из DockerFile
Вы можете установить Docker Volume с помощью DockerFile. В следующем примере вы создадите изображение nanoserver/iis с помощью ключевого слова VOLUME для установки папки. Обязательно создайте каталог C:\Volume на хосте, если он не существует.
#On the container host PS > New-Item C:\Volume\Dockerfile -ItemType file PS > Add-Content -Path «C:\Volume\Dockerfile» -Value «FROM nanoserver/iis» PS > Add-Content -Path «C:\Volume\Dockerfile» -Value «VOLUME C:/Vol03» PS > Add-Content -Path «C:\Volume\Dockerfile» -Value «RUN powershell -Command gci» |
Перейдите в каталог, в котором находится этот файл Dockerfile, и выполните следующую команду:
#On the container host PS C:\Volume> docker build -t volumeimg . Sending build context to Docker daemon 2.048kB Step 1/3 : FROM nanoserver/iis —-> 234e90a5d146 Step 2/3 : VOLUME C:/Vol03 —-> Using cache —-> 9acd2015fab2 Step 3/3 : RUN powershell -Command gci —-> Running in 98c4a64d54e2 Directory: C:\ Mode LastWriteTime Length Name —— ——————— ——— —— d——— 3/3/2018 4:37 PM inetpub d——— 3/3/2018 4:37 PM Program Files d——— 7/16/2016 12:09 PM Program Files (x86) d-r—— 3/3/2018 4:37 PM Users d——l 3/3/2018 4:37 PM vol03 d——— 3/3/2018 4:37 PM Windows -a—— 11/20/2016 11:32 AM 1894 License.txt […] Successfully tagged vol3:latest |
Создано пользовательское изображение Docker:
Итак, теперь каждый контейнер, созданный с использованием этого изображения, автоматически монтирует том:
#On the container host PS > docker run —rm -it —name srv01 volumeimg powershell #On the «srv01» Container PS > cd vol03 PS C:\vol03> «Mount from Container» > mount.txt |
На хосте контейнера был успешно создан новый файл с именем mount.txt. Вы можете подтвердить путь установки с проверкой Docker:
Этот метод очень полезен в режиме DevOps или когда вы хотите развернуть несколько контейнеров Windows в массовом режиме. Volume будет смонтирован автоматически во время развертывания.
Контейнеры Linux в Windows?
Еще одно большое улучшение — контейнеры Linux. Теперь вы можете запускать контейнеры Linux на хосте контейнера Windows. Однако его можно запустить только в среде dev/test, поскольку он все еще находится в экспериментальной версии. Итак, что это значит? Ну, вы сможете развернуть свой Windows Containers Host, затем установить движок Docker и, наконец, запустить контейнер Linux или контейнер Windows. Благодаря LinuxKit и Moby Project вы можете использовать контейнеры Linux в Windows, используя одну из следующих сборок Windows для поддержки этой функции:
- Windows 10 Fall Creators Update
- Windows Server 2016 1709 (новое основное издание)
Чтобы запустить Linux-контейнеры в Windows, Microsoft использует функцию Linux Containers on Windows (LCOW). LCOW будет использовать изоляцию Hyper-V, поэтому перед использованием Linux-контейнеров необходимо установить Hyper-V:
#On the container host PS > Install-WindowsFeature Hyper-V -IncludeManagementTools -Restart |
Затем Docker daemon работает как процесс Windows, и каждый раз, когда вы запускаете контейнер Linux, Docker запускает минимальную виртуальную машину с ядром Linux. Однако «виртуальная машина» не отображается пользователем в консоли Hyper-V! По-прежнему невозможно совместно использовать контейнеры для Windows и Linux Docker. Это означает, что вы должны включить LCOW для запуска контейнеров Linux и отключить LCOW для запуска контейнеров Windows. Если вы работаете в Windows 10, обратите внимание, что поддержка LCOW доступна только на канале Edge.
Начните с включения функции LCOW со следующими командами.
#On the container host PS > [Environment]::SetEnvironmentVariable(«LCOW_SUPPORTED», «1», «Machine») PS > Restart-Service Docker |
- Эта функция включена, поэтому вы можете создать контейнер Linux на основе Ubuntu, используя следующую команду:
#On the contaner host PS > Docker run –it ubuntu |
На этом этапе вы работаете в контейнере Ubuntu на своем Windows Server:
root@58e001fba499:/# pwd / root@58e001fba499:/# mkdir /tmp/Linux root@58e001fba499:/# ls /tmp linux |
Чтобы закончить с забавным контейнером Linux, вы можете запустить контейнер NyanCat:
#On the container host PS > Docker run -it supertest2014/nyan |
Заключение
В этой статье серии обсуждались новые версии Docker, которые вы можете использовать в зависимости от ваших потребностей. Первый — Docker CE, который предназначен для среды разработки и тестирования, а второй — Docker EE, который предназначен для использования в производстве. Затем вы увидели:
- Как обмениваться данными между хостом контейнера и контейнером.
- Как делиться данными между двумя контейнерами.
И в конце вы запускали контейнеры Linux на хосте Windows-контейнера, что является отличным улучшением для sysadmin и разработчиков. В настоящее время LCOW все еще находится в стадии бета-тестирования и не поддерживается. В производственной среде, пожалуйста, используйте его для целей dev.