Docker, Программирование

Создание образов

Время прочтения: 4 мин.

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

1. Установка

Для начала следует проверить, все ли корректно установлено. Для этого вам понадобится линуксовый инстанс, в данной статье на хост-машине используется дистрибутив ubuntu 19:04.

Установка докера:

sudo snap install docker

Для проверки корректности установки, мы можем запустить контейнер – аналог “hello world” .

sudo docker run hello-world

Так как образа нет изначально в вашей системе, то при запуске этой команды из публичного реестра DockerHub будет выгружен образ hello-world. Затем запустится соответствующий контейнер, который выведет результат в стандартный поток вывода.

Чтобы каждый раз не вводить sudo вы можете добавить вашего пользователя в группу docker:

sudo usermod -aG docker ${USER}

Но следует иметь ввиду, что каждый пользователь, который имеет права на запуск контейнеров, фактически может получить себе root доступ. Это связано с монтированием разделов, что будет рассмотрено только в следующей статье. Краткое резюме: если вы изучаете docker на локальном компьютере, то можно и добавить своего пользователя в группу для удобства.

2. Способы создания контейнеров

Итак, существует два основных способа создания новых образов:

  • Создание образа из контейнера
  • Создание с использованием докерфайлов

2.1 Создание образа из контейнера

Мы можем любой докер-контейнер превратить в образ, чтобы затем из него создавать новые контейнеры. Рассмотрим подробнее это на примере. Для начала выведем список образов, которые присутствуют в системе на данный момент:

docker images

Создадим контейнер, используя в качестве базового образа ubuntu: 16.04, запустим его в интерактивном режиме, затем внесем в него какие-либо изменения, например, запишем текст в файл. Далее создадим образ из этого контейнера.

1) Запускаем, ключ –it (означает интерактивный режим):

docker run -it --name my-new-container ubuntu:16.04

2) Внутри контейнера запишем строку перенаправив стандартный поток вывода в файл в каталоге root:

echo random_text  > my_text

3) Выходим из контейнера:

exit

4) Создаем образ из измененного контейнера. Для этого используется команда docker commit, где первый аргумент — это имя контейнера, а второй — имя создаваемого образа:

docker commit my-new-container my-new-image

5) Создаем контейнер из нашего нового образа и можем зайти убедиться, сохранился ли файл:

docker run -it --rm my-new-image

Стоит упомянуть ещё одну полезную команду, с помощью которой можно просмотреть историю изменений образа, а конкретно, какие операции были проделаны при его создании. Для этого используется команда docker history, где первый аргумент – это название образа.

docker history my-new-image

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

2.2 Докерфайлы

Существует и другой способ создания образов, где компенсируется этот недостаток. Этот способ заключается в использовании файлов со специальным синтаксисом, в которых описан процесс создания. Использование таких файлов делает процесс создания образов более воспроизводимым.

Докерфайл — это текстовый файл, который содержит в себе набор инструкций, описывающий то, как должен быть устроен создаваемый образ.

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

1) Открываем файл в отдельном каталоге:

vim Dockerfile

2) Первая инструкция — это инструкция FROM, которая указывает то, из какого базового образа создаем новый. Мы также будем использовать ubuntu 16.04:

FROM ubuntu:16.04

3) Рекомендуется указывать человека, отвечающего за поддержку этого образа:

LABEL maintainer="Andreev Nickolay"

4) С помощью инструкции RUN мы можем выполнять shell-команды, в частности инсталлировать необходимые пакеты python. Sudo не требуется, так как по умолчанию в контейнере мы авторизуемся как root:

RUN apt-get update \
        && apt-get install python3-pip -y \
        && pip3 install  --upgrade pip \
        && pip3 install numpy pandas scipy

5) Изменим точку входа для создаваемого образа. Для изменения точки входа используется инструкция ENTRYPOINT. Зададим в качестве точки входа интерактивный режим python:

ENTRYPOINT ["python3"]

6) Затем сохраним файл и соберем из него образ. Для сборки образа используется команда docker build, параметр -t определяет имя создаваемого образа. Обязательным параметром также является папка, в которой происходит сборка образа. Важно понимать, что все файлы, которые находятся в ней кэшируются при сборке, поэтому нежелательно, чтобы в этой папке находились те файлы, которые на практике не требуются для сборки образа:

docker build –t my-python-image 

7) Образ собран, и мы можем увидеть его в списке:

docker images

8) Запускаем наш контейнер и убеждаемся, что в качестве точки входа установлен python со всеми необходимыми библиотеками:

docker run -it --rm my-python-image

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

В нашем случае при создании образа в качестве точки входа был указан интерактивный режим Python. Но точно также мы можем установить и все необходимые библиотеки, указав в качестве точки входа конкретный скрипт для его изолированного запуска.

Советуем почитать