Введение в docker

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

    Введение в 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 Compose — технология, упрощающая работу с многоконтейнерными приложениями.
    Docker Swarm или Kubernetes — средство для управления развёртыванием контейнеров.
    Сервисы Docker — контейнеры в продакшне.


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

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


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

    Образ (images)

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


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

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

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

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

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

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

    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
    Удаление

    #Полное удаление 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

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

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

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

    Использование 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
    И многое другое ЗДЕСЬ


    Источники
    Последнее изменение: 13.04.2025 08:05


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

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