Введение в docker

Конспект в доработке

    Источники

    Общие сведения

    Docker - это среда для автоматизации развертывания, разработки, управления приложением в среде виртуализации операционной системы, доставки приложения
    С помощью docker можно упаковать приложение вместе с его окружением и зависимостями в виде контейнера.
    Контейнеры используют схожий с виртуальными машинами уровень изоляции, но не создают сильной нагрузки, что позволяет использовать ресурсы системы более эффективно.
    Docker предоставляет все необходимые инструменты и платформу для управления жизненным циклом контейнеров.
    Разработчики могут писать код локально и делиться своими работами со своими коллегами, используя docker
    Docker можно использовать для переноса своих приложений в тестовую среду для выполнения автоматических и ручных тестов
    Когда разработчики исправляют ошибки в среде разработки, они могут повторно загрузить свое приложение в тестовую среду используя контейнеры
    После завершения тестирования можно просто загрузить контейнер в production среду
    Docker контейнер можно развернуть на обычном ноутбуке, на виртуальном или физическом сервере, в облачной среде или дата центре
    Docker написан на языке GO и использует некоторые возможности ядра linux
    Docker использует технологию namespace для изолирования рабочего пространства, называемого контейнером


    Контейнеры - изолированные процессы для каждого компонента вашего приложения
    Каждый компонент — интерфейсное приложение React, движок Python API и база данных — работает в собственной изолированной среде, полностью изолированной от всего остального на вашем компьютере.

    Преимущества:
    Автономность. В каждом контейнере есть всё необходимое для работы без использования предустановленных зависимостей на хост-компьютере.
    Изолированность. Поскольку контейнеры работают изолированно, они оказывают минимальное влияние на хост и другие контейнеры, повышая безопасность ваших приложений.
    Портативность. Контейнеры могут работать где угодно! Контейнер, работающий на вашем компьютере для разработки, будет работать так же в центре обработки данных или в любом другом месте в облаке!

    Docker daemon ( dockerd ) - прослушивает запросы docker API и управляет объектами docker ( изображения, сети, контейнеры,сервисы, плагины, томы ), кроме этого взаимодействует с другими демонами


    Тома Docker (Docker Volumes) представляют собой наиболее предпочтительный механизм постоянного хранения данных, потребляемых или производимых приложениями.

    В качестве клиентов могут выступать docker run, docker build, docker pull
    Docker client ( docker ) - основной способ взаимодействия с docker. Например docker клиент отправляет команду демону dockerd, который в свою очередь эту команд выполняет

    Docker Desktop - это приложение которое содержит в себе как клиент, так и демон docker, Docker Compose, Docker Content Trust, Kubernetes, позволяет создавать и управлять контейнерами

    Репозиторием Docker (Docker Repository) называют набор образов Docker, обладающих одинаковыми именами и разными тегами. Теги — это идентификаторы образов.

    Docker Swarm — это решение, предназначенное для управления контейнерными развёртываниями (то есть, как говорят, для оркестрации контейнеров).

    Kubernetes — это технология, которая позволяет автоматизировать развёртывание и масштабирование контейнеризированных приложений, а также управление ими.

    Образы — это неизменные шаблоны, которые используются для создания одинаковых контейнеров.
    В образе контейнера Docker содержится образ базовой операционной системы, код приложения, библиотеки, от которого оно зависит. Всё это скомпоновано в виде единой сущности, на основе которой можно создать контейнер.


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

    Файл Dockerfile содержит набор инструкций, следуя которым Docker будет собирать образ контейнера.
    Этот файл содержит описание базового образа, который будет представлять собой исходный слой образа.

    В образ контейнера, поверх базового образа, можно добавлять дополнительные слои. Делается это в соответствии с инструкциями из Dockerfile. Например, если Dockerfile описывает образ, который планируется использовать для решения задач машинного обучения, то в нём могут быть инструкции для включения в промежуточный слой такого образа библиотек NumPy, Pandas и Scikit-learn.
    Для того чтобы запустить контейнер, нам нужен, во-первых, образ контейнера, во-вторых — среда, в которой установлен Docker, способная понять команду вида docker run image_name. Эта команда создаёт контейнер из образа и запускает его.

    ОС Ubuntu. Это — нижний слой образа, его в образ добавляют первым.
    второй слой в виде какой-то внешней библиотеки наподобие NumPy
    код приложения, которое должно запускаться в контейнере, это третий слой

    docker run image_name — создаёт и запускает контейнер

    Движок Docker (Docker Engine) — это клиент-серверное приложение
    Клиент Docker (Docker Client) — это основное средство, которое используют для взаимодействия с Docker.
    Демон Docker (Docker Daemon) — это сервер Docker, который ожидает запросов к API Docker. Демон Docker управляет образами, контейнерами, сетями и томами.

    Тома Docker (Docker Volumes) представляют собой наиболее предпочтительный механизм постоянного хранения данных, потребляемых или производимых приложениями.

    Реестр Docker (Docker Registry) представляет собой удалённую платформу, используемую для хранения образов Docker
    Хаб Docker (Docker Hub) — это самый крупный реестр образов Docker

    Репозиторием Docker (Docker Repository) называют набор образов Docker, обладающих одинаковыми именами и разными тегами. Теги — это идентификаторы образов.
    Обычно в репозиториях хранятся разные версии одних и тех же образов. Например, Python — это имя популярнейшего официального репозитория Docker на хабе Docker. А вот Python:3.7-slim — это версия образа с тегом 3.7-slim в репозитории Python

    Масштабирование

    Сетевые механизмы Docker (Docker Networking) позволяют организовывать связь между контейнерами Docker. Соединённые с помощью сети контейнеры могут выполняться на одном и том же хосте или на разных хостах.


    Docker Compose — это инструмент, который упрощает развёртывание приложений, для работы которых требуется несколько контейнеров Docker. Docker Compose позволяет выполнять команды, описываемые в файле docker-compose.yml. Эти команды можно выполнять столько раз, сколько потребуется. Интерфейс командной строки Docker Compose упрощает взаимодействие с многоконтейнерными приложениями. Этот инструмент устанавливается при установке Docker.

    Сервисы Docker (Docker Services) — это различные части распределённого приложения

    Сервисы — это всего лишь «контейнеры в продакшне». В пределах сервиса выполняется лишь один образ, но сервис определяет то, как именно выполняется образ. В частности, речь идёт о том, какие порты должны использоваться, сколько реплик контейнера должно выполняться для того, чтобы сервис обеспечивал бы необходимую вычислительную мощность, и так далее. Масштабирование сервисов предусматривает изменение количества экземпляров контейнера, в которых работает некая программа, благодаря чему сервису выделяется столько системных ресурсов, сколько ему требуется для решения некоей задачи.

    Сетевая подсистема Docker — среда, которая позволяет организовывать взаимодействие контейнеров.
    Docker Compose — технология, упрощающая работу с многоконтейнерными приложениями.
    Docker Swarm — средство для управления развёртыванием контейнеров.
    Сервисы Docker — контейнеры в продакшне.

    Kubernetes — это технология, которая позволяет автоматизировать развёртывание и масштабирование контейнеризированных приложений, а также управление ими.

    Отличия контейнера и виртуальной машины

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


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

    Образ (images)

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


    Образы контейнеров состоят из слоёв.
    Каждый слой в образе содержит набор изменений файловой системы — добавление, удаление или модификацию
    Первый уровень добавляет базовые команды и менеджер пакетов, такой как apt.
    Второй уровень устанавливает среду выполнения Python и pip для управления зависимостями.
    Третий уровень копирует данные в специальный файл приложения requirements.txt.
    Четвертый уровень устанавливает конкретные зависимости этого приложения.
    Пятый уровень копирует фактический исходный код приложения.
    Это полезно, потому что позволяет повторно использовать слои между изображениями
    Например, представьте, что вы хотите создать ещё одно приложение на Python. Благодаря наложению слоёв вы можете использовать ту же базу Python. Это ускорит сборку и сократит объём памяти и пропускную способность, необходимые для распространения изображений.
    Слои позволяют расширять изображения других пользователей, повторно используя их базовые слои и добавляя только те данные, которые нужны вашему приложению.

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

    Образ (images) - это шаблон доступный только для чтения, содержит инструкцию для создания контейнера
    Образы (images) могут создаваться на основе других images с дополнительными настройками. Например можно создать образ на основе образа Ubuntu
    Можно создавать свои образы или использовать общедоступные образы из реестра
    Например, если вы создаёте приложение на Python, вы можете начать с образа Python и добавить дополнительные слои для установки зависимостей вашего приложения и добавления кода. Это позволит вам сосредоточиться на приложении, а не на самом Python.

    Новые слои образов можно создавать вручную, с помощью команды docker container commit. Редко кто создает образы таким способом, так как обычно используется Dockerfile. Но так вам будет проще понять, как всё работает.

    Чтобы создать свой собственный образ, создается dockerfile который содержит инструкции необходимые для создания и запуска образа
    Существует два важных принципа создания изображений:
    Изображения являются неизменяемыми. После создания изображения его нельзя изменить. Вы можете только создать новое изображение или внести в него изменения.
    Образы контейнеров состоят из слоёв. Каждый слой представляет собой набор изменений в файловой системе, которые добавляют, удаляют или изменяют файлы.

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


    Каждый слой, кроме последнего, находящегося поверх всех остальных, предназначен только для чтения. Dockerfile сообщает системе Docker о том, какие слои и в каком порядке надо добавить в образ.

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

    Инструкции, при сборке образа, обрабатываются сверху вниз.
    FROM ubuntu:18.04
    COPY . /app

    Слои в итоговом образе создают только инструкции FROM, RUN, COPY, и ADD. Другие инструкции что-то настраивают, описывают метаданные, или сообщают Docker о том, что во время выполнения контейнера нужно что-то сделать, например — открыть какой-то порт или выполнить какую-то команду.

    Основные инструкции:
    FROM — задаёт базовый (родительский) образ.
    LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
    ENV — устанавливает постоянные переменные среды.
    RUN — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
    COPY — копирует в контейнер файлы и папки.
    ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
    CMD — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD.
    WORKDIR — задаёт рабочую директорию для следующей инструкции.
    ARG — задаёт переменные для передачи Docker во время сборки образа.
    ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
    EXPOSE — указывает на необходимость открыть порт.
    VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.

    Файл Dockerfile должен начинаться с инструкции FROM, или с инструкции ARG, за которой идёт инструкция FROM
    Ключевое слово FROM сообщает Docker о том, чтобы при сборке образа использовался бы базовый образ, который соответствует предоставленному имени и тегу. Базовый образ, кроме того, ещё называют родительским образом.
    Когда вышеописанный Dockerfile используется на локальной машине для сборки образа в первый раз, Docker загрузит слои, определяемые образом ubuntu. Их можно представить наложенными друг на друга. Каждый следующий слой представляет собой файл, описывающий отличия образа в сравнении с тем его состоянием, в котором он был после добавления в него предыдущего слоя.

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

    Когда образ выполняется, если слой нужно модифицировать средствами контейнера, то соответствующий файл копируется в самый верхний, изменяемый слой

    Рассмотрим следующий пример файла 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, и, по большому счёту, этим его состав и ограничивается
    Чтобы собрать на основе такого образа что-то полезное, создателю образа нужно установить в него необходимые ему пакеты.


    Инструкция LABEL (метка) позволяет добавлять в образ метаданные.
    В случае с рассматриваемым сейчас файлом, она включает в себя контактные сведения создателя образа.

    Инструкция ENV позволяет задавать постоянные переменные среды, которые будут доступны в контейнере во время его выполнения

    Инструкция RUN позволяет создать слой во время сборки образа. После её выполнения в образ добавляется новый слой, его состояние фиксируется.
    Инструкция RUN часто используется для установки в образы дополнительных пакетов.
    Инструкция RUN и схожие с ней инструкции — такие, как CMD и ENTRYPOINT, могут быть использованы либо в exec-форме, либо в shell-форме
    Exec-форма использует синтаксис, напоминающий описание JSON-массива. Например, это может выглядеть так: RUN ["my_executable", "my_first_param1", "my_second_param2"].
    В предыдущем примере мы использовали shell-форму
    Позже в нашем Dockerfile использована exec-форма инструкции RUN, в виде RUN ["mkdir", "/a_directory"] для создания директории. При этом, используя инструкцию в такой форме, нужно помнить о необходимости оформления строк с помощью двойных кавычек, как это принято в формате JSON.

    Инструкция COPY представлена в нашем файле так: COPY . ./app. Она сообщает Docker о том, что нужно взять файлы и папки из локального контекста сборки и добавить их в текущую рабочую директорию образа.

    Инструкция ADD позволяет решать те же задачи, что и COPY, но с ней связана ещё пара вариантов использования. Так, с помощью этой инструкции можно добавлять в контейнер файлы, загруженные из удалённых источников, а также распаковывать локальные .tar-файлы.
    В этом примере инструкция ADD была использована для копирования файла, доступного по URL, в директорию контейнера my_app_directory
    Инструкция CMD предоставляет Docker команду, которую нужно выполнить при запуске контейнера.
    В одном файле Dockerfile может присутствовать лишь одна инструкция CMD. Если в файле есть несколько таких инструкций, система проигнорирует все кроме последней.
    Аргументы командной строки, передаваемые docker run, переопределяют аргументы, предоставленные инструкции CMD в 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

    Инструкция WORKDIR позволяет изменить рабочую директорию контейнера. С этой директорией работают инструкции COPY, ADD, RUN, CMD и ENTRYPOINT, идущие за WORKDIR
    Лучше устанавливать с помощью WORKDIR абсолютные пути к папкам, а не перемещаться по файловой системе с помощью команд cd в Dockerfile.
    Инструкция WORKDIR автоматически создаёт директорию в том случае, если она не существует.


    Инструкция ARG позволяет задать переменную, значение которой можно передать из командной строки в образ во время его сборки. Значение для переменной по умолчанию можно представить в Dockerfile. Например: ARG my_var=my_default_value
    В отличие от ENV-переменных, ARG-переменные недоступны во время выполнения контейнера. Однако ARG-переменные можно использовать для задания значений по умолчанию для ENV-переменных из командной строки в процессе сборки образа. А ENV-переменные уже будут доступны в контейнере во время его выполнения

    Инструкция ENTRYPOINT позволяет задавать команду с аргументами, которая должна выполняться при запуске контейнера. Она похожа на команду CMD, но параметры, задаваемые в ENTRYPOINT, не перезаписываются в том случае, если контейнер запускают с параметрами командной строки.
    Вместо этого аргументы командной строки, передаваемые в конструкции вида docker run my_image_name, добавляются к аргументам, задаваемым инструкцией ENTRYPOINT
    Например, после выполнения команды вида docker run my_image bash аргумент bash добавится в конец списка аргументов, заданных с помощью ENTRYPOINT
    Если при каждом запуске контейнера нужно выполнять одну и ту же команду — используйте ENTRYPOINT
    Если контейнер будет использоваться в роли приложения — используйте ENTRYPOINT
    Если вы знаете, что при запуске контейнера вам понадобится передавать ему аргументы, которые могут перезаписывать аргументы, указанные в Dockerfile, используйте CMD
    В нашем примере использование инструкции ENTRYPOINT ["python", "my_script.py", "my_var"] приводит к тому, что контейнер, при запуске, запускает Python-скрипт my_script.py с аргументом my_var
    В Dockerfile переменной my_var, до её использования, назначено значение по умолчанию с помощью ARG.

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

    Инструкция VOLUME позволяет указать место, которое контейнер будет использовать для постоянного хранения файлов и для работы с такими файлами

    Кэширование

    Благодаря механизму кэширования, ускоряется сборка образов.
    При сборке образа Docker проходится по инструкциям файла Dockerfile, выполняя их по порядку. В процессе анализа инструкций Docker проверяет собственный кэш на наличие в нём образов, представляющих собой то, что получается на промежуточных этапах сборки других образов.
    Если подобные образы удаётся найти, то система может ими воспользоваться, не тратя время на их повторное создание.
    В результате, если в ходе выполнения инструкций из Dockerfile оказывается, что базовый образ имеется в кэше, то используется именно этот образ из кэша. Это называется «попаданием кэша»


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

    В Dockerfile, описывающем многоступенчатую сборку образа, используется несколько инструкций FROM. Создатель такого образа может настроить выборочное копирование файлов, называемых артефактами сборки, из одной ступени сборки в другую ступень. При этом появляется возможность избавиться от всего того, что в готовом образе не понадобится. Благодаря этому методу можно уменьшить размер готового образа.
    Вот как работает каждая инструкция FROM:
    Она начинает новый шаг сборки.
    Она не зависит от того, что было создано на предыдущем шаге сборки.
    Она может использовать базовый образ, отличающийся от того, который применялся на предыдущем шаге.
    Вот модифицированный пример файла Dockerfile из документации Docker, описывающего многоступенчатую сборку

    FROM golang:1.7.3 AS build WORKDIR /go/src/github.com/alexellis/href-counter/ RUN go get -d -v golang.org/x/net/html COPY app.go . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=build /go/src/github.com/alexellis/href-counter/app . CMD ["./app"]

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

    Реестры изображений

    Docker registries - docker реестр хранит в себе образы docker.


    Docker Hub - общедостпный реестр, по умолчанию docker ищет образы именно там
    При запуске команд: docker run или docker pull, образы извлекаются из настроенного реестра или помещаются в реестр, есл используется команду docker push
    Docker Hub — это глобальная платформа по умолчанию для хранения и распространения образов

    Контейнер

    Containers - это доступный для запуска экземпляр образа, после запуска это изолированный процесс
    Запущенный контейнер имеет изолированную файловую систему
    Эта изолированная файловая система предоставляется образом контейнера, и образ контейнера должен содержать все необходимое для запуска приложения - все зависимости, конфигурации, скрипты, двоичные файлы и т.д.
    Контейнер - это самодостаточная операционная система, в которой имеется только самое необходимое и код приложения.
    Контейнер можно создать, запустить, остановить, или удалить используя docker API или CLI
    Контейнер можно подключить к одной или нескольким сетям, можно подключить к контейнеру хранилище или создать новый контейнер на основа образа существующего контейнера
    Образы Docker являются результатом процесса их сборки, а контейнеры Docker — это выполняющиеся образы
    Можно контролировать уровень изоляции для контейнеров относительно других контейнеров, базовой системы, хранилища, сети
    Контейнер определяется его образом и параметрами конфигурации
    При запуске контейнера docker создает набор пространств имен для этого контейнера, эти пространства имен обеспечивают определенный уровень изоляции

    Принцип работы

    Если нет локального образа, он извлекается из реестра
    Создается docker контейнер, как если бы он создавался вручную
    Далее docker выделяет файловую систему для чтения и записи
    Далее docker создает сетевой интерфейс и присваевает ip-адрес для контейнера, по умолчанию контейнер может подключаться к внешней сети используя сетевое подключения хоста на котором установлен docker
    Docker запускает созданный контейнер, возможно в интерактивном режиме

    Требования к установке

    Docker запускает VM поэтому должен быть включен модуль kvm-intel или kmv-amd в зависимости от модели процессора

    #Проверить kvm на Linux можно следующей командой lsmod | grep kvm #Проверить разрешения kmv для системного пользователя ls -la /dev/kvm #При необходимости можно добавить пользователя в группу kvm, после чего выйти и войти в систему sudo usermod -aG kvm $USER
    Удаление Docker

    #Полное удаление sudo apt remove docker-desktop rm -r $HOME/.docker/desktop sudo rm /usr/local/bin/com.docker.cli sudo apt purge docker-desktop rm ~/.config/systemd/user/docker-desktop.service rm ~/.local/share/systemd/user/docker-desktop.service #Для среды рабочего стола Gnome необходимы расширения https://extensions.gnome.org/extension/615/appindicator-support/ #Если среда отличается от GNOME тогда gnome-terminal sudo apt install gnome-terminal
    Установка

    Установить docker engine можно в комплекте с Docker Desktop, из apt, вручную или с помощью скрипта. Перед установкой необходимо удалить старые пакеты и зависимости, настроить и обновить репозитории, добавить официальный gpg-ключ
    Изображения, контейнеры, тома и сети, хранящиеся в /var/lib/docker/, не удаляются автоматически при удалении Docker.
    Docker Engine поставляется в комплекте с Docker Desktop для Linux.


    Докер-файл и создание контейнера

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


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

    cd /home/user/aplication touch Dockerfile vim Dockerfile #Содержимое файла dockerfile # syntax=docker/dockerfile:1 FROM node:18-alpine WORKDIR /app COPY . . RUN yarn install --production CMD ["node", "src/index.js"] EXPOSE 3000 #Создать образ docker build -t getting-started .

    Слои в итоговом образе создают только инструкции FROM, RUN, COPY, и ADD


    FROM — задаёт базовый (родительский) образ.
    Файл Dockerfile должен начинаться с инструкции FROM, или с инструкции ARG, за которой идёт инструкция FROM
    Ключевое слово FROM сообщает Docker о том, чтобы при сборке образа использовался бы базовый образ, который соответствует предоставленному имени и тегу

    FROM alpine:3.21

    alpine — это название официального репозитория Docker, предоставляющего базовую версию популярной ОС семейства Linux, которая называется Alpine
    Тег :3.21 (версия ОС) уточняет, какой именно базовый образ нам нужен
    В данной инструкции docker загрузит слои, используемые образом alpine
    Каждый следующий слой представляет собой файл, описывающий отличия образа в сравнении с тем его состоянием, в котором он был после добавления в него предыдущего слоя.
    Создавать новый образ есть смысл когда вы не можете найти подходящий для вашей задачи образ на hub.docker.com. Созданные образы можно также загружать на hub.docker.com и делать их доступными для других разработчиков.


    RUN — выполняет команду и создаёт слой образа во время сборки. Используется для установки в контейнер пакетов.

    RUN apk update && apk upgrade && apk add bash

    Инструкция RUN и схожие с ней инструкции — такие, как CMD и ENTRYPOINT, могут быть использованы либо в exec-форме, либо в shell-форме. Exec-форма использует синтаксис, напоминающий описание JSON-массива. Например, это может выглядеть так: RUN ["shell_command", "param1", "param2"].

    RUN ["mkdir", "/folder"]


    COPY — копирует в контейнер файлы и папки.
    COPY - сообщает Docker о том, что нужно взять файлы и папки из локального контекста сборки и добавить их в текущую рабочую директорию образа.

    ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
    Инструкция ADD позволяет решать те же задачи, что и COPY, но с ней связана ещё пара вариантов использования. Так, с помощью этой инструкции можно добавлять в контейнер файлы, загруженные из удалённых источников, а также распаковывать локальные .tar-файлы.

    CMD определяет команду, которая должна выполняться при запуске образа, аргументы переопределяются в командной строке пользователем
    Результаты выполнения этой команды не добавляются в образ во время его сборки.
    В одном файле Dockerfile может присутствовать лишь одна инструкция CMD
    Аргументы командной строки, передаваемые docker run, переопределяют аргументы, предоставленные инструкции CMD в Dockerfile.

    В образ контейнера, поверх базового образа, можно добавлять дополнительные слои. Делается это в соответствии с инструкциями из Dockerfile
    Docker загрузил недостающие образы помимо того что создал сам образ
    yarn в dockerfile использовался для установки зависимостей
    Флаг -t определяет короткое название образа
    . сообщает Docker в какой директории искать dockerfile
    Для запуска созданного контейнера используется команда docker run

    #Создание и запуск контейнера из образа docker run -dp 127.0.0.1:3000:3000 getting-started

    Флаг -d ( --detach ) запускает контейнер в фоновом режиме
    Флаг -p ( --publish ) сопоставляет порт контейнера и хоста
    Чтобы посмотреть используемые и запущенные контейнеры, можно использовать командную строку или интерфейс docker desktop #Посмотреть запущенные контейнеры docker ps

    LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.

    LABEL maintainer="chich87@gmail.com"


    ENV — устанавливает постоянные переменные среды.

    WORKDIR — задаёт рабочую директорию для следующей инструкции.
    WORKDIR позволяет изменить рабочую директорию контейнера. С этой директорией работают инструкции COPY, ADD, RUN, CMD и ENTRYPOINT, идущие за WORKDIR
    Лучше устанавливать с помощью WORKDIR абсолютные пути к папкам, а не перемещаться по файловой системе с помощью команд cd в Dockerfile.
    Инструкция WORKDIR автоматически создаёт директорию в том случае, если она не существует.
    Можно использовать несколько инструкций WORKDIR. Каждая из них меняет текущую рабочую директорию.

    ARG — задаёт переменные для передачи Docker во время сборки образа.
    Во время сборки образа не всегда удобно, а иногда даже опасно, описывать все параметры внутри Dockerfile
    ARG позволяет задать переменную, значение которой можно передать из командной строки в образ во время его сборки. Значение для переменной по умолчанию можно представить в Dockerfile. Например: ARG var1=test
    В отличие от ENV-переменных, ARG-переменные недоступны во время выполнения контейнера.

    ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера, аргументы не переопределяются в командной строке пользователем
    Она похожа на команду CMD, но параметры, задаваемые в ENTRYPOINT, не перезаписываются в том случае, если контейнер запускают с параметрами командной строки.
    Например, после выполнения команды вида docker run my_image bash аргумент bash добавится в конец списка аргументов, заданных с помощью ENTRYPOINT.
    Если при каждом запуске контейнера нужно выполнять одну и ту же команду — используйте ENTRYPOINT.
    Если вы знаете, что при запуске контейнера вам понадобится передавать ему аргументы, которые могут перезаписывать аргументы, указанные в Dockerfile, используйте CMD.

    EXPOSE — указывает на необходимость открыть порт.
    EXPOSE указывает на то, какие порты планируется открыть для того, чтобы через них можно было бы связаться с работающим контейнером.
    Например Запись EXPOSE 8080 означает, что на компьютере, на котором запущен Docker, веб-приложение будет доступно по адресу http://localhost:8080
    Для того чтобы открыть порт (или порты) и настроить перенаправление портов, нужно выполнить команду docker run с ключом -p. Если использовать ключ в виде -P (с заглавной буквой P), то открыты будут все порты, указанные в инструкции EXPOSE.

    VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.
    Команда VOLUME используется для организации доступа вашего контейнера к директории на хосте (тоже самое, что и монтирование директории), команда определяет где контейнер будет хранить постоянные данные и получать к ним доступ:

    VOLUME ["/opt/project"]


    USER задаёзапуск приложения от имени пользователя

    Документация: https://docs.docker.com/reference/dockerfile/#add

    Многоступенчатая сборка образа

    С точки зрения оптимизации сборки, уменьшения размера образа и ускорения приложения, образ можно собирать в несколько этапов. Например, с помощью платформы Node.js произвести сборку веб-приложения на первом этапе, а на втором — запустить готовый бандл с помощью веб-сервера.


    Источник: https://hmarketing.ru/blog/docker/fayl-dockerfile/

    # Сборка проекта на платформе Node.js FROM node:lts-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # Запуск приложения на сервере FROM nginx:stable-alpine as production-stage COPY --from=build-stage /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]

    Имя промежуточного образа build-stage служит для передачи результата работы первой стадии сборки.

    Использование нескольких Dockerfile

    Иногда возникает необходимость использования нескольких вариантов сборок в одном проекте. В этом случае не обойтись без нескольких файлов с инструкциями. При сборке можно указать другое имя для файла конфигурации или относительный путь внутри PATH, нужно использовать флаг -f

    docker build -f containers/dockerfile1 .

    Точно так же можно указать относительный путь для проекта или репозитория по некоторому URL. Например, Docker может скачать не только репозиторий GitHub, но и произвольный архив с проектом, распаковать его и собрать образ (поддерживаются архивы форматов bzip2, gzip, xz):

    docker build -f ctx/Dockerfile http://server/ctx.tar.gz


    Источник: https://hmarketing.ru/blog/docker/fayl-dockerfile/

    Файл .dockerignore

    Эти файлы похожи на файлы .gitignore. Они содержат список файлов и папок, в виде имён или шаблонов, которые Docker должен игнорировать в ходе сборки образа.
    При запуске команды docker build, инициирующей сборку образа, Docker проверяет папку на наличие в ней файла .dockerignore. Если такой файл найти удаётся, тогда этот файл разбирается, при этом при определении списка файлов, которые нужно игнорировать, используются правила функции Match() из пакета filepath Go и некоторые собственные правила Docker.


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

    Для того чтобы выяснить примерный размер выполняющегося контейнера, можно использовать команду вида docker container ls -s.
    Команда docker image ls выводит размеры образов.
    Узнать размеры промежуточных образов, из которых собран некий образ, можно с помощью команды docker image history my_image:my_tag.
    Команда docker image inspect my_image:tag позволяет узнать подробные сведения об образе, в том числе — размер каждого его слоя. Слои немного отличаются от промежуточных образов, из которых состоит готовый образ, но, в большинстве случаев их можно рассматривать как одинаковые сущности. Вот хороший материал, который посвящён подробностям внутреннего устройства образов Docker.
    Для того чтобы исследовать содержимое контейнеров можно установить пакет dive.

    Для того чтобы собирать как можно более компактные образы, пользуйтесь базовыми образами, основанными на Alpine Linux
    Кроме того, объединяйте в одну инструкцию команды установки пакетов. Перечисляйте пакеты в алфавитном порядке на нескольких строках, разделяя список символами \. Например, это может выглядеть так

    RUN apt-get update && apt-get install -y \ package-one \ package-two \ package-three && rm -rf /var/lib/apt/lists/*

    Этот метод позволяет сократить число слоёв, которые должны быть добавлены в образ, и помогает поддерживать код файла в приличном виде.


    Команды

    docker container run my_app - команда для создания и запуска контейнера с именем my_app
    В версии 1.12 использовалась команда вида docker create, а в версии 1.13 стала доступна команда docker container create.


    Схема команд для управления контейнерами выглядит так:
    docker container my_command
    create — создание контейнера из образа.
    start — запуск существующего контейнера.
    run — создание контейнера и его запуск.
    ls — вывод списка работающих контейнеров.
    inspect — вывод подробной информации о контейнере.
    logs — вывод логов.
    stop — остановка работающего контейнера с отправкой главному процессу контейнера сигнала SIGTERM, и, через некоторое время, SIGKILL.
    kill — остановка работающего контейнера с отправкой главному процессу контейнера сигнала SIGKILL.
    rm — удаление остановленного контейнера.

    Для управления образами используются команды, которые выглядят так:
    docker image my_command
    build — сборка образа. push — отправка образа в удалённый реестр. ls — вывод списка образов. history — вывод сведений о слоях образа. inspect — вывод подробной информации об образе, в том числе — сведений о слоях. rm — удаление образа.

    docker version — вывод сведений о версиях клиента и сервера Docker. docker login — вход в реестр Docker. docker system prune — удаление неиспользуемых контейнеров, сетей и образов, которым не назначено имя и тег.
    На начальном этапе работы с контейнерами используются команды create, start и run. Они применяются, соответственно, для создания контейнера, для его запуска, и для его создания и запуска.

    Команда для создания контейнера из образа:

    docker container create my_repo/my_image:my_tag

    Команда create принимает множество флагов. Например, её можно записать в таком виде:

    docker container create -a STDIN my_image

    Флаг -a представляет собой краткую форму флага --attach. Этот флаг позволяет подключить контейнер к STDIN, STDOUT или STDERR
    После того, как контейнер создан, его можно запустить следующей командой:

    docker container start my_container

    Которая позволяет создать и запустить контейнер:

    docker container run my_image

    Рассмотрим некоторые аргументы на примере такой конструкции:

    docker container run -i -t -p 1000:8000 --rm my_image

    Флаг -i — это сокращение для --interactive. Благодаря этому флагу поток STDIN поддерживается в открытом состоянии даже если контейнер к STDIN не подключён.
    Флаг -t — это сокращение для --tty. Благодаря этому флагу выделяется псевдотерминал, который соединяет используемый терминал с потоками STDIN и STDOUT контейнера
    Для того чтобы получить возможность взаимодействия с контейнером через терминал нужно совместно использовать флаги -i и -t.
    Флаг -p представляет собой сокращение для --port. Порт — это интерфейс, благодаря которому контейнер взаимодействует с внешним миром. Конструкция 1000:8000 перенаправляет порт Docker 8000 на порт 1000 компьютера, на котором выполняется контейнер. Если в контейнере работает некое приложение, способное выводить что-то в браузер, то, для того, чтобы к нему обратиться, в нашем случае можно перейти в браузере по адресу localhost:1000.
    Флаг --rm автоматически удаляет контейнер после того, как его выполнение завершится.


    Флаг -d — это сокращение для --detach. Эта команда запускает контейнер в фоновом режиме. Это позволяет использовать терминал, из которого запущен контейнер, для выполнения других команд во время работы контейнера

    docker container run -d my_image

    Вывод списка контейнеров
    Ключ -a этой команды — это сокращение для --all. Благодаря использованию этого ключа можно вывести сведения обо всех контейнерах, а не только о выполняющихся.
    Ключ -s — это сокращение для --size. Он позволяет вывести размеры контейнеров.

    docker container ls # docker container ls -a -s

    команда, которая выводит подробные сведения о контейнере:

    docker container inspect my_container #команда, выводящая логи контейнера: docker container logs my_container

    Иногда работающий контейнер надо остановить. Для этого используется такая команда:

    docker container stop my_container

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

    docker container kill my_container

    Вот команда, которая позволяет быстро остановить все работающие контейнеры:

    docker container kill $(docker ps -q)  #Для удаления остановленного контейнера можно воспользоваться такой командой: docker container rm my_container #удалить все контейнеры, которые на момент вызова этой команды не выполняются: docker container rm $(docker ps -a -q)

    docker image build -t my_repo/my_image:my_tag
    Флаг -t — это сокращение для --tag. Он указывает Docker на то, что создаваемому образу надо назначить предоставленный в команде тег. В данном случае это my_tag.
    #Отправка образа в реестр #Вход в docker hub docker login docker image push my_repo/my_image:my_tag

    Следующая команда позволяет удалить неиспользуемые контейнеры, сети и образы, которым не назначено имя и тег:

    docker system prune docker system prune -a --volumes

    Ключ -a — сокращение для --all, позволяет удалить неиспользуемые образы, а не только те, которым не назначено имя и тег.
    Ключ --volumes позволяет удалить неиспользуемые тома.

    #Сборка образа docker image build -t my_repo/my_image:my_tag
    Исследование образов

    Вот команда, которая выводит список образов, выводя, в том числе, и сведения об их размере:

    docker image ls

    Следующая команда позволяет вывести сведения о промежуточных образах, входящих в состав образа, в частности — данные об их размерах и о том, как они были созданы:

    docker image history my_image

    Вот команда, которая выводит подробные сведения об образе, в том числе — данные о слоях, из которых состоит образ:

    docker image inspect my_image
    Обновление, удаление контейнера

    После изменения файла приложения, создается новый контейнер

    #Посмотреть CONTAINER ID работающих контейнеров docker ps #Остановить работающий контейнер docker stop 48279e93089b #Удалить остановленный контейнер docker rm 48279e93089b #Можно остановить и удалить контейнер одной командой, используя флаг -f ( force ) docker rm -f 84b9d873f634
    Удаление образов

    Вот команда, которая позволяет удалить указанный образ:

    docker image rm my_image

    Если образ хранится в удалённом репозитории, он оттуда удалён не будет.
    Вот команда, которая позволяет удалить все локальные образы:

    docker image rm $(docker images -a -q) 
    Добавления приложения в Docker Hub

    Сначала необходимо создать репозиторий на Docker Hub
    Для доступа к личному репозиторию из консоли необходимо инициализировать pass с помощью ключа, подробнее об этом здесь

    # Авторизоваться через консоль docker login -u chich87 #Переименовать образ в соответствии с логином аккаунта в Docker Hub docker tag getting-started chich87/getting-started #Теперь можно отправить данные в репозиторий docker push chich87/getting-started
    Запуск контейнера из образа Ubuntu и выполнение команд

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

    #Запуск контейнера ubuntu и выполнение в нем команды через bash docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null" #Получить идентификатор созданного контейнера docker ps #Запустить команду в запущенном контейнере с помощью команды docker exec docker exec e36231027ac8 cat /data.txt #Теперь запустим контейнер из того же образа и убедимся, что созданный файл не доступен, так как был создан новый контейнер docker run -it ubuntu ls / #Удалить первый контейнер docker rm -f e36231027ac8
    Хранение данных

    Данные в Docker могут храниться либо временно, либо постоянно


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

    Volumes

    Volumes предоставляют возможность подключать в файловую систему контейнера, которые хранится на хосте, чем то напоминают монтирование
    Если монтируется каталог в контейнере, изменения в контейнере фиксируются в каталоге docker на хосте
    Если подключить этот же каталог при запуске нового контейнера, будут отображаться раннее добавленные изменения
    Volumes более безопасно распределять между несколькими контейнерами
    Volumes используются, когда приложению требуется высокопроизводительный ввод-вывод.
    Тома — не лучший выбор, если вам нужен доступ к файлам с хоста, так как тома полностью управляются Docker.
    Тома часто являются лучшим выбором, чем запись данных непосредственно в контейнер, поскольку том не увеличивает размер используемых контейнеров
    Эта дополнительная абстракция снижает производительность по сравнению с использованием томов, которые записывают данные непосредственно в файловую систему хоста


    Если ваш контейнер генерирует непостоянные данные о состоянии, рассмотрите возможность использования монтирования tmpfs

    Использование тома гарантирует сохранение данных, даже если использующий его контейнер будет удалён.
    Один и тот же том может быть подключен к нескольким контейнерам одновременно. Если ни один из запущенных контейнеров не использует том, он по-прежнему доступен для Docker и не удаляется автоматически. Вы можете удалить неиспользуемые тома с помощью docker volume prune

    Если вы монтируете непустой том в каталог в контейнере, в котором уже есть файлы или каталоги, то при монтировании уже существующие файлы будут скрыты, это похоже на обычное монтирование в linux

    #Создание volume docker volume create todo-db #Запуск контейнера с использованием опции mount docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started #Посмотреть где хранится volume docker volume inspect todo-db

    Документация по использованию Volumes довольно обширная, чтобы не дублировать сюда, проще заглянуть в официальную документацию


    Источник: https://docs.docker.com/engine/storage/volumes/

    Создание томов

    Тома можно создавать средствами Docker или с помощью запросов к API.
    Вот инструкция в Dockerfile, которая позволяет создать том при запуске контейнера.
    VOLUME /my_volume
    При использовании подобной инструкции Docker, после создания контейнера, создаст том, содержащий данные
    Если вы создаёте том с использованием Dockerfile, это не освобождает вас от необходимости указать точку монтирования тома.
    Создавать тома в Dockerfile можно и используя формат JSON.


    Создание тома из командной строки

    docker volume create —-name my_volume # список томов Docker docker volume ls #Исследовать конкретный том можно так: docker volume inspect my_volume #Удалить том можно так: docker volume rm my_volume #чтобы удалить все тома, которые не используются контейнерами docker volume prune

    Если том связан с каким-либо контейнером, такой том нельзя удалить до тех пор, пока не удалён соответствующий контейнер. При этом, даже если контейнер удалён, Docker не всегда это понимает. Если это случилось — можете воспользоваться следующей командой:

    docker system prune

    Она предназначена для очистки ресурсов Docker. После выполнения этой команды у вас должна появиться возможность удалить тома, статус которых до этого определялся неправильно.


    Флаги --mount и --volume.
    Для работы с томами вам, при вызове команды docker, часто придётся пользоваться флагами. Например, для того чтобы создать том во время создания контейнера можно воспользоваться такой конструкцией:

    docker container run --mount source=my_volume, target=/container/path/for/volume my_image

    Надо отметить, что при использовании флага --mount увеличивается объём дополнительных данных, которые приходится указывать в команде, но, по нескольким причинам, лучше использовать именно этот флаг, а не --volume. Флаг --mount — это единственный механизм, который позволяет работать с сервисами или указывать параметры драйвера тома


    В существующих примерах команд, направленных на работу с данными в Docker, вы можете встретить множество примеров употребления флага -v. Пытаясь адаптировать эти команды для себя, учитывайте то, что флаги --mount и --volume используют различные форматы параметров. То есть, нельзя просто заменить -v на --mount и получить рабочую команду.
    Главное различие между --mount и --volume заключается в том, что при использовании флага --volume все параметры собирают вместе, в одном поле, а при использовании --mount параметры разделяются.
    При работе с --mount параметры представлены как пары вида ключ-значение, а именно, это выглядит как key=value. Эти пары разделяют запятыми. Вот часто используемые параметры --mount:
    type — тип монтирования. Значением для соответствующего ключа могут выступать bind, volume или tmpfs. Мы тут говорим о томах, то есть — нас интересует значение volume.
    source — источник монтирования. Для именованных томов это — имя тома. Для неименованных томов этот ключ не указывают. Он может быть сокращён до src.
    destination — путь, к которому файл или папка монтируется в контейнере. Этот ключ может быть сокращён до dst или target.
    readonly — монтирует том, который предназначен только для чтения. Использовать этот ключ необязательно, значение ему не назначают.

    docker run --mount type=volume,source=volume_name,destination=/path/in/container,readonly my_image

    Использование bind mounts

    Bind mount тип монтирования, который позволяет совместно использовать каталог из файловой системы хоста в контейнере
    Контейнер сразу видит изменения после сохранения исходного кода в каталоге хоста
    Это означает, что процессы контейнера могут отслеживать изменения в файлах каталога хоста и реагировать на них


    bind mounts может применяться:
    Для обмена исходным кодом или результатом сборки между средой разработки нахосте docker и контейнером
    Если вы хотите создать или сгенерировать файлы в контейнере и сохранить их в файловой системе хоста.
    Совместное использование файлов конфигурации с хост-компьютера с контейнерами

    Если вы привязываете файл или каталог для монтирования к каталогу в контейнере, в котором существуют файлы или каталоги, то уже существующие файлы скрываются за монтированием, это похоже на использование монтирования в linux

    Подробная документация: https://docs.docker.com/engine/storage/bind-mounts/

    #Перейти в директорию приложения cd /app/getting-started-app #Запустить docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash

    Параметр --mount указывает создать bind mount, где src= это рабочий каталог на хосте ( в данном случае каталог приложения getting-started-app )
    target=/src - это директория на хосте в контейнере ubuntu
    После запуска команды Docker запускает интерактивный сеанс bash в файловой системе контейнера

    #Далее можно перейти в каталог и убедиться в наличии привязанного каталога cd src; ls

    В следующем примере демонстрируется монтирование каталога хоста, установка зависимостей и запуск nodemon для отслеживания изменений в монтированном каталоге

    docker run -dp 127.0.0.1:3000:3000 \ -w /app --mount type=bind,src="$(pwd)",target=/app \ node:18-alpine \ sh -c "yarn install && yarn run dev"

    -dp 127.0.0.1:3000:3000 - запуск в фоновом режиме
    -w каталог из которого будет выполняться команда
    --mount type=bind,src="$(pwd)",target=/app - монтировать текущий каталог хоста в директорию контейнера
    node:18-alpine - образ который будет использоваться
    sh -c "yarn install && yarn run dev" - устанавливает и запускает сервер разработки
    Каждый раз, когда вносятся изменения в каталоге хоста, процесс nodemon автоматически перезапускает приложение внутри контейнера.

    #Просмотр логов контейнера docker logs -f 6892738e5194

    После завершения изменений в каталоге можно заново пересобрать образ используя следующую команду:

    docker build -t getting-started .

    Смысл такого подхода в том, что можно изменять код приложения и просматривать его работу в процессе работы приложения

    Монтирование tmpfs

    В отличие от томов и привязных монтирований, монтирование tmpfs является временным и сохраняется только в памяти хоста. Когда контейнер останавливается, монтирование tmpfs удаляется, и записанные в нём файлы не сохраняются.
    Монтирование tmpfs лучше всего подходит для случаев, когда вы не хотите сохранять данные ни на хост-компьютере, ни в контейнере. Это может быть сделано из соображений безопасности или для защиты производительности контейнера, когда вашему приложению необходимо записать большой объём непостоянных данных.


    Монтирование tmpfs в Docker напрямую связано с tmpfs в ядре Linux. Таким образом, временные данные могут записываться в файл подкачки и сохраняться в файловой системе.
    Если вы создадите монтирование tmpfs в каталоге контейнера, в котором существуют файлы или каталоги, то уже существующие файлы будут скрыты монтированием. Это похоже на то, как если бы вы сохраняли файлы в /mnt на хосте Linux

    Подробная документация: https://docs.docker.com/engine/storage/tmpfs/

    Storage drivers

    Storage drivers - довольно обширная тема
    Документация: https://docs.docker.com/engine/storage/drivers/

    хранилище контейнерных изображений с движком Docker Engine

    Документация: https://docs.docker.com/engine/storage/containerd/

    Создание сети и подключение других контейнеров

    Каждый контейнер должен делать хорошо что то одно. Благодаря такому подходу, каждый контейнер можно обновлять изолированно.
    Контейнеры общаются между собой с помощью сети
    Сеть можно назначить при запуске контейнера или подключить запущенный контейнер к сети
    Каждый контейнер имеет свой собственный ip адрес
    Контейнер видит только сетевой интерфейс с IP-адресом, шлюзом, таблицей маршрутизации, службами DNS и другими сетевыми параметрами. То есть, если только контейнер не использует none сетевой драйвер.
    Можно создавать собственные пользовательские сети и подключать несколько контейнеров к одной сети.
    После подключения к пользовательской сети контейнеры могут взаимодействовать друг с другом с помощью IP-адресов или имён контейнеров.


    #Создать сеть с помощью сетевого драйвера bridge docker network create -d bridge my-net #Запустить контейнер в созданной сети docker run --network=my-net -itd --name=container3 busybox
    Сетевые драйверы

    Следующие сетевые драйверы доступны по умолчанию и обеспечивают основные сетевые функции:
    bridge Сетевой драйвер по умолчанию.
    host Удалите сетевую изоляцию между контейнером и хостом Docker.
    none Полностью изолируйте контейнер от хоста и других контейнеров.
    overlay Оверлейные сети соединяют несколько демонов Docker вместе.
    ipvlan Сети IPvlan обеспечивают полный контроль как над адресацией IPv4, так и IPv6.
    macvlan Назначьте MAC-адрес контейнеру.


    Контейнер может быть подключен к нескольким сетям.
    Например, внешний контейнер может быть подключён к мостовой сети с внешним доступом и к сети --internal для связи с контейнерами, в которых работают внутренние сервисы, не требующие внешнего доступа к сети.
    Чтобы Docker выбирал конкретный шлюз по умолчанию при создании контейнера или подключении к новой сети, установите приоритет шлюза. См. параметр gw-priority для команд docker run и docker network connect.

    Контейнерные сети

    Помимо пользовательских сетей, вы можете напрямую подключить контейнер к сетевому стеку другого контейнера, используя формат флага --network container:.
    Некоторые флаги не поддерживаются для контейнеров, использующих сетевой режим container:
    --add-host
    --hostname
    --dns
    --dns-search
    --dns-option
    --mac-address
    --publish
    --publish-all
    --expose

    Опубликованные порты

    По умолчанию при создании или запуске контейнера с помощью docker create или docker run контейнеры в мостовых сетях не открывают порты для внешнего мира. Используйте флаг --publish или -p для того, чтобы сделать порт доступным для служб за пределами мостовой сети.
    Это создает правило брандмауэра на хосте, сопоставляя порт контейнера с портом на хосте Docker для внешнего мира.


    Дополнительный источник: https://docs.docker.com/engine/network/packet-filtering-firewalls/

    IP-адрес и имя хоста

    При создании сети распределение IPv4-адресов включено по умолчанию, его можно отключить с помощью --ipv4=false

    Службы DNS

    По умолчанию контейнеры используют те же DNS-серверы, что и хост, но вы можете изменить это с помощью --dns.
    По умолчанию контейнеры наследуют настройки DNS, определенные в /etc/resolv.conf файле конфигурации


    Источник:

    Пользовательские хосты

    В контейнере будут строки в /etc/hosts , которые определяют имя хоста самого контейнера, а также localhost и некоторые другие распространённые параметры. Пользовательские хосты, определённые в /etc/hosts на хост-компьютере, не наследуются контейнерами

    #Создать сеть docker network create todo-app # Старт контейнера MySql docker run -d \ --network todo-app --network-alias mysql \ -v todo-mysql-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=todos \ mysql:8.0 #Выполнить команду в созданном контейнере mysq docker exec -it 9b00fa3f5f7f mysql -u root -p

    -e - создание нескольких переменных окружений для инициализации базы данных
    --network-alias - сетевой псевдоним
    -v todo-mysql-data:/var/lib/mysql \ - том todo-mesql-data который был подключен в директорию /var/lib/mysql, в нем mysql хранит свои данные, данный том создается автоматически
    В следующем примере используется nicolaka/netshoot - образ с инструментами для отладки сети.

    #Запуск контейнера с nicolaka/netshoot docker run -it --network todo-app nicolaka/netshoot #Поиск ip по ранее указанному псевдониму mysql dig mysql #Переход в директорию приложения cd app/getting-started-app #Теперь можно запустить приложение и указать переменные окружения для подключения к контейнеру mysql #При запуске указывается используемая сеть, подключается каталог app из текущей директории #Указывается образ node который будет использоваться, устанавливается и запускается сервер разработки docker run -dp 127.0.0.1:3000:3000 \ -w /app -v "$(pwd):/app" \ --network todo-app \ -e MYSQL_HOST=mysql \ -e MYSQL_USER=root \ -e MYSQL_PASSWORD=secret \ -e MYSQL_DB=todos \ node:18-alpine \ sh -c "yarn install && yarn run dev" #Подключиться к базе данных и убедиться, что элементы записались в базу docker exec -it 9b00fa3f5f7f mysql -p todos #Вывод данных в оболочке mysql select * from todo_items;
    Docker Compose

    Docker Compose для запуска и остановки многоконтейнерного приложения.
    Вы можете использовать несколько команд docker run для запуска нескольких контейнеров. Но вскоре вы поймёте, что вам нужно будет управлять сетями, всеми флагами, необходимыми для подключения контейнеров к этим сетям, и многим другим. А когда вы закончите, очистка будет немного сложнее.
    С помощью Docker Compose вы можете определить все свои контейнеры и их конфигурации в одном файле YAML
    С помощью compose создается yaml файл для определения необходимых сервисов и команд


    Источник: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-docker-compose/

    #Перейти в директорию приложения cd app/getting-started-app #Создать файл compose.yaml vim compose.yaml #В первых строках определяется имя образа который будет использоваться как часть приложения services: app: image: node:18-alpine #Данное имя также будет определять ip адрес для подключения к контейнеру #Добавить команду для установки и запуска сервера разработки command: sh -c "yarn install && yarn run dev" #Следующая команда определяет порты для службы ports: - 127.0.0.1:3000:3000 #Далее определяется рабочая директория working_dir: /app #И каталог для volumes в директории приложения volumes: - ./:/app #С помощью ключа environment определяются переменные окружения environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos #Далее необходимо определить сервер mysql и установить для нее соответствующий псевдоним services: app: # The app service definition mysql: image: mysql:8.0 #Определить каталог для volume и указать переменные окружения volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos

    В целом код внутри файла compose.yaml должен выглядить так

    services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev" ports: - 127.0.0.1:3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos mysql: image: mysql:8.0 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos volumes: todo-mysql-data:

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

    #Запуск docker compose с флагом -f для запуска в фоновом режиме docker compose up -d

    В процессе запуска docker composer автоматически создаст сеть по умолчанию для стека приложений

    #Просмотр логов docker compose docker compose logs -f #Чтобы увидить лог конкретной службы, необходимо в конце команды добавить название службы docker compose logs -f mysql #Остановить приложение запущенной с помощью compose docker compose down #Чтобы удалить volumes, используется дополнительный флаг --volumes docker compose down --volumes

    Документация: https://docs.docker.com/get-started/workshop/08_using_compose/

    Image-building
    #Используя image history можно просмотреть команду, которая использовалась для создания каждого слоя в образе #В выхлопе каждая строка это слой образа или команда docker image history getting-started #Более подробный выхлоп можно получить с помощью дополнительной опции --no-trunc docker image history --no-trunc getting-started

    Если в определенном слое, все последующие слои также будут воссозданы заново.
    Чтобы сократить время сборки нужно реструктурировать ваш Dockerfile для кеширования зависимостей
    Например для приложений, основанных на nodejs эти зависимости определены в файле package.json
    Необходимо воссоздать зависимости yarn только в том случае, если в package.json были внесены изменения.
    Для этого необходимо обновить Dockerfile для копирования в package.json, установить зависимости, а затем скопировать все остальное.
    Создайте файл с именем .dockerignore в той же папке, что и Dockerfile, со следующим содержимым.
    node_modules
    файлы .dockerignore - это простой способ выборочно скопировать только файлы, которые относятся к образу
    В этом случае папка node_modules должна быть опущена на втором шаге копирования, поскольку в противном случае, возможно, были бы перезаписаны файлы, которые были созданы командой на шаге ЗАПУСКА.
    После внесения изменений необходимо пересобрать образ

    docker build -t getting-started .

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

    Автоматический запуск контейнеров

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


    Использование --live-restore позволяет продолжать работу контейнеров во время обновления Docker, несмотря на прерывание сетевого подключения и ввода данных пользователем.
    Чтобы настроить политику перезапуска контейнера, используйте флаг --restart при выполнении команды docker run . Значение флага --restart может быть любым из следующих:
    no - не перезапускать контейнер автоматически. (По умолчанию)
    on-failure[:max-retries] - перезапускать контейнер, если он завершает работу из-за ошибки, которая проявляется в виде ненулевого кода завершения. При необходимости ограничьте количество попыток перезапуска контейнера демоном Docker с помощью опции :max-retries
    always - всегда перезапускать контейнер, если он останавливается. Если он остановлен вручную, он перезапускается только при перезапуске демона Docker или при перезапуске самого контейнера вручную. (См. второй пункт в разделе «Сведения о политике перезапуска») unless-stopped - аналогично always за исключением того, что при остановке контейнера (вручную или иным способом) он не перезапускается даже после перезапуска демона Docker.

    Следующая команда гарантирует перезапуск всех запущенных контейнеров

    docker update --restart unless-stopped $(docker ps -q)

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


    Политики перезапуска применяются только к контейнерам
    Источник: https://docs.docker.com/engine/containers/start-containers-automatically

    Запуск нескольких процессов в контейнере


    Источник: https://docs.docker.com/engine/containers/multi-service_container/

    Ресурсные ограничения


    Источник: https://docs.docker.com/engine/containers/resource_constraints/

    Подробная документация

    Install
    Storage
    Networking
    Автоматический запуск контейнеров
    Ресурсные ограничения
    Показатели времени выполнения
    Управление работающими контейнерами
    Тонкости работы с CLI
    Демон Dockerd
    Управление ресурсами
    Плагины движка Docker
    Сборка и обзор файла Dockerfile
    Многоступенчатые сборки
    Переменные
    Проверка конфигурации сборки
    Кэш
    Метаданные
    Docker Compose
    И многое другое ЗДЕСЬ


    Источники
    Последнее изменение: 03.06.2026 09:26


    Связанные темы
    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ