Изучаем Docker, часть 3: файлы Dockerfile
В переводе третьей части серии материалов, посвящённых Docker, мы продолжим вдохновляться выпечкой, а именно — бубликами. Нашей сегодняшней основной темой будет работа с файлами Dockerfile. Мы разберём инструкции, которые используются в этих файлах.

Бублики — это инструкции в файле Dockerfile
Образы Docker
Вспомните о том, что контейнер Docker — это образ Docker, вызванный к жизни. Это — самодостаточная операционная система, в которой имеется только самое необходимое и код приложения.
Образы Docker являются результатом процесса их сборки, а контейнеры Docker — это выполняющиеся образы. В самом сердце Docker находятся файлы Dockerfile. Подобные файлы сообщают Docker о том, как собирать образы, на основе которых создаются контейнеры.
Каждому образу Docker соответствует файл, который называется Dockerfile. Его имя записывается именно так — без расширения. При запуске команды docker build для создания нового образа подразумевается, что Dockerfile находится в текущей рабочей директории. Если этот файл находится в каком-то другом месте, его расположение можно указать с использованием флага -f .
Контейнеры, как мы выяснили в первом материале этой серии, состоят из слоёв. Каждый слой, кроме последнего, находящегося поверх всех остальных, предназначен только для чтения. Dockerfile сообщает системе Docker о том, какие слои и в каком порядке надо добавить в образ.
Каждый слой, на самом деле, это всего лишь файл, который описывает изменение состояния образа в сравнении с тем состоянием, в котором он пребывал после добавления предыдущего слоя. В Unix, кстати, практически всё что угодно — это файл.
Базовый образ — это то, что является исходным слоем (или слоями) создаваемого образа. Базовый образ ещё называют родительским образом.

Базовый образ — это то, с чего начинается образ Docker
Когда образ загружается из удалённого репозитория на локальный компьютер, то физически скачиваются лишь слои, которых на этом компьютере нет. Docker стремится экономить пространство и время путём повторного использования существующих слоёв.
Файлы Dockerfile
В файлах Dockerfile содержатся инструкции по созданию образа. С них, набранных заглавными буквами, начинаются строки этого файла. После инструкций идут их аргументы. Инструкции, при сборке образа, обрабатываются сверху вниз. Вот как это выглядит:
FROM ubuntu:18.04 COPY . /app
Слои в итоговом образе создают только инструкции FROM , RUN , COPY , и ADD . Другие инструкции что-то настраивают, описывают метаданные, или сообщают Docker о том, что во время выполнения контейнера нужно что-то сделать, например — открыть какой-то порт или выполнить какую-то команду.
Здесь мы исходим из предположения, в соответствии с которым используется образ Docker, основанный на Unix-подобной ОС. Конечно, тут можно воспользоваться и образом, основанным на Windows, но использование Windows — это менее распространённая практика, работать с такими образами сложнее. В результате, если у вас есть такая возможность, пользуйтесь Unix.
Для начала приведём список инструкций Dockerfile с краткими комментариями.
Дюжина инструкций Dockerfile
- FROM — задаёт базовый (родительский) образ.
- LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
- ENV — устанавливает постоянные переменные среды.
- RUN — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
- COPY — копирует в контейнер файлы и папки.
- ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
- CMD — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD .
- WORKDIR — задаёт рабочую директорию для следующей инструкции.
- ARG — задаёт переменные для передачи Docker во время сборки образа.
- ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
- EXPOSE — указывает на необходимость открыть порт.
- VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.
Инструкции и примеры их использования
▍Простой Dockerfile
Dockerfile может быть чрезвычайно простым и коротким. Например — таким:
FROM ubuntu:18.04
▍Инструкция FROM
Файл Dockerfile должен начинаться с инструкции FROM , или с инструкции ARG , за которой идёт инструкция FROM .
Ключевое слово FROM сообщает Docker о том, чтобы при сборке образа использовался бы базовый образ, который соответствует предоставленному имени и тегу. Базовый образ, кроме того, ещё называют родительским образом.
В этом примере базовый образ хранится в репозитории ubuntu. Ubuntu — это название официального репозитория Docker, предоставляющего базовую версию популярной ОС семейства Linux, которая называется Ubuntu.
Обратите внимание на то, что рассматриваемый Dockerfile включает в себя тег 18.04 , уточняющий то, какой именно базовый образ нам нужен. Именно этот образ и будет загружен при сборке нашего образа. Если тег в инструкцию не включён, тогда Docker исходит из предположения о том, что требуется самый свежий образ из репозитория. Для того чтобы яснее выразить свои намерения, автору Dockerfile рекомендуется указывать то, какой именно образ ему нужен.
Когда вышеописанный Dockerfile используется на локальной машине для сборки образа в первый раз, Docker загрузит слои, определяемые образом ubuntu . Их можно представить наложенными друг на друга. Каждый следующий слой представляет собой файл, описывающий отличия образа в сравнении с тем его состоянием, в котором он был после добавления в него предыдущего слоя.
При создании контейнера слой, в который можно вносить изменения, добавляется поверх всех остальных слоёв. Данные, находящиеся в остальных слоях, можно только читать.

Структура контейнера (взято из документации)
Docker, ради эффективности, использует стратегию копирования при записи. Если слой в образе существует на предыдущем уровне и какому-то слою нужно произвести чтение данных из него, Docker использует существующий файл. При этом ничего загружать не нужно.
Когда образ выполняется, если слой нужно модифицировать средствами контейнера, то соответствующий файл копируется в самый верхний, изменяемый слой. Для того чтобы узнать подробности о стратегии копирования при записи, взгляните на этот материал из документации Docker.
Продолжим рассмотрение инструкций, которые используются в Dockerfile, приведя пример такого файла с более сложной структурой.
▍Более сложный Dockerfile
Хотя файл Dockerfile, который мы только что рассмотрели, получился аккуратным и понятным, он устроен слишком просто, в нём используется всего одна инструкция. Кроме того, там нет инструкций, вызываемых во время выполнения контейнера. Взглянем на ещё один файл, который собирает маленький образ. В нём имеются механизмы, определяющие команды, вызываемые во время выполнения контейнера.
FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" ENV ADMIN="jeff" RUN apk update && apk upgrade && apk add bash COPY . ./app ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \ /my_app_directory RUN ["mkdir", "/a_directory"] CMD ["python", "./my_script.py"]
Возможно, на первый взгляд этот файл может показаться довольно сложным. Поэтому давайте с ним разберёмся.
Базой этого образа является официальный образ Python с тегом 3.7.2-alpine3.8. Проанализировав этот код можно увидеть, что данный базовый образ включает в себя Linux, Python, и, по большому счёту, этим его состав и ограничивается. Образы ОС Alpine весьма популярны в мире Docker. Дело в том, что они отличаются маленькими размерами, высокой скоростью работы и безопасностью. Однако образы Alpine не отличаются широкими возможностями, характерными для обычных операционных систем. Поэтому для того, чтобы собрать на основе такого образа что-то полезное, создателю образа нужно установить в него необходимые ему пакеты.
▍Инструкция LABEL

Инструкция LABEL (метка) позволяет добавлять в образ метаданные. В случае с рассматриваемым сейчас файлом, она включает в себя контактные сведения создателя образа. Объявление меток не замедляет процесс сборки образа и не увеличивает его размер. Они лишь содержат в себе полезную информацию об образе Docker, поэтому их рекомендуется включать в файл. Подробности о работе с метаданными в Dockerfile можно прочитать здесь.
▍Инструкция ENV

Окружающая среда
Инструкция ENV позволяет задавать постоянные переменные среды, которые будут доступны в контейнере во время его выполнения. В предыдущем примере после создания контейнера можно пользоваться переменной ADMIN .
Инструкция ENV хорошо подходит для задания констант. Если вы используете некое значение в Dockerfile несколько раз, скажем, при описании команд, выполняющихся в контейнере, и подозреваете, что, возможно, вам когда-нибудь придётся сменить его на другое, его имеет смысл записать в подобную константу.
Надо отметить, что в файлах Dockerfile часто существуют разные способы решения одних и тех же задач. Что именно использовать — это вопрос, на решение которого влияет стремление к соблюдению принятых в среде Docker методов работы, к обеспечению прозрачности решения и его высокой производительности. Например, инструкции RUN , CMD и ENTRYPOINT служат разным целям, но все они используются для выполнения команд.
▍Инструкция RUN

Инструкция RUN
Инструкция RUN позволяет создать слой во время сборки образа. После её выполнения в образ добавляется новый слой, его состояние фиксируется. Инструкция RUN часто используется для установки в образы дополнительных пакетов. В предыдущем примере инструкция RUN apk update && apk upgrade сообщает Docker о том, что системе нужно обновить пакеты из базового образа. Вслед за этими двумя командами идёт команда && apk add bash , указывающая на то, что в образ нужно установить bash.
То, что в командах выглядит как apk — это сокращение от Alpine Linux package manager (менеджер пакетов Alpine Linux). Если вы используете базовый образ какой-то другой ОС семейства Linux, тогда вам, например, при использовании Ubuntu, для установки пакетов может понадобиться команда вида RUN apt-get . Позже мы поговорим о других способах установки пакетов.
Инструкция RUN и схожие с ней инструкции — такие, как CMD и ENTRYPOINT , могут быть использованы либо в exec-форме, либо в shell-форме. Exec-форма использует синтаксис, напоминающий описание JSON-массива. Например, это может выглядеть так: RUN [«my_executable», «my_first_param1», «my_second_param2»] .
В предыдущем примере мы использовали shell-форму инструкции RUN в таком виде: RUN apk update && apk upgrade && apk add bash .
Позже в нашем Dockerfile использована exec-форма инструкции RUN , в виде RUN [«mkdir», «/a_directory»] для создания директории. При этом, используя инструкцию в такой форме, нужно помнить о необходимости оформления строк с помощью двойных кавычек, как это принято в формате JSON.
▍Инструкция COPY

Инструкция COPY
Инструкция COPY представлена в нашем файле так: COPY . ./app . Она сообщает Docker о том, что нужно взять файлы и папки из локального контекста сборки и добавить их в текущую рабочую директорию образа. Если целевая директория не существует, эта инструкция её создаст.
▍Инструкция ADD
Инструкция ADD позволяет решать те же задачи, что и COPY , но с ней связана ещё пара вариантов использования. Так, с помощью этой инструкции можно добавлять в контейнер файлы, загруженные из удалённых источников, а также распаковывать локальные .tar-файлы.
В этом примере инструкция ADD была использована для копирования файла, доступного по URL, в директорию контейнера my_app_directory . Надо отметить, однако, что документация Docker не рекомендует использование подобных файлов, полученных по URL, так как удалить их нельзя, и так как они увеличивают размер образа.
Кроме того, документация предлагает везде, где это возможно, вместо инструкции ADD использовать инструкцию COPY для того, чтобы сделать файлы Dockerfile понятнее. Полагаю, команде разработчиков Docker стоило бы объединить ADD и COPY в одну инструкцию для того, чтобы тем, кто создаёт образы, не приходилось бы помнить слишком много инструкций.
Обратите внимание на то, что инструкция ADD содержит символ разрыва строки — \ . Такие символы используются для улучшения читабельности длинных команд путём разбиения их на несколько строк.
▍Инструкция CMD

Инструкция CMD
Инструкция CMD предоставляет Docker команду, которую нужно выполнить при запуске контейнера. Результаты выполнения этой команды не добавляются в образ во время его сборки. В нашем примере с помощью этой команды запускается скрипт my_script.py во время выполнения контейнера.
Вот ещё кое-что, что нужно знать об инструкции CMD :
- В одном файле Dockerfile может присутствовать лишь одна инструкция CMD . Если в файле есть несколько таких инструкций, система проигнорирует все кроме последней.
- Инструкция CMD может иметь exec-форму. Если в эту инструкцию не входит упоминание исполняемого файла, тогда в файле должна присутствовать инструкция ENTRYPOINT . В таком случае обе эти инструкции должны быть представлены в формате JSON .
- Аргументы командной строки, передаваемые docker run , переопределяют аргументы, предоставленные инструкции CMD в Dockerfile.
▍Ещё более сложный Dockerfile
Рассмотрим ещё один файл Dockerfile, в котором будут использованы некоторые новые команды.
FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" # Устанавливаем зависимости RUN apk add --update git # Задаём текущую рабочую директорию WORKDIR /usr/src/my_app_directory # Копируем код из локального контекста в рабочую директорию образа COPY . . # Задаём значение по умолчанию для переменной ARG my_var=my_default_value # Настраиваем команду, которая должна быть запущена в контейнере во время его выполнения ENTRYPOINT ["python", "./app/my_script.py", "my_var"] # Открываем порты EXPOSE 8000 # Создаём том для хранения данных VOLUME /my_volume
В этом примере, кроме прочего, вы можете видеть комментарии, которые начинаются с символа # .
Одно из основных действий, выполняемых средствами Dockerfile — это установка пакетов. Как уже было сказано, существуют различные способы установки пакетов с помощью инструкции RUN .
Пакеты в образ Alpine Docker можно устанавливать с помощью apk . Для этого, как мы уже говорили, применяется команда вида RUN apk update && apk upgrade && apk add bash .
Кроме того, пакеты Python в образ можно устанавливать с помощью pip, wheel и conda. Если речь идёт не о Python, а о других языках программирования, то при подготовке соответствующих образов могут использоваться и другие менеджеры пакетов.
При этом для того, чтобы установка была бы возможной, нижележащий слой должен предоставить слою, в который выполняется установка пакетов, подходящий менеджер пакетов. Поэтому если вы столкнулись с проблемами при установке пакетов, убедитесь в том, что менеджер пакетов установлен до того, как вы попытаетесь им воспользоваться.
Например, инструкцию RUN в Dockerfile можно использовать для установки списка пакетов с помощью pip . Если вы так поступаете — объедините все команды в одну инструкцию и разделите её символами разрыва строки с помощью символа \ . Благодаря такому подходу файлы будут выглядеть аккуратно и это приведёт к добавлению в образ меньшего количества слоёв, чем было бы добавлено при использовании нескольких инструкций RUN .
Кроме того, для установки нескольких пакетов можно поступить и по-другому. Их можно перечислить в файле и передать менеджеру пакетов этот файл с помощью RUN . Обычно таким файлам дают имя requirements.txt .
▍Инструкция WORKDIR

Рабочие директории
Инструкция WORKDIR позволяет изменить рабочую директорию контейнера. С этой директорией работают инструкции COPY , ADD , RUN , CMD и ENTRYPOINT , идущие за WORKDIR . Вот некоторые особенности, касающиеся этой инструкции:
- Лучше устанавливать с помощью WORKDIR абсолютные пути к папкам, а не перемещаться по файловой системе с помощью команд cd в Dockerfile.
- Инструкция WORKDIR автоматически создаёт директорию в том случае, если она не существует.
- Можно использовать несколько инструкций WORKDIR . Если таким инструкциям предоставляются относительные пути, то каждая из них меняет текущую рабочую директорию.
▍Инструкция ARG
Инструкция ARG позволяет задать переменную, значение которой можно передать из командной строки в образ во время его сборки. Значение для переменной по умолчанию можно представить в Dockerfile. Например: ARG my_var=my_default_value .
В отличие от ENV -переменных, ARG -переменные недоступны во время выполнения контейнера. Однако ARG -переменные можно использовать для задания значений по умолчанию для ENV -переменных из командной строки в процессе сборки образа. А ENV -переменные уже будут доступны в контейнере во время его выполнения. Подробности о такой методике работы с переменными можно почитать здесь.
▍Инструкция ENTRYPOINT

Пункт перехода в какое-то место
Инструкция ENTRYPOINT позволяет задавать команду с аргументами, которая должна выполняться при запуске контейнера. Она похожа на команду CMD , но параметры, задаваемые в ENTRYPOINT , не перезаписываются в том случае, если контейнер запускают с параметрами командной строки.
Вместо этого аргументы командной строки, передаваемые в конструкции вида docker run my_image_name , добавляются к аргументам, задаваемым инструкцией ENTRYPOINT . Например, после выполнения команды вида docker run my_image bash аргумент bash добавится в конец списка аргументов, заданных с помощью ENTRYPOINT . Готовя Dockerfile, не забудьте об инструкции CMD или ENTRYPOINT .
В документации к Docker есть несколько рекомендаций, касающихся того, какую инструкцию, CMD или ENTRYPOINT , стоит выбрать в качестве инструмента для выполнения команд при запуске контейнера:
- Если при каждом запуске контейнера нужно выполнять одну и ту же команду — используйте ENTRYPOINT .
- Если контейнер будет использоваться в роли приложения — используйте ENTRYPOINT .
- Если вы знаете, что при запуске контейнера вам понадобится передавать ему аргументы, которые могут перезаписывать аргументы, указанные в Dockerfile, используйте CMD .
Документация Docker рекомендует использовать exec-форму ENTRYPOINT : ENTRYPOINT [«executable», «param1», «param2»] .
▍Инструкция EXPOSE

Инструкция EXPOSE
Инструкция EXPOSE указывает на то, какие порты планируется открыть для того, чтобы через них можно было бы связаться с работающим контейнером. Эта инструкция не открывает порты. Она, скорее, играет роль документации к образу, средством общения того, кто собирает образ, и того, кто запускает контейнер.
Для того чтобы открыть порт (или порты) и настроить перенаправление портов, нужно выполнить команду docker run с ключом -p . Если использовать ключ в виде -P (с заглавной буквой P ), то открыты будут все порты, указанные в инструкции EXPOSE .
▍Инструкция VOLUME

Инструкция VOLUME
Инструкция VOLUME позволяет указать место, которое контейнер будет использовать для постоянного хранения файлов и для работы с такими файлами. Об этом мы ещё поговорим.
Итоги
Теперь вы знаете дюжину инструкций, применяемых при создании образов с помощью Dockerfile. Этим список таких инструкций не исчерпывается. В частности, мы не рассмотрели здесь такие инструкции, как USER , ONBUILD , STOPSIGNAL , SHELL и HEALTHCHECK . Вот краткий справочник по инструкциям Dockerfile.
Вероятно, файлы Dockerfile — это ключевой компонент экосистемы Docker, работать с которым нужно научиться всем, кто хочет уверенно чувствовать себя в этой среде. Мы ещё вернёмся к разговору о них в следующий раз, когда будем обсуждать способы уменьшения размеров образов.
Уважаемые читатели! Если вы пользуетесь Docker на практике, просим рассказать о том, как вы пишете Docker-файлы.

- Блог компании RUVDS.com
- Веб-разработка
- Виртуализация
Как сохранить образ docker
С помощью команды docker save «image» > «path».tar образ сохраняется, но весит очень много, около 2Гб, а также не открывается с ошибкой «Файл имеет неверный формат или поврежден» Мой Dockerfile:
FROM node:18-alpine WORKDIR /usr/src/app EXPOSE 3000 COPY package.json ./ RUN npm install COPY . . CMD ["npm", "run", "start"]
docker-compose.yml:
version: '3.8' services: app: build: context: ./APP container_name: front ports: - '3000:3000' volumes: - .:/APP
Возможно ли, что образ выгружается вместе со всеми зависимостями в виде ОС и тд, если да, то как выгрузить образ без этих зависимостей?
Отслеживать
задан 12 апр в 16:08
43 7 7 бронзовых знаков
а зачем? и как вы пытаетесь его открыть, что получаете ошибку «Файл имеет неверный формат или поврежден»?
12 апр в 18:06
Образ нужно развернуть на другой системе, а открыть я его пытался винраром и 7zip
12 апр в 21:49
для этих целей обычно используют docker registry, например docker hub или любой другой, но даже если вы хотите использовать docker save, то на другой машине нужно просто использовать docker load и все, а уменьшить образ можно с помощью multistage build
12 апр в 21:51
2 gb — это как-то очень много. Я собрал небольшое приложение в докере на образе node:18-alpine , и получил всего 172 мб, а после сжатия gzip и вовсе 50 мб. Вы уверены, что ничего лишнего не тащите в образ инструкцией COPY . . ?
13 апр в 2:49
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Да, image save выгружает образ целиком, включая базовый образ. Восстановить образ из архива командой image load
У вас получается архив размером 2 Гб? Это очень странно. Базовый образ всего 174 мб, сжатием gzip получается 50 мб.
Я сделал маленький образ
FROM node:18-alpine WORKDIR /usr/src/app EXPOSE 8081 COPY ./src . CMD ["node", "hello.js"]
В ./src лежит единственный файл hello.js
var http = require("http"); http.createServer(function (request, response) < response.writeHead(200, < 'Content-Type': 'text/plain' >); response.end('Hello World\n'); >).listen(8081); console.log('Server started at http://localhost:8081/');
docker build . -t try-node
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE try-node latest 4445087d824e 13 minutes ago 175MB
docker image save try-node | gzip > image.tar.gz du -sm image.tar.gz
50 image.tar.gz
Итого — выгруженный сжатый образ размером 50 мегабайт.
$ docker image rm try-node $ cat image.tar.gz | gzip -d | docker image load f1417ff83b31: Loading layer [==================================================>] 7.338MB/7.338MB 8f90faa0eb99: Loading layer [==================================================>] 164.2MB/164.2MB e2ed77d8fead: Loading layer [==================================================>] 7.819MB/7.819MB 1e9663a5b8eb: Loading layer [==================================================>] 3.584kB/3.584kB 03429486714c: Loading layer [==================================================>] 3.072kB/3.072kB 242deab87f84: Loading layer [==================================================>] 3.584kB/3.584kB Loaded image: try-node:latest
Образ загружен и добавлен в список образов:
docker image ls try-node REPOSITORY TAG IMAGE ID CREATED SIZE try-node latest 4445087d824e 25 minutes ago 175MB
Как поделиться образами Docker с другими —
Вы создали образ Docker, которым нужно поделиться с коллегой? Вот как можно распространять изображение без необходимости его запуска получателем. docker build сами по себе.
Поделиться предустановленным изображением вместо одного Dockerfile позволяет убедиться, что ваш коллега использует точно такое же программное обеспечение. Повторный запуск компиляции может привести к несколько иному окружению. У вас есть два варианта показа вашего изображения, в зависимости от ситуации.
Используйте реестр Docker
Самый простой способ поделиться образом Docker — загрузить его в реестр Docker. Эта функциональность полностью интегрирована с Docker CLI. При использовании этого метода вам не нужно выполнять передачу файлов вручную.
Реестр по умолчанию — Docker Hub. Это позволяет вам обмениваться изображениями публично, а также предоставляет вам частный репозиторий. Создайте учетную запись в Docker Hub, затем запустите docker login в вашем терминале. Предоставьте данные своей учетной записи, чтобы подключить Docker CLI к вашей учетной записи.
Затем создайте свой образ как обычно, используя docker build . Добавьте тег, который начинается с вашего имени пользователя Docker Hub:
docker build -t my-account / my-image: latest.
Затем используйте docker push команда, чтобы отправить помеченное изображение в Docker Hub:
docker push my-account / my-image: последний
Теперь ваш образ надежно хранится в Docker Hub. Другие пользователи могут удалить его с помощью docker pull или docker run заказы. Вы закончили делиться своим изображением!
Для реального использования Docker Hub может быть недостаточно. Если вы являетесь частью команды разработчиков, вы, вероятно, захотите хранить образы на своем собственном сервере, а не в общедоступном реестре Hub. Вместо этого вы можете создать собственный сервер реестра, чтобы получить частное хранилище, полностью совместимое с. docker push et docker pull заказы. Это позволяет вам легко обмениваться изображениями с любым, у кого есть доступ к вашему личному реестру.
Экспорт изображений
Если использование реестра невозможно, вы можете вручную экспортировать архивы образов Docker. Эта функция также интегрирована в Docker CLI. Создайте свой образ, затем используйте docker save чтобы получить tar архив его содержимого:
докер сохранить мое-изображение: последнее> мое-изображение.tar
Экспорт может занять некоторое время. Docker будет включать в себя все необходимое для воссоздания образа — это все слои в вашем Dockerfile , а также слои, унаследованные от вашего базового изображения. В архиве также будет информация о тегах, связанных с изображением.
Как выход простой tar файл, теперь вы можете свободно распространять его по своему усмотрению. Архивы могут быть довольно большими, поэтому обычно лучше загружать их на файловый сервер или у поставщика облачного хранилища.
Чтобы использовать экспортированное изображение, запустите docker load порядок. Это принимает tar архивы, созданные docker save как входной поток. Docker загрузит содержимое архива и добавит его в список ваших локальных образов.
docker loadТеперь вы увидите недавно импортированное изображение в своем docker images производство. Вы готовы запустить новый контейнер с docker run .
Экспорт и импорт образов добавляет еще несколько шагов к использованию реестра Docker. Вам нужно будет вручную передать файл между клиентами. Поэтому этот подход менее подходит для частого использования, хотя и имеет свои преимущества.
Преобразование изображений в tar архив может быть полезен для длительного хранения. Если вам не хватает места на сервере реестра, архивируйте старые образы и загружайте их tars Резервное копирование файлового хранилища может быть экономичным способом восстановления некоторой емкости. Вы все равно сможете восстановить изображение, если оно вам понадобится в будущем.
А как насчет "экспорта докеров"?
У Docker есть еще один порядок, связанный с экспортом, docker export . Не следует путать с docker save . В то время как save работает с изображениями, export фактически управляет человеком контейнеры.
docker export создаст tar архив файловой системы контейнера. Это можно использовать для восстановления реплики контейнера на другой машине. Если вы проверите содержимое архива, вы увидите, что это обычная корневая файловая система Linux с такими каталогами, как /bin , /etc et /usr .
докер экспорт мой-контейнер> мой-контейнер.tardocker export полезно, если вы хотите сделать снимок контейнера для последующего восстановления. Однако архивы контейнеров не импортируются должным образом. Поскольку контейнер представляет собой работающую среду, вы не можете «импортировать» его напрямую. Вместо этого при импорте архива контейнера создается Модерн изображения.
docker import my-container.tar my-image: последнийВ этом примере Docker возьмет файловую систему из my-container.tar и автоматически создаст новый образ с именем my-image:latest . Он будет иметь ту же файловую систему, но не тот же базовый образ или конфигурацию Docker, что и исходный контейнер, который вы экспортировали.
Резюме
Docker упрощает обмен изображениями приложений и сред разработки с вашими сотрудниками. Обычно лучше всего загружать изображения в централизованный репозиторий, из которого любой может их получить. В некоторых случаях может иметь смысл экспортировать изображение в архив, который вы распределяете вручную.
Docker также позволяет экспортировать файловую систему контейнера для последующего восстановления в образ. Будьте осторожны при его использовании, так как это не точная перестройка и не все данные файловой системы включены. Любые тома, смонтированные в исходном контейнере, не будут включены в архив файловой системы, поэтому вам следует предпринять шаги для их отдельного резервного копирования.
Tremplin Numérique
Написание Tremplin Numérique, французское веб-агентство. Наши авторы ежедневно и бесплатно предоставляют вам последние технологические и цифровые новости во Франции и во всем мире.
Выгрузка, загрузка и распространение образов контейнеров Docker в виде архива
Стандартный способ распространения образов Docker — использование репозиториев Docker, которые позволяют как опубликовать вновь созданные образы, так и скачать их для локального использования. Развернуть локальный реестр Docker можно за 1 минуту, однако, для полноценного использования требуется больше действий, например, установка SSL-сертификата и поддержка авторизации.
Бывают случаи, когда серверы, на которых планируется выполнять контейнеры, созданные из образов, полностью изолированы от сегмента сети и не могут скачать себе образ из реестра. В этом случае у разработчиков возникает необходимость каким-то образом сформировать образ контейнера на сервере. Команда docker build тоже часто не подходит, поскольку большинство образов при сборке скачивает зависимости и необходимые слои из сети. Если хост не имеет подключения к сети, то и скачать ничего не сможет.
К счастью, Docker предоставляет стандартный механизм для распространения образов без использования реестров с помощью импорта и экспорта. Далее в статье мы рассмотрим как воспользоваться этими возможностями для того, чтобы эффективно распространять образы на серверы, где подключение к интернет невозможно.
Вообще, данный подход можно применять и в ряде других случаев, часть из которых мы перечислим ниже:
- обеспечение развертывания без сети;
- гарантированное развертывание с твердого носителя (USB, DVD);
- поставка в форме готового к использовании дистрибутива;
- минимизация инфраструктуры за счет исключения лишних элементов (registry).
Сохранение образа в архив
Для начала рассмотрим как можно выполнить сохранение образа контейнера из среды. Для выполнения данной операции используется команда docker save (man docker-save):
docker pull ubuntu:18.04 docker save -o ubuntu-1804.tar ubuntu:18.04
После выполнения данной команды образ со всеми слоями будет выгружен из пространства образов демона Docker в файловую систему в виде архива tar.
Интересно, что таким образом можно выгрузить более одного образа:
docker pull ubuntu:16.04 docker save -o ubuntu-16+18.tar ubuntu:18.04 ubuntu:16.04
Таким образом, вы можете за одну команду выгрузить все необходимые для распространения контейнеры в один tar-архив.
Загрузка образа в среду Docker
Для выполнения загрузки ипользуется обратная операция docker load:
# удалим образы docker rmi ubuntu:18.04 ubuntu:16.04 # убедимся, что нет доступных образов docker images | grep ubuntu | wc -l # загрузим образы из архива в среду Docker docker load -i ubuntu-16+18.tar aa54c2bc1229: Loading layer [==================================================>] 121.6MB/121.6MB 7dd604ffa87f: Loading layer [==================================================>] 15.87kB/15.87kB 2f0d1e8214b2: Loading layer [==================================================>] 11.78kB/11.78kB 297fd071ca2f: Loading layer [==================================================>] 3.072kB/3.072kB Loaded image: ubuntu:16.04 Loaded image: ubuntu:18.04 # проверим доступное количество образов docker images | grep ubuntu | wc -l 2
Таким образом вы можете распространять образы контейнеров Docker между узлами без использования реестра и даже сети, например, на DVD или накопителе USB.
Отличия Save, Load от Export, Import
Docker поддерживает команды export и import, которые часто могут быть перепутаны с save, load. Ключевое отличие данных команд в том, для чего они предназначены:
- save/load выгружают и загружают образы контейнеров, которые будут использоваться для создания контейнеров;
- export выгружает файловую систему созданного контейнера (не образ контейнера, а изменения, которые внес контейнер в образ);
- import позволяет создать образ тома файловой системы из архива, созданного с помощью export, который может использоваться, например, при запуске контейнера с помощью —volumes-from.
В целом, разница заключается, что save/load относятся к данным образов, а export/import к данным контейнеров.