Продвинутым
October 14, 2021

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

1package & Let's Node

⠀Прописав инструкции в файле под названием Dockerfile, можно создать свой образ, а затем использовать его или даже опубликовать на Docker Hub.


Содержание

Знакомство с Docker

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


Вступление

К содержанию

⠀Знакомство с Docker происходит в статье для новичков.


Инструкции Dockerfile

К содержанию

⠀Как было изложено в статье для новичков:

⠀Dockerfile — это основа любого образа. Этот файл содержит заранее прописанный набор инструкций (команд), которые выполняются построчно, добавляя слои, и в итоге собираются в образ, доступный для использования.

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

⠀Если не написано, что инструкция является обязательной, то она является необязательной.

⠀Если не написано, что инструкция может использоваться только один раз, то она может использоваться один или несколько раз.

FROM

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

⠀Общедоступные образы можно найти на Docker Hub.

⠀Допускается использование опции --platform, которая используется для указания платформы образа, в случае, если указанный образ является мультиплатформенным, например:

  • linux/amd64
  • linux/arm64
  • windows/amd64

⠀По умолчанию используется платформа ОС, на которой работает Docker.

⠀Примеры использования

FROM ubuntu
FROM python:3.9.7-slim
FROM --platform=linux/arm64/v8 mongo

LABEL

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

⠀Примеры использования

LABEL "vendor"="Google"
LABEL value="hello"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
LABEL one="value1" two="value2" three="value3"
LABEL one="value1" \
      two="value2" \
      three="value3"

ENV

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

⠀Значения переменных могут быть изменены в команде создания контейнера

docker run --env KEY=VALUE

⠀Примеры использования

ENV one="value one"
ENV two=value\ two
ENV three=value3
ENV one="value one" two=value\ two \
    three=value3

ARG

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

⠀Значения переменных могут быть изменены в команде создания образа

docker build --build-arg KEY=VALUE

⠀Примеры использования

ARG value
ARG DEBIAN_FRONTEND=noninteractive

WORKDIR

⠀Создаёт и задаёт рабочий каталог для последующих инструкций RUN, CMD, ENTRYPOINT, COPY и ADD. Допускается использование переменных окружения ENV.

⠀Примеры использования

WORKDIR /dir
# /dir
WORKDIR /dir1
WORKDIR dir2
# /dir1/dir2
ENV DIRPATH=/dir1
WORKDIR $DIRPATH/dir2/$DIRPATH
# /dir1/dir2/dir1

RUN

⠀Выполняет любые команды в новом слое и сохраняет результаты выполнения. Допускается использование обратных слешей, переменные, объявленные в виде var="..." или export var="...", работают только внутри команды, где были объявлены.

⠀Может быть двух типов:

  • shell — команда выполняется в оболочке по умолчанию: /bin/sh -c в Linux или cmd /S /C в Windows;
  • exec — команда выполняется не используя оболочку.

⠀Примеры использования

RUN echo "Hello, World!"
RUN export text="I'm a cow!"; \
    apt update && \
    apt upgrade -y && \
    apt install cowsay; \
    apt clean; \
    cowsay "$text"
RUN ["sh", "-c", "echo $HOME"]
RUN ["/bin/bash", "-c", "echo Hello"]

USER

⠀Задает имя пользователя (или UID) и, по желанию, группу пользователей (или GID) от имени которого будет выполнятся последующие инструкции RUN, CMD и ENTRYPOINT.

⠀Сначала нужно создать пользователя, в разных ОС разная команда.

⠀Примеры использования

RUN useradd -ms /bin/bash user
USER user

RUN groupadd friends \
    useradd -ms /bin/bash -g friends john
USER john:friends

ADD

⠀Закачивает указанный файл или папку с хоста или по ссылке в образ в указанное место. Обладает особенностью — при закачивании распаковывает tar архивы.

⠀Команда имеет синтаксис

ADD WHAT TO
  • WHAT — ссылка, файл или папка, которую закачивать;
  • TO — файл или папка, в которую закачивать.

⠀Подчиняется правилам:

  • WHAT должен находится в папке, из которой создаётся образ.
  • Если WHAT это ссылка, а TO не заканчивается /, то загруженный файл копируется в TO.
  • Если WHAT это ссылка, а TO заканчивается /, то название файла получается из ссылки, а файл закачивается в TO/FILENAME. Например, ADD http://example.com/test /dir создаст файл /dir/test.
  • Если WHAT это папка, то скопируется всё содержимое.
  • Если WHAT это tar архив, сжатый identity, gzip, bzip2 или xz алгоритмом, то он будет распакован как папка. Архивы, закачанные по ссылке не распаковываются.
  • Если WHAT это файл, то он копируется отдельно.
  • Если указано несколько WHAT, то TO должен заканчиваться /.
  • Если TO не заканчивается /, то он будет считаться файлом и будет перезаписан WHAT.
  • Если TO не существует, то он будет создан вместе со всеми отсутствующими в пути папками.

⠀Можно использовать следующие символы:

  • * — любое количество любых символов;
  • ? — один любой символ.

⠀Примеры использования

ADD file.tar.gz /dir
ADD test.txt /dir/
ADD tes?.txt /dir/
ADD tes* /dir/
ADD test1.txt test2.sh test3.toml /dir/

COPY

⠀Всё идентично ADD, за исключением:

  • Не позволяет закачивать файлы по ссылке;
  • Не распаковывает архивы.

⠀Примеры использования

COPY file.tar.gz /dir
COPY test.txt /dir/
COPY tes?.txt /dir/
COPY tes* /dir/
COPY test1.txt test2.sh test3.toml /dir/

EXPOSE

⠀Сообщает Docker, что контейнер прослушивает указанные сетевые порты во время выполнения. Можно задать tcp (по умолчанию) или upd протокол.

⠀При использовании команды docker run -P открываются все указанные порты, однако сопоставляются с портами хоста высокого порядка: 49XXX. Поэтому желательно сопоставлять порты при помощи опции -p.

⠀Примеры использования

EXPOSE 8000
EXPOSE 8000 8001 8002
EXPOSE 80/tcp
EXPOSE 80/udp

ENTRYPOINT

⠀Определяет исполняемый файл для запуска контейнера.

⠀Может быть двух типов:

  • shell — команда выполняется в оболочке по умолчанию: /bin/sh -c в Linux или cmd /S /C в Windows (лучше не использовать);
  • exec — команда выполняется не используя оболочку.

⠀Аргументы команды docker run после названия образа будут добавлены в конец exec-формы ENTRYPOINT и перезапишут все элементы, указанные с помощью инструкции CMD. Значение ENTRYPOINT может быть изменено с помощью опции docker run --entrypoint.

⠀Обязательно должна быть хотя бы одна ENTRYPOINT или CMD инструкция, либо обе, при этом допускается использование только одной ENTRYPOINT инструкции.

⠀Примеры использования

ENTRYPOINT ["echo", "Hello, World!"]
ENTRYPOINT ["/bin/sh", "-c", "cd dir1/ && mkdir dir2"]

ENTRYPOINT ["java"]
CMD ["-jar", "main.jar"]

ENTRYPOINT ["python3"]
CMD ["main.py"]

CMD

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

⠀Может быть двух типов:

  • shell — команда выполняется в оболочке по умолчанию: /bin/sh -c в Linux или cmd /S /C в Windows (лучше не использовать);
  • exec — команда выполняется не используя оболочку.

⠀Аргументы команды docker run после названия образа перезапишут все элементы, указанные с помощью инструкции CMD.

⠀Обязательно должна быть хотя бы одна ENTRYPOINT или CMD инструкция, либо обе, при этом допускается использование только одной CMD инструкции.

⠀Примеры использования

CMD ["echo", "Hello, World!"]
CMD ["/bin/sh", "-c", "cd dir1/ && mkdir dir2"]

ENTRYPOINT ["java"]
CMD ["-jar", "main.jar"]

ENTRYPOINT ["python3"]
CMD ["main.py"]

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

К содержанию

⠀Для начала необходимо создать папку, в которую будет помещён Dockerfile и необходимые для создания образа файлы

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

mkdir docker/

⠀Перейти в неё

cd docker/

⠀У себя на ПК или на хосте создать Dockerfile. На хосте можно создать командой

sudo touch Dockerfile

⠀Открыть файл Dockerfile при помощи текстового редактора и прописать необходимые инструкции.

⠀В образах на базе Linux Ubuntu необходимо обязательно использовать инструкции ниже (временную зону TZ можно выбрать из списка), иначе создание образа зависнет на моменте выбора временной зоны.

ARG DEBIAN_FRONTEND=noninteractive

ENV TZ=UTC

⠀При установке пакетов в любом из Linux дистрибутивов желательно очищать кэш утилиты для работы с пакетами с целью экономии места.

⠀Пример в нескольких дистрибутивах:

  • Ubuntu
RUN apt update && \
    apt upgrade -y && \
    apt install ... -y; \
    apt clean
    
  • Alpine
RUN apk add -U ...; \
    apk cache clean
# Или просто
RUN apk add -U --no-cache ...

⠀Примеры Dockerfile:

  • Говорящая корова
FROM alpine

RUN apk add -U --no-cache perl perl-text-charwidth

COPY cowsay /usr/local/bin/
COPY cows /usr/share/cowsay/cows

ENTRYPOINT ["cowsay"]
  • Python скрипт
FROM python:3.9.7-slim

WORKDIR /program_name

COPY . .
RUN pip install -r requirements.txt

ENTRYPOINT ["python3"]

CMD ["main.py"]
  • Minima нода
FROM ubuntu

LABEL creator="SecorD | Let's Node"
LABEL url="https://t.me/letskynode — node Community"

ARG DEBIAN_FRONTEND=noninteractive

ENV TZ=UTC


RUN apt update && \
    apt upgrade -y && \
    apt install wget openjdk-11-jre-headless -y; \
    apt clean; \
    wget -qO minima.jar https://github.com/minima-global/Minima/raw/master/jar/minima.jar

EXPOSE 9001 9002 9003 9004

ENTRYPOINT ["java"]

CMD ["-Xmx1G", "-jar", "minima.jar", "-port", "9001", "-daemon"]

⠀Собрать образ

docker build -t IMAGE_NAME .
  • IMAGE_NAME — название образа, может быть:
    • NAME:TAG — для локального использования;
    • USER/NAME:TAG — для публикации на Docker Hub;
    • Прочее — для других регистров.

⠀При успешном создании образа в конце будет две надписи Successfully

⠀А в списке образов появится базовый из команды FROM и созданный


Публикация в Docker Hub

К содержанию

⠀Для публикации своего образа на Docker Hub сначала необходимо зарегистрироваться по ссылке и подтвердить почту.

⠀После создания аккаунта необходимо авторизоваться в Docker Hub на хосте

docker login

⠀Для публикации образа используется команда

docker push USER/NAME:TAG

⠀Указанный для публикации образ должен быть собран локально.

⠀После этого образ появится во вкладке «Repositories» на Docker Hub


Полезные команды

К содержанию

⠀Авторизоваться в Docker Hub

docker login

⠀Опубликовать образ

docker push NAME

Полезные ссылки

К содержанию

Оф. док. Dockerfile (EN) | Dockerfile | Создание образа (видео)

Создание образа и публикация в приватный регистр (EN)

Методики уменьшения размеров образов Docker

Docker Hub


Благодарности

К содержанию

Команда 1package — написание статьи

Выразить благодарность