Обзор хранилища контейнера
В этом разделе приводятся общие сведения о различных способах использования контейнерами хранилища в Windows. В случае хранилища контейнеры ведут себя иначе, чем виртуальные машины. По сути, контейнеры создаются так, чтобы выполняющееся в них приложение не могло записывать свое состояние в файловую систему узла. По умолчанию контейнеры используют «вспомогательное» пространство, но Windows также предоставляет средства для хранения в постоянном хранилище.
Область временных файлов
Контейнеры Windows по умолчанию используют временное хранилище. Все операции ввода-вывода контейнера выполняются во «вспомогательном пространстве», и у каждого контейнера такое пространство свое. Данные о создании и записи файлов записываются во вспомогательное пространство и не отправляются на узел. При остановке экземпляра контейнера все изменения, произошедшие во вспомогательном пространстве, сбрасываются. При запуске нового экземпляра контейнера ему предоставляется новое вспомогательное пространство.
Хранилище уровня
Как описано в статье Общие сведения о контейнерах, образы контейнеров представляют собой набор файлов, представленный в виде совокупности слоев. Хранилище слоя содержит все файлы, которые встроены в контейнер. При каждом выполнении операции docker pull и docker run с контейнером результаты совпадают.
Где хранятся уровни и как их изменить
При установке по умолчанию уровни хранятся в C:\ProgramData\docker и распределяются между каталогами «image» и «windowsfilter». Вы можете изменить место хранения уровней, используя конфигурацию docker-root , как показано в документации по подсистеме Docker в Windows.
Для хранилища уровня поддерживается только файловая система NTFS. ReFS и общие тома кластера (CSV) не поддерживаются.
Вам не следует менять какие-либо файлы в каталогах уровня — они тщательно контролируются с помощью таких команд, как:
Поддерживаемые операции хранилища уровня
Запущенные контейнеры могут использовать большинство операций NTFS, за исключением транзакций. К ним относятся настройка списков управления доступом, при этом все списки проверяются внутри контейнера. Если вы хотите запускать процессы как множество пользователей в контейнере, вы можете создать пользователей в Dockerfile с помощью RUN net user /create . , настроить списки управления доступом к файлу, а затем настроить процессы для выполнения с этим пользователем с помощью директивы Dockerfile USER.
Постоянное хранилище
Контейнеры Windows поддерживают механизмы для обеспечения постоянного хранения с помощью привязок и томов. Дополнительные сведения см. в разделе Постоянное хранилище в контейнерах.
Ограничения хранилища
Обычно приложения для Windows запрашивают объем свободного места на диске перед установкой или созданием новых файлов, а также для удаления временных файлов. Для обеспечения максимальной совместимости приложений диск C: в контейнере Windows представляет виртуальное свободное пространство размером 20 ГБ.
Некоторым пользователям может потребоваться переопределить это значение по умолчанию и настроить свободное пространство меньшей или большей емкости. Это можно сделать с помощью параметра «size» в конфигурации «storage-opt».
Пример
Командная строка: docker run —storage-opt «size=50GB» mcr.microsoft.com/windows/servercore:ltsc2019 cmd
Вы также можете изменить файл конфигурации Docker напрямую.
"storage-opts": [ "size=50GB" ]
Этот способ подходит также для команды docker build. В документе Настройка docker представлены дополнительные сведения об изменении файла конфигурации docker.
Где docker хранит контейнеры?
Хочу перенести их, запустить в другом месте, и сделать резервную копию. В документации ясно написано, что контейнеры создаются в том числе для переноса, однако инструкций как это делается я не нашёл. Нашёл, что docker хранит свои файлы в директории /var/lib/docker однако там у меня много тысяч файлов на 4 GB, а мои контейнеры — намного меньше, не хотелось бы таскать всё что есть в этой директории
Отслеживать
задан 28 окт 2015 в 20:14
Алексей Стародубцев Алексей Стародубцев
649 1 1 золотой знак 4 4 серебряных знака 15 15 бронзовых знаков
Вы изначально при запуске контейнеров не создавали volumes на хостовую машину docker run -v /path/to/host/data::/var/lib/postgresql ?
28 окт 2015 в 20:59
скорее всего создавал, я по инструкции настраивал: github.com/sameersbn/docker-redmine
28 окт 2015 в 21:01
Да, в доках написано —volume=/srv/docker/redmine/postgresql:/var/lib/postgresql . Когда контейнер запускался директория /srv/docker/redmine/postgresql должна была создаться автоматически. Посмотрите, что там или sudo docker inspect —format ‘<< .Volumes >>’ postgresql-redmine . Достаточно заархивировать её, перенести на новый сервер и разархивировать. Путь разархиварования, не имеет значение, ибо директория, как вы уже заметили, задаётся через volume. Далее, на новой машине подтянуть образ контейнера желательно той же версии: docker pull quay.io/sameersbn/postgresql:latest<>
28 окт 2015 в 21:30
Собственно, запускаем postgres-контейнер, но без переменных окружения — нам же не нужно вновь создавать БД и пользователя: docker run —name=postgresql-redmine -d —volume=/srv/docker/redmine/postgresql:/var/lib/postgresql quay.io/sameersbn/postgresql:latest . C redmine аналогично. Архивируем /srv/docker/redmine/redmine , переносим и запускаем docker run —name=redmine -d —link=postgresql-redmine:postgresql -p 10083:80 -e ‘REDMINE_PORT=10083’ -v /srv/docker/redmine/redmine:/home/redmine/data quay.io/sameersbn/redmine
28 окт 2015 в 21:42
Да, перед архивированием контейнеры необходимо остановить docker stop redmine postgresql-redmine , а потому можно запустить вновь docker stop postgresql-redmine redmine .
28 окт 2015 в 21:58
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
В приведённой вами инструкции видно, что контейнер запускается с опцией
--volume=/srv/docker/redmine/postgresql:/var/lib/postgresql
В момент монтирования происходит затирание данных в контейнере, если те присутствовали по этому пути.
Если опция —volume не была указана, то docker автоматически создаёт volumes исходя из параметров указанных в конфигурационном файле Dockerfile.
Если обратиться к исходникам образа для PostgreSQL, то можно заметить, что это два volumes: /var/lib/postgresql и /run/postgresql . По первому пути расположены данные postgres. Собственно, они нас и интересуют.
Узнать всю информацию про volumes отдельно взятого контейнера можно командой
docker inspect --format '>'
Данные возвращаются в json-формате, а потому предусмотрена возможность фильтрации/поиска через опцию —format
Все volumes для которых не указан путь расположения на хосте (левая часть /host/path/to/data:/container/to/data ) хранятся в директории /var/lib/docker/volumes//_data/ . Таким образом, можно просто исследовав все директории в /var/lib/docker/volumes/ и найти необходимый.
Если левая часть указана, а правая совпадает с volumes, которые указаны в Dockerfile (volumes by default), то происходит переопределение директории на хосте. Зачем нам два волиума с одинковыми данными на хосте ( /var/lib/docker/volumes//_data/ и /host/path/to/data ), правда?
Как уже было отмечено @dmitrz, пока не существует возможности управлять volumes уже на поднятых контейнерах, также как и линковать. Первая проблема должна уже очень скоро решиться.
Команда commit
Volume является отдельной сущностью и потому не попадает в commit. Вот что говорит официальная документация.
The commit operation will not include any data contained in volumes mounted inside the container.
Вообще смущает наличие двух методов создания образов: файлами конфигурации и коммитами.
Файл конфигурации задаёт изначальную конфигурацию контейнера в момент запуска, а коммит сохраняет состояние на момент коммита. Если, к примеру, волиумы не задавать (не в конфиге и не при запуске), то состояние контейнера будет меняться (писаться данные будут именно в него). Возможно, у вас может возникнуть ситуация, когда нужно подправить конфиг postgres или ещё что-то сделать внутри контейнера, то с помощью команды docker exec -it postgresql bash вы можете зайти внутрь. Далее, все сделанные изменения вы можете закоммитить в образ, чтобы запуская контейнер где-нибудь ещё из этого образа не повторять все эти действия. Но такой подход сомнительный. Лучше сделать правки в основном конфиге Dockerfile .
Ошибка в версии Ruby
В docker существует такое понятие, как entrypoint. Обычно это shell-скрипт, который дёргается при запуске docker run или docker start . Если посмотреть листинг entrypoint.sh для redmine, то можно заметить установку плагинов (bundles) для redmine. Далее, если файла $/tmp/plugins.sha1 не существует, то происходит установка плагинов. Обратите внимание на переменную $ и посмотрите в Dockerfile для redmine, т.е. REDMINE_DATA_DIR входит в волиум. Вспоминаем, что при коммите данные волиума не заносятся в образ. Когда закоммиченый контейнер запускается на новой машине видимо возникает конфликт старой версии redmine и устанавливаемых вновь плагинов.
Если данные redmine критичны ( /srv/docker/redmine/redmine:/home/redmine/data ), то их обязательно нужно перенести на новую машину. Далее, поднять либо закоммиченый образ, либо загрузить контейнер с уже новой версией redmine по той инструкции.
Можете ознакомится со всеми доступными версиями redmine образов от sameersbn.
Что касается PostgreSQL контейнера, то его данные ( /srv/docker/redmine/postgresql:/var/lib/postgresql ) обязательно необходимо перенести.
Загрузка образов
Загрузка образов из registry (https://hub.docker.com/, https://quay.io/, можно даже поднять локальный) осуществляется с помощь команды
docker pull :
, где тег — это, как правило, версия софта, который находится в этом образе.
Запуск контейнера происходит командой
docker run --name -d :
Если образа с таким именем и тегом на локальной машине нет, то прозрачно срабатывает команда docker pull , т.е. образ ищется на удалённых registry.
Работа с образами — Docker: Основы
Docker — больше, чем просто программа. Это целая экосистема со множеством проектов и сервисов.
В работе с Docker часто приходится иметь дело с Registry. Это хранилище образов, которое работает как репозиторий пакетов любого пакетного менеджера. Именно здесь хранятся образы, которые Docker скачивает во время выполнения команды docker run . Посмотреть список образов хранилища можно на сайте https://hub.docker.com/ .
docker images
Список образов, скачанных на компьютер, можно посмотреть командой docker images :
# В вашем случае вывод будет отличаться docker images REPOSITORY TAG IMAGE ID CREATED SIZE workshopdevops*web latest cfd7771b4b3a 2 days ago 817MB hexletbasics*app latest 8e34a5f631ea 2 days ago 1.3GB mokevnin/rails latest 96487c602a9b 2 days ago 743MB ubuntu latest 2a4cca5ac898 3 days ago 111MB ruby 2.4 713da53688a6 3 weeks ago 687MB ruby 2.5 4c7885e3f2bb 3 weeks ago 881MB nginx latest 3f8a4339aadd 3 weeks ago 108MB elixir latest 93617745963c 4 weeks ago 889MB postgres latest ec61d13c8566 5 weeks ago 287MB
Вторая колонка в выводе выше называется TAG. Когда мы выполняли команду docker run nginx , то на самом деле выполнялась команда docker run nginx:latest . То есть мы не просто скачиваем образ nginx, а скачиваем его конкретный тег. latest — тег по умолчанию. По задумке он обозначает последнюю версию образа.
Такая работа с тегами не является строгим правилом. Конкретный образ вообще может не иметь тега latest, либо иметь, но он не будет содержать последние изменения, просто потому, что никто их не публикует. Впрочем, популярные образы следуют соглашению.
Теги в Docker изменяемы. Другими словами, создатель образа может перезаписать образ, связанный с любым тегом. Такой подход может показаться странным и ненадежным, ведь нет гарантий. К счастью, на практике, есть определенные соглашения, которым стараются следовать все популярные образы. Тег latest действительно содержит последнюю версию и постоянно обновляется, но кроме этого тега активно используется семантическое версионирование . Рассмотрим теги https://hub.docker.com/_/nginx
Теги с полной семантической версией (x.x.x) делают неизменяемыми, даже если в них встречается что-то еще — например, 1.12.2-alpine. Такую версию смело можно брать для продакшен-окружения, так как создатели образа гарантируют, что они будут следовать общим правилам. Теги, подобные такому 1.12, обновляются при изменении patch версии. То есть внутри образа может оказаться и версия 1.12.2 и в будущем 1.12.8. Точно такая же схема и с версиями, в которых указана только мажорная версия, например, 1. Только в данном случае обновление идет не только по патчу, но и по минорной версии.
docker pull
Как влияют теги на работу команды docker run во время скачивания образа? docker run скачивает образ если его нет, но эта проверка не связана с обновлением содержимого. Если nginx:latest обновился, то docker run его не будет скачивать, он использует тот latest, который прямо сейчас уже загружен. Для гарантированного обновления образа существует другая команда: docker pull . Вот она всегда проверяет, обновился ли образ для определенного тега.
# Пытается скачать обновления в образе # даже если он присутствует в локальной системе docker pull nginx
Кроме тегов имя образа может содержать префикс, например, etsy/chef . Этот префикс является именем аккаунта на сайте, через который создаются образы, попадающие в Registry. Большинство образов как раз такие, с префиксом. И есть небольшой набор, буквально сотня образов, которые не имеют префикса. Их особенность в том, что эти образы поддерживает сам Docker. Поэтому если вы видите, что в имени образа нет префикса, значит это официальный образ. Список таких образов можно увидеть здесь .
docker rmi
Удаляются образы командой docker rmi .
Удаление иногда бывает нужно, когда заканчивается место. Образы могут быть тяжелыми и в случае ограниченных ресурсов их регулярно удаляют.
Если в Docker присутствует хоть один контейнер из удаляемого образа, то Docker не даст его удалить, так как это автоматически бы привело к исчезновению всех контейнеров, что может быть нежелательным поведением. Если вы все же хотите удалить и образ, и все контейнеры, связанные с ним, используйте флаг -f .
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Изменение расположения контейнеров и образов Docker в Windows
Docker Desktop в Windows 10 создаёт WSL 2 дистрибутив docker-desktop-data и соответствующий виртуальный диск для него, который обычно расположен здесь:
%USERPROFILE%\AppData\Local\Docker\wsl\data\ext4.vhdx
Именно тут хранятся все контейнеры и образы докера. Для перемещения этого диска в другое место нужно выполнить несколько шагов.
Шаг 1. Выйти из Docker Desktop (если запущен).

Завершение работы Docker Desktop
Шаг 2. В командной строке выполняем команду для вывода списка дистрибутивов Linux:
wsl --list -v
- wsl — команда для взаимодействия с подсистемой Linux в Windows;
- —list — вывести список дистрибутивов Linux;
- -v — вывести расширенную информацию.
Результат выполнения команды должен быть примерно таким:

Список дистрибутивов Linux с расширенной информацией
Состояние дистрибутивов (STATE) должно быть Stopped .
Шаг 3. Экспортируем данные в файл. Можно экспортировать в любое место, этот файл позже можно будет удалить. Например, в корень диска f: :
wsl --export docker-desktop-data "f:\docker-desktop-data.tar"
Шаг 4. Удалим дистрибутив docker-desktop-data из WSL. Во время выполнения этой операции виртуальный диск со всеми данными докера будет удалён.
wsl --unregister docker-desktop-data
Шаг 5. Импортируем дистрибутив обратно в WSL, но теперь в новое место. Например, в папку f:\docker\wsl (папка должна быть предварительно создана):
wsl --import docker-desktop-data "f:\docker\wsl" "f:\docker-desktop-data.tar" --version 2
Шаг 6. Запускаем Docker Desktop и проверяем, что всё работает. Если всё хорошо, можно удалить файл, который мы создали при экспорте дистрибутива на 3 шаге ( f:\docker-desktop-data.tar ).
На этом всё. Данные докера хранятся теперь в новом месте.
Полезные ссылки
При написании статьи использовалось следующее ПО:
- Windows 10 Pro 20H2
- Docker Desktop 3.5.1 (66090)