3.9.16.1 Установка и настройка docker
Установка docker
Доступ к среде контейнеризации
Консольные команды docker
Настройка зеркал общедоступного хранилища образов Docker Hub
Базовые образы
Реестр образов РЕД ОС
Настройка собственного локального реестра docker-образов
Работа с Dockerfile
Настройка контейнеров для автоматического запуска в systemd
Автоматизированное создание образа
Окружение
- Версия ОС: 8
- Конфигурация ОС: Сервер графический, Сервер минимальный
- Редакция ОС: Все
- Версия ПО: docker-ce-4:28.1.1-3, docker-ce-cli-4:28.1.1-3, registry-2.8.2-2
Контейнеризация — метод виртуализации, при котором ядро операционной системы поддерживает несколько изолированных экземпляров пространства пользователя вместо одного. Эти экземпляры (обычно называемые контейнерами) с точки зрения выполняемых в них процессов идентичны отдельному экземпляру операционной системы. Ядро обеспечивает полную изолированность контейнеров, поэтому программы из разных контейнеров не могут воздействовать друг на друга.
В отличие от аппаратной виртуализации, при которой эмулируется аппаратное окружение и может быть запущен широкий спектр гостевых операционных систем, в контейнере может быть запущен экземпляр операционной системы только с тем же ядром, что и у хостовой операционной системы (все контейнеры узла используют общее ядро). При этом при контейнеризации отсутствуют дополнительные ресурсные накладные расходы на эмуляцию виртуального оборудования и запуск полноценного экземпляра операционной системы, характерные при аппаратной виртуализации.
В РЕД ОС одним из средств контейнеризации является контейнерная платформа Docker.
Docker — программное обеспечение для автоматизации развертывания и управления приложениями в средах с поддержкой контейнеризации. Позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, который может быть развернут на любой Linux-подобной системе с поддержкой контрольных групп в ядре, а также предоставляет набор команд для управления этими контейнерами.
Для экономии пространства хранения проект использует файловую систему aufs с поддержкой технологии каскадно-объединенного монтирования: контейнеры используют образ базовой операционной системы, а изменения записываются в отдельную область.
В состав программных средств входит демон — сервер контейнеров, клиентские средства, позволяющие из интерфейса командной строки управлять образами и контейнерами, а также REST API, позволяющий управлять контейнерами программно.
Демон обеспечивает полную изоляцию запускаемых на узле контейнеров на уровне файловой системы (у каждого контейнера собственная корневая файловая система), на уровне процессов (процессы имеют доступ только к собственной файловой системе контейнера, а ресурсы разделены средствами containerd), на уровне сети (каждый контейнер имеет доступ только к привязанному к нему сетевому пространству имен и соответствующим виртуальным сетевым интерфейсам).
Установка docker
Для установки средства контейнеризации необходимо выполнить команду (потребуются права администратора):
dnf install docker-ce docker-ce-cli
После успешной установки необходимо запустить сервис контейнеризации docker и добавить его в автозагрузку:
systemctl enable docker --now
Убедитесь, что сервис запущен, проверив статус запущенной службы:
systemctl status docker
В статусе должно быть отображено active (running).
Для получения информации об установленном docker выполните команду:
docker info
При корректной настройке будет получен соответствующий ответ от сервиса Docker.
Доступ к среде контейнеризации
По умолчанию доступ к среде контейнеризации и запуску сервисов имеет только суперпользователь. Демон docker подключается к сокету Unix, к которому также имеет доступ только суперпользователь.
Для использования и управления средой контейнеризации обычным пользователем необходимо добавить его в отдельную группу, пользователям которой будет разрешено выполнять необходимые манипуляции. Такая группа создается в процессе установки среды контейнеризации и имеет название docker.
Добавьте необходимого пользователя в группу docker командой:
usermod -aG docker <имя_пользователя>
Проверить назначенные права можно, выполнив загрузку тестового образа с правами обычного пользователя:
docker info
При корректной настройке будет получен соответствующий ответ от сервиса Docker.
Консольные команды docker
Часто используемые команды (аргументы команд для краткости не указаны):
|
Команда |
Краткое описание |
| docker attach | Подключить стандартные каналы ввода-вывода (stdin, stdout, stderr) к активному контейнеру. |
| docker build | Построить Docker-образ из Docker-файла. |
| docker builder | Управление модулем построения Docker-образов. |
| docker commit | Создание нового Docker-образа из активного контейнера. |
| docker config | Управление конфигурациями Docker. |
| docker container |
Управление контейнерами:
|
| docker context | Управление контекстами Docker. |
| docker cp | Копирование файлов или каталогов между локальной файловой системой и файловой системой контейнера. |
| docker create | Создать новый изменяемый слой в указанном контейнере. |
| docker diff | Вывести список файлов и каталогов, изменённых с момента создания контейнера. |
| docker events | Вывести событий, произошедших с различными объектами Docker. |
| docker exec | Выполнить команду в активном контейнере. |
| docker export | Экспортировать файловую систему контейнера как архив формата tar. |
| docker history | Показать историю образа |
| docker image |
Управление образами:
|
| docker images | Вывести список образов верхнего уровня. |
| docker import | Cоздать файловую систему образа из архива. |
| docker info | Вывод системной информации. |
| docker inspect | Вывод подробной информации об объектах Docker. |
| docker kill | Принудительно деактивировать активный контейнер (контейнеры). |
| docker load | Загрузить образ из архива tar или из стандартного ввода. |
| docker login | Войти в реестр образов. |
| docker logout | Выйти из реестра образов. |
| docker logs | Извлечь журналы контейнера. |
| docker manifest | Управление манифестами и списками манифестов Docker. |
| docker network | Управление сетями. |
| docker node | Управление узлами кластеров Docker. |
| docker pause | Приостановить все процессы в активном контейнере (контейнерах). |
| docker plugin | Управление плагинами. |
| docker port | Вывести список отображения портов контейнера. |
| docker ps | Вывести список активных контейнеров. |
| docker pull | Загрузить образ на локальный компьютер из реестра образов. |
| docker push | Загрузить образ с локального компьютера в реестр образов. |
| docker rename | Переименовать контейнер. |
| docker restart | Перезапустить контейнер (контейнеры). |
| docker rm | Удалить контейнер (контейнеры). |
| docker rmi | Удалить образ (образы). |
| docker run |
Выполнить команду в новом контейнере, то есть: создать в существующем образе новый изменяемый слой, и выполнить команду, сохраняя изменения в этом слое.
|
| docker save | Сохранить образ (образы) в архиве tar (через стандартный вывод по умолчанию). |
| docker search | Поиск образов Docker в сети Интернет. |
| docker secret | Управление паролями кластеров Docker. |
| docker service | Управление сервисами кластеров Docker. |
| docker stack | Управление стеками. |
| docker start | Запустить контейнер (контейнеры). |
| docker stats | Отобразить в режиме реального времени статистику потребления ресурсов контейнером. |
| docker stop | Остановить активный контейнер (контейнеры). |
| docker swarm | Управление кластерами Docker. |
| docker system | Управление службой Docker. |
| docker tag | Создать тег (метку) образа, ссылающийся на существующий образ. |
| docker top | Вывести список процессов активного контейнера. |
| docker trust | Управление ключами и подписями образов. |
| docker unpause | Продолжить выполнение приостановленного активного контейнера (контейнеров). |
| docker update | Обновить конфигурацию контейнера (контейнеров). |
| docker version | Отобразить версию Docker. |
| docker volume | Управление томами хранения данных для контейнеров. |
| docker wait | Ожидание завершения работы контейнера (контейнеров) и вывод кодов завершения. |
Настройка зеркал общедоступного хранилища образов Docker Hub
При возникновении проблем с обращением к образам из общедоступного хранилища Docker Hub для обеспечения возможности продолжения корректной работы с образами рекомендуется настроить подготовленные зеркала.
Для настройки обращения docker к определенному зеркалу необходимо выполнить следующий алгоритм действий:
1а. В файл /etc/docker/daemon.json добавить строку вида:
"registry-mirrors": ["<адрес_зеркала>"]
где <адрес_зеркала> – адрес настроенного зеркала хранилища образов.
Например:
"registry-mirrors": ["https://mirror.gcr.io/"]
где https://mirror.gcr.io/ – публичное зеркало хранилища образов Docker Hub от компании Google.
1б. Если файл /etc/docker/daemon.json пуст или не существует, внести строки вида:
{
"registry-mirrors": ["<адрес_зеркала>"]
}
где <адрес_зеркала> – адрес настроенного зеркала хранилища образов.
Например:
{
"registry-mirrors": ["https://mirror.gcr.io/"]
}
где https://mirror.gcr.io/ – публичное зеркало хранилища образов Docker Hub от компании Google.
2. Перезапустить службу docker:
systemctl daemon-reload systemctl restart docker
Базовые образы
Универсальные базовые образы (UBI) — это легковесная и безопасная основа для создания облачных и веб-приложений в контейнерах. На основе UBI можно создавать свои контейнерные приложения и собственные образы.
В реестре образов РЕД ОС на данный момент доступны следующие базовые образы:
-
ubi – "урезанный образ", который использует dnf в качестве менеджера пакетов;
-
ubi-minimal – еще более "урезанный" образ, который использует microdnf в качестве менеджера пакетов;
-
ubi-micro – максимально "урезанный" образ, в котором отсутствует собственный менеджер пакетов. Данный docker-образ предназначен для запуска статически собранных бинарных файлов.
Также в реестре образов доступны образы типа S2I (Source-to-Image).
Source-to-Image — это процесс сборки для создания воспроизводимых образов контейнеров из исходного кода. Source-to-Image создает готовые к использованию образы на основе исходных кодов приложений, которые, в свою очередь, могут запускаться в виде собранного приложения.
В реестре образов РЕД ОС доступны следующие образы S2I:
-
s2i-core — предоставляет образам инструменты, необходимые для использования функциональности source-to-image, сохраняя при этом минимальный размер образа;
-
s2i-base — основан на s2i-core, предоставляет образам инструменты, необходимые для использования функциональности source-to-image, а также содержит различные библиотеки, которые служат основой для создания других s2i-образов — таких как s2i-python, s2i-ruby, s2i-nodejs и прочих.
Реестр образов РЕД ОС
На пакетной базе РЕД ОС разработан ряд docker-образов и создан собственный реестр docker-образов — registry.red-soft.ru.
В зависимости от содержащихся образов реестр имеет следующие ветки:
-
ubi8 — содержит базовые и прикладные образы, построенные на пакетах из репозитория Стандартной редакции РЕД ОС 8;
-
k8s8 — содержит образы кластера Kubernetes, построенные на пакетах из репозитория Стандартной редакции РЕД ОС 8.
-
redos8c — содержит базовые образы, построенные на пакетах из репозитория Сертифицированной редакции РЕД ОС 8;
-
k8s8c — содержит образы кластера Kubernetes, построенные на пакетах из репозитория Сертифицированной редакции РЕД ОС 8.
Для получения списка доступных образов в реестре необходимо выполнить команду (в примере будет выведен список образов вести ubi8):
docker search registry.red-soft.ru/ubi8
Для установки требуемого образа из реестра необходимо выполнить команду:
docker pull registry.red-soft.ru/ubi8/<название_образа>
Настройка собственного локального реестра docker-образов
В централизованном хранилище хранятся доступные docker-образы.
Одним из примеров общедоступных хранилищ образов является Docker Hub, по умолчанию Docker настроен на поиск образов в нем. Также есть возможность настройки своего собственного хранилища.
При использовании команд docker pull или docker run требуемые образы будут извлекаться из настроенного хранилища. Когда используется команда docker push, образ помещается в настроенное хранилище образов.
Установка и настройка локального реестра docker-образов из репозитория РЕД ОС
Для установки локального реестра docker-образов из репозитория РЕД ОС выполните команду:
dnf install registry
Запустите службу registry:
systemctl enable registry.service --now
Убедитесь, что служба активна, выполнив:
systemctl status registry.service
В статусе должно быть указано active(running).
Необходимо настроить демон docker на обращение к приватному реестру образов. Для этого добавьте в файл /etc/docker/daemon.json следующую строку:
"insecure-registries": ["127.0.0.1:5000"],
Локальный реестр docker-образов готов к использованию. Для проверки корректности настройки локального реестра см. п. «Загрузка docker-образов в локальный реестр».
Настройка локального реестра образов путем создания контейнера в docker
Для настройки локального хранилища образов путем использования контейнеров в реестре docker-образов РЕД СОФТ предоставлен образ registry.red-soft.ru/ubi8/registry, являющийся реализацией инструмента хранения и обмена образами Docker Registry.
Для создания локального хранилища образов запустите контейнер на основе образа registry.red-soft.ru/ubi8/registry командой:
docker run -d -p 5000:5000 --restart=always --name test_reg_2 registry.red-soft.ru/ubi8/registry:latest
где:
-
-p 5000:5000— порт для обращения к реестру по умолчанию; -
--restart=always— автоматический запуск контейнера после перезапуска хостовой ОС; -
--name test_reg_2— имя контейнера; -
registry.red-soft.ru/ubi8/registry:latest— необходимый образ.
Локальный реестр образов готов к использованию. Для проверки корректности настройки локального реестра см. п. «Загрузка docker-образов в локальный реестр».
Изменение расположения хранилища образов
Локальное хранилище образов является контейнером и хранит образы внутри себя в каталоге /var/lib/registry. Однако при переустановке контейнера все данные внутри него будут уничтожены. Для избежания потери данных к контейнеру необходимо подключить внешнее хранилище данных.
Для этого на хостовой ОС сначала следует создать каталог, предназначенный для хранения образов:
mkdir /reg_images
Далее необходимо остановить и уничтожить имеющийся контейнер с локальным хранилищем:
docker container stop test_reg_2 && docker container rm -v test_reg_2
После этого следует запустить контейнер снова с дополнительным ключом, который отвечает за подключение к нему ранее созданного каталога:
docker run -d -p 5000:5000 --restart=always --name test_reg_2 -v /reg_images:/var/lib/registry registry.red-soft.ru/ubi8/registry:latest
где:
-
-p 5000:5000— порт для обращения к реестру по умолчанию; -
--restart=always— автоматический запуск контейнера после перезапуска хостовой ОС; -
--name test_reg_2— имя контейнера; -
-v /reg_images:/var/lib/registry— подключение каталога /reg_images к контейнеру в качестве каталога /var/lib/registry; -
registry.red-soft.ru/ubi8/registry:latest— необходимый образ.
Для проверки корректности настройки локального хранилища образов в качестве примера будет загружен образ nodejs-20 из реестра образов РЕД СОФТ registry.red-soft.ru/ubi8:
docker pull registry.red-soft.ru/ubi8/nodejs-20
Далее будет добавлен тег к загруженному образу:
docker tag registry.red-soft.ru/ubi8/nodejs-20 localhost:5000/js20_test:latest
Затем образ загружается в локальное хранилище:
docker push localhost:5000/js20_test:latest
The push refers to repository [localhost:5000/js20_test]
0932ece797fa: Pushed
6512634988ef: Pushed
526374a3d4d5: Pushed
latest: digest: sha256:fe07d0235d269961ba25f5853809ff81807f52d0aa75a77e51899a540975a675 size: 954
Проверка наличия загруженного образа в созданном каталоге /reg_images:
ls /reg_images/docker/registry/v2/repositories/ js20_test
Локальное хранилище с подключенным внешним каталогом успешно работает.
Загрузка docker-образов в локальный реестр
Для загрузки образа docker в локальное хранилище необходимо сперва создать тег образа, ссылающийся на существующий образ (в примере использован образ ubi-minimal из реестра образов РЕД СОФТ registry.red-soft.ru/ubi8), командой:
docker tag registry.red-soft.ru/ubi8/ubi-minimal localhost:5000/test_reg
где:
-
registry.red-soft.ru/ubi8/ubi-minimal— имеющийся образ docker; -
localhost— имя или IP-адрес хостовой ОС; -
5000— порт для обращения к реестру по умолчанию; -
test_reg— новое имя образа.
Убедитесь, что тег образа был успешно создан:
docker images REPOSITORY TAG IMAGE ID CREATED SIZE localhost:5000/test_reg latest 60d2a5f5b971 24 hours ago 102MB registry.red-soft.ru/ubi8/ubi-minimal latest 60d2a5f5b971 24 hours ago 102MB
После этого образ можно загрузить в локальное хранилище командой:
docker push localhost:5000/test_reg:latest
Ответ команды должен выглядеть примерно следующим образом:
The push refers to repository [localhost:5000/test_reg] 00983af53c2c: Pushed latest: digest: sha256:fde90838c647d829131f124a6d87801ac28c2a05619efff983dde04e1d6c16c3 size: 529
В корректности загрузки docker-образов в локальный реестр можно убедиться, удалив имеющиеся образы из docker (следующие команды удаляют образы из docker, но не затрагивают образы в локальном реестре):
docker image remove registry.red-soft.ru/ubi8/ubi-minimal Untagged: registry.red-soft.ru/ubi8/ubi-minimal:latest Untagged: registry.red-soft.ru/ubi8/ubi-minimal@sha256:fde90838c647d829131f124a6d87801ac28c2a05619efff983dde04e1d6c16c3 docker image remove localhost:5000/test_reg Untagged: localhost:5000/test_reg:latest Untagged: localhost:5000/test_reg@sha256:fde90838c647d829131f124a6d87801ac28c2a05619efff983dde04e1d6c16c3 Deleted: sha256:60d2a5f5b971ce5a1938d692175ece7416e148394f0d3987c9ff7e80b88e3e66 Deleted: sha256:00983af53c2c493b01c7f747c4197794c6250140357fba2cfbc0fb0c312162c0 docker images REPOSITORY TAG IMAGE ID CREATED SIZE
При загрузке docker-образов в локальный реестр, настроенный как контейнер docker, установленный образ registry.red-soft.ru/ubi8/registry удалять не нужно!
После этого загрузите образ из локального реестра командой:
docker pull localhost:5000/test_reg Using default tag: latest latest: Pulling from test_reg ebc434fd7dc8: Pull complete Digest: sha256:fde90838c647d829131f124a6d87801ac28c2a05619efff983dde04e1d6c16c3 Status: Downloaded newer image for localhost:5000/test_reg:latest localhost:5000/test_reg:latest docker images REPOSITORY TAG IMAGE ID CREATED SIZE localhost:5000/test_reg latest 60d2a5f5b971 24 hours ago 102MB
Локальный реестр образов работает корректно.
Работа с Dockerfile
Dockerfile — это текстовый файл, включающий в себя инструкции по созданию docker-образа. Dockerfile описывает будущую «операционную систему», которая будет лежать в основе контейнера, а также языки, переменные среды, расположение файлов, сетевые порты и другие необходимые компоненты и действия контейнера после его запуска.
Инструкции выполняются последовательно по принципу «одна строка — одна команда». Результаты наиболее важных инструкций фиксируются в виде отдельных слоев образа.
Каждая новая инструкция выполняется независимо от других — это означает, что выполнение RUN cd /tmp не будет иметь никакого эффекта для последующих инструкций.
Слои в образе создают только инструкции FROM, RUN, COPY, и ADD.
Формат файла имеет следующий вид:
<ИНСТРУКЦИЯ> <аргументы>
Инструкции не чувствительны к регистру, однако используется единый стиль их оформления с использованием заглавных букв.
Список инструкций, используемых в Dockerfile:
- FROM — определяет базовый (родительский) образ;
- RUN — выполняет команду и создаёт слой образа, используется для установки в контейнер пакетов;
- CMD — описывает команду с аргументами, которую нужно выполнить, когда контейнер будет запущен. Команда может быть переопределена при запуске контейнера;
- ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются;
- COPY — копирует в контейнер файлы и папки;
- ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы;
- WORKDIR — задаёт рабочую директорию для следующей инструкции;
- EXPOSE — указывает на необходимость открыть порт;
- ENV — устанавливает постоянные переменные среды;
- VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.
Если в Dockerfile используется несколько инструкций CMD, применена будет только последняя указанная инструкция.
С подробной информацией об использовании и применении Dockerfile можно ознакомиться в справочной странице:
man dockerfile
Инструкция FROM
Dockerfile должен начинаться с инструкции FROM.
Инструкция FROM задает базовый (родительский) образ, на основе которого будет создаваться новый образ. Перед инструкцией FROM могут быть указаны только директивы синтаксического анализатора (parser directives), комментарии или глобальные аргументы (ARG).
Строки, начинающиеся с символа # воспринимаются как комментарии и не обрабатываются.
Если необходимо создать образ, основанный на UBI, можно использовать следующую инструкцию FROM:
FROM registry.red-soft.ru/ubi8/ubi:latest
Эта инструкция указывает Docker, что будет использована последняя версия образа UBI в качестве базового для создания нового образа.
Инструкция RUN
Инструкция RUN позволяет выполнять команды внутри контейнера во время создания образа.
Пример использования инструкции RUN:
RUN dnf install -y \
package1 \
package2 \
package3
Данная инструкция устанавливает пакеты package1, package2 и package3 внутри контейнера.
Инструкция RUN может использоваться для установки зависимостей, настройки окружения, запуска скриптов и т. д. Она также может использоваться для создания новых слоев в образе Docker.
Важно помнить, что каждая инструкция RUN создает новый слой в образе Docker, поэтому необходимо объединять несколько команд в одну строку с помощью && или использовать инструкцию SHELL для выполнения нескольких команд в одном слое.
Инструкция CMD
Инструкция CMD передает Docker команду, которую необходимо выполнить при запуске контейнера.
Пример использования инструкции CMD:
CMD ["python", "./my_script.py"]
Инструкция CMD может использоваться для определения стандартного поведения контейнера при запуске. Это может быть полезно для установки параметров по умолчанию, например, для запуска веб-сервера или приложения.
Стоит отметить, что инструкция CMD может быть переопределена при запуске контейнера с помощью команды docker run. Например, если необходимо выполнить другой скрипт при запуске контейнера, можно использовать следующую команду:
docker run my-image python another_app.py
Данная команда переопределит команду, определенную в инструкции CMD, и запустит скрипт another_app.py вместо app.py.
Ограничения использования инструкции CMD:
- в одном файле Dockerfile может быть применена только одна инструкция CMD. Если в файле есть несколько таких инструкций, система проигнорирует все, кроме последней;
- инструкция CMD может иметь exec-форму. Если в инструкцию не входит упоминание исполняемого файла, тогда в файле должна присутствовать инструкция ENTRYPOINT. В таком случае обе инструкции должны быть представлены в формате JSON.
Инструкция ENTRYPOINT
Инструкция ENTRYPOINT определяет исполняемый файл или команду, которые будут выполняться при запуске контейнера. Инструкция также может использоваться для определения стандартного поведения контейнера при запуске. Пример использования инструкции ENTRYPOINT:
ENTRYPOINT ["python", "app.py"]
Данная инструкция определяет исполняемый файл, который будет выполнен при запуске контейнера — запуск скрипта app.py на языке Python.
В отличие от инструкции CMD, у инструкции ENTRYPOINT не могут быть переопределены аргументы при запуске контейнера с помощью команды docker run. Однако, если необходимо добавить аргументы или параметры при запуске контейнера, можно использовать инструкцию CMD совместно с инструкцией ENTRYPOINT.
Пример совместного использования инструкций ENTRYPOINT и CMD:
ENTRYPOINT ["python", "app.py"] CMD ["--port", "8080"]
Эти инструкции определяют исполняемый файл и параметры, которые будут переданы ему при запуске контейнера. В данном случае, при запуске контейнера будет запущен скрипт app.py на языке Python с параметром --port, равным 8080. Если необходимо изменить значение параметра --port, можно переопределить его при запуске контейнера с помощью флага docker run:
docker run my-image --port 9000
Данная команда переопределит значение параметра --port и запустит контейнер с параметром --port, равным 9000.
Инструкция COPY
Инструкция COPY сообщает Docker о необходимости переноса файлов и папок из локального контекста сборки в текущую рабочую директорию образа. Если целевая директория не существует, инструкция её создаст.
Пример использования инструкции COPY:
COPY . ./app
Инструкция ADD
Инструкция ADD копирует файлы или директории из исходной директории на хостовой машине в контейнер. Пример использования инструкции ADD:
ADD app.py /app/
Эта инструкция копирует файл app.py из текущей директории на хостовой машине в директорию /app/ внутри контейнера.
Инструкция ADD может использоваться для добавления файлов, архивов, конфигурационных файлов и в контейнер. Она также может использоваться для скачивания файлов из сети Интернет.
Важно помнить, что инструкция ADD создает новый слой в образе Docker, поэтому необходимо использовать ее с осторожностью и объединять несколько команд в один слой, если это возможно. Кроме того, не рекомендуется использовать инструкцию ADD для копирования больших файлов, так как это может привести к увеличению размера образа Docker.
Инструкция WORKDIR
Инструкция WORKDIR позволяет изменить рабочую директорию контейнера. С этой директорией работают инструкции COPY, ADD, RUN, CMD и ENTRYPOINT, указанные после WORKDIR.
Пример использования инструкции WORKDIR:
WORKDIR /usr/src/my_app_directory
Ограничения использования инструкции WORKDIR:
- с помощью WORKDIR рекомендуется устанавливать абсолютные пути к папкам, не перемещаясь по файловой системе с помощью команды
cdв Dockerfile; - инструкция WORKDIR автоматически создаёт директорию в том случае, если она не существует;
- можно использовать несколько инструкций WORKDIR. Если таким инструкциям предоставляются относительные пути, то каждая из них меняет текущую рабочую директорию.
Инструкция EXPOSE
Инструкция EXPOSE указывает, какие порты планируется открыть для того, чтобы через них можно было бы связаться с работающим контейнером. Данная инструкция не открывает порты. Она является средством общения между тем, кто собирает образ, и тем, кто запускает контейнер.
Для того чтобы открыть порт (или порты) и настроить перенаправление портов, необходимо выполнить команду docker run с ключом -p. Если использовать ключ -P, открыты будут все порты, указанные в инструкции EXPOSE.
Пример использования инструкции EXPOSE:
EXPOSE 8000
Инструкция ENV
Инструкция ENV позволяет задавать постоянные переменные среды, которые будут доступны в контейнере во время его выполнения.
Инструкция ENV подходит для задания констант. Если вы используете некоторое значение в Dockerfile несколько раз, например, при описании команд, выполняющихся в контейнере, и в будущем оно может измениться, имеет смысл записать данное значение в подобную константу.
Пример использования инструкции ENV:
ENV ADMIN="Ivan"
Инструкция VOLUME
Инструкция VOLUME позволяет указать каталог, который контейнер будет использовать для постоянного хранения файлов и для работы с такими файлами.
Пример использования инструкции VOLUME:
VOLUME /my_volume
Примеры использования Dockerfile
В рассматриваемых далее примерах представлены варианты Dockerfile для разных приложений на разных языках программирования. В качестве базовых будут использоваться docker-образы, представленные в Реестре docker-образов РЕД ОС.
Пример развертывания приложения на Python
Создайте Dockerfile:
nano Dockerfile.python
со следующим содержимым:
FROM registry.red-soft.ru/ubi8/python-313-minimal WORKDIR /app COPY app.py ./ CMD ["python", "app.py"]
Создайте файл приложения:
nano app.py
со следующим содержимым:
print("Hello World from Python!")
Для сборки docker-образа представленной программы на Python выполните команду:
docker build -t python_example:latest -f Dockerfile.python .
где:
-
-t python_example:latest— имя docker-образа и тег (задаются пользователем); -
-f Dockerfile.python— имя Dockerfile, с помощью которого будет собран docker-образ.
Для запуска контейнера из собранного образа выполните команду:
docker run --name py_ex python_example:latest
где:
--name py_ex— имя контейнера (задается пользователем).
После запуска контейнера в терминале появится приветственное сообщение:
Hello World from Python!
Пример развертывания приложения на Golang
Создайте Dockerfile:
nano Dockerfile.golang
со следующим содержимым:
FROM registry.red-soft.ru/ubi8/golang:1.25 WORKDIR /build RUN go mod init golang_test COPY main.go ./ RUN go mod tidy RUN go build -o main main.go CMD ["./main"]
Создайте файл приложения:
nano main.go
со следующим содержимым:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World from Golang!")
})
r.Run(":8080")
}
Для сборки docker-образа представленной программы на Golang выполните команду:
docker build -t golang_example:latest -f Dockerfile.golang .
где:
-
-t golang_example:latest— имя docker-образа и тег (задаются пользователем); -
-f Dockerfile.golang— имя Dockerfile, с помощью которого будет собран docker-образ.
Для запуска контейнера из собранного образа выполните команду:
docker run -p 8080:8080 - -name go_ex golang_example:latest
где:
-p 8080:8080— порт для доступа к веб-интерфейсу;--name go_ex— имя контейнера (задается пользователем).
Для проверки работоспособности контейнера в адресной строке браузера введите http://<IP-адрес_машины>:8080.
Если контейнер работает корректно, страница браузера будет иметь следующий вид:

Настройка контейнеров для автоматического запуска в systemd
Бывают ситуации, когда контейнеры могут быть остановлены вследствие определенных факторов. Для того чтобы остановленные контейнеры не приходилось запускать вручную, можно использовать настройку их автоматического запуска.
Далее будет рассмотрен пример настройки автоматического запуска локального реестра registry, настроенного как контейнер с именем test_reg_systemd и внешним каталогом для хранения образов /reg_images_sys.
Настройка автоматического запуска контейнера через службу systemd актуальна только в тех случаях, когда при запуске контейнера командой docker run не была использована опция --restart=always.
Предварительно был создан внешний каталог для хранения образов /reg_images_sys и запущен контейнер с локальным хранилищем следующими командами:
mkdir /reg_images_sys docker run -d -p 5000:5000 --name test_reg_systemd -v /reg_images_sys:/var/lib/registry registry.red-soft.ru/ubi8/registry:latest
После запуска контейнера registry необходимо создать файл настройки для службы systemd со следующим содержимым:
nano /etc/systemd/system/registry.service
[Unit] Description=registry container Requires=docker.service After=docker.service [Service] Restart=always ExecStart=/usr/bin/docker start -a test_reg_systemd ExecStop=/usr/bin/docker stop -t 15 test_reg_systemd TimeoutSec=30 [Install] WantedBy=multi-user.target
Сохраните изменения в файле и закройте его.
После этого необходимо запустить настроенную службу и добавить ее в автозагрузку командой:
systemctl enable registry.service --now
Проверьте статус службы:
systemctl status registry.service
В статусе должно быть указано active(running).
После перезагрузки хостовой ОС проверьте статус контейнера командой:
docker ps -a
В графе STATUS должно отображаться Up:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5cee2dc6e925 registry.red-soft.ru/ubi8/registry:latest "entrypoint.sh /etc/…" 20 minutes ago Up 49 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp test_reg_systemd
Автоматизированное создание образа
Для автоматизированного создания образа необходимо создать скрипт create_minimal_image_moby.sh
nano create_minimal_image_moby.sh
со следующим содержимым:
#!/usr/bin/env bash
dnf_config=""
build_dir=""
name=""
usage() {
cat << EOOPTS
$(basename $0) [OPTIONS] NAME
NAME Имя создаваемого docker-образа.
OPTIONS:
-d "путь" Указывает путь к файлу конфигурации dnf.
По умолчанию используется системный конфигурационный файл (/etc/dnf/dnf.conf).
-b "путь" Директория, в которой будет производиться сборка.
По умолчанию '/tmp'.
-t "тег" Тег, которым будет помечен docker-образ.
По умолчанию используется версия из файла /etc/redos-release.
EOOPTS
exit 1
}
while getopts "d:b:t:h" opt; do
case $opt in
d)
dnf_config=$OPTARG
;;
b)
build_dir=$OPTARG
;;
h)
usage
;;
t)
tag="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG"
usage
;;
esac
done
shift $((OPTIND - 1))
if [[ "x$1" == "x" ]]; then
echo "Не задано имя docker-образа"
exit 1
fi
name=$1
if [[ "$(id -u)" -gt "0" ]]; then
echo "Пользователь должен иметь права суперпользователя"
exit 1
fi
command -v dnf &> /dev/null
if [[ "$?" -gt "0" ]]; then
echo "Не найден dnf"
exit 1
fi
command -v docker &> /dev/null
if [[ "$?" -gt "0" ]]; then
echo "Не найден docker"
exit 1
fi
docker info &> /dev/null
if [[ "$?" -gt "0" ]]; then
echo "Невозможно получить информацию о docker"
echo "Возможно не запущен сервис docker"
exit 1
fi
if [[ "x$dnf_config" == "x" ]]; then
if [ -f /etc/dnf/dnf.conf ] ; then
dnf_config=/etc/dnf/dnf.conf
else
echo "Не задан конфигурационный файл dnf"
exit 1
fi
else
if [ ! -f $dnf_config ]; then
echo "Ошибка открытия конфигурационного файла dnf"
exit 1
fi
fi
if [[ "x$build_dir" == "x" ]]; then
target=$(mktemp -d /tmp/ubi.XXXXXX)
else
mkdir -p $build_dir
target=$(mktemp -d -p $(readlink -f $build_dir) ubi.XXXXXX)
fi
mkdir -m 755 "$target"/dev
mknod -m 600 "$target"/dev/console c 5 1
mknod -m 600 "$target"/dev/initctl p
mknod -m 666 "$target"/dev/full c 1 7
mknod -m 666 "$target"/dev/null c 1 3
mknod -m 666 "$target"/dev/ptmx c 5 2
mknod -m 666 "$target"/dev/random c 1 8
mknod -m 666 "$target"/dev/tty c 5 0
mknod -m 666 "$target"/dev/tty0 c 4 0
mknod -m 666 "$target"/dev/urandom c 1 9
mknod -m 666 "$target"/dev/zero c 1 5
packages="acl audit-libs basesystem bash bzip2-libs ca-certificates coreutils-single cracklib cracklib-dicts
crypto-policies crypto-policies-scripts cryptsetup-libs curl-minimal cyrus-sasl-lib dbus dbus-broker dbus-common
dbus-libs device-mapper device-mapper-libs dmidecode dnf dnf-data elfutils-default-yama-scope elfutils-libelf
elfutils-libs expat file-libs filesystem findutils gawk gdb-gdbserver gdbm-libs glib2 glibc glibc-common
glibc-minimal-langpack gmp gnupg2 gnutls gobject-introspection gpgme grep gzip glibc-langpack-ru glibc-langpack-en
ima-evm-utils json-c json-glib keyutils-libs kmod-libs krb5-libs libacl libarchive libassuan libattr libblkid libcap
libcap-ng libcom_err libcomps libcurl-minimal libdb libdnf libeconf libevent libfdisk libffi libgcc libgcrypt libgpg-error
libidn2 libksba libmodulemd libmount libnghttp2 libnl3 libpwquality librepo libreport-filesystem librhsm libseccomp
libselinux libsemanage libsepol libsigsegv libsmartcols libsolv libstdc++ libtasn1 libunistring libuser libutempter
libuuid libverto libxcrypt libxml2 libyaml libzstd lua-libs lz4-libs mpfr ncurses-base ncurses-libs nettle npth openldap
openssl openssl-libs p11-kit p11-kit-trust pam passwd pcre pcre2 pcre2-syntax popt python3 python3-chardet python3-dateutil
python3-dbus python3-decorator python3-dnf python3-dnf-plugins-core python3-ethtool python3-gpg python3-hawkey python3-idna
python3-iniparse python3-inotify python3-libcomps python3-libdnf python3-librepo python3-libs python-pip-wheel python3-pysocks
python3-requests python3-rpm python3-setuptools python-setuptools-wheel python3-six python3-subscription-manager-rhsm
python3-urllib3 readline redos-release rootfiles rpm rpm-build-libs rpm-libs sed setup shadow-utils sqlite-libs
subscription-manager-rhsm-certificates systemd systemd-libs systemd-pam systemd-rpm-macros tar tpm2-tss tzdata usermode
util-linux util-linux-core vim-minimal virt-what which xz-libs zlib zchunk-libs vi"
dnf -c "$dnf_config" \
--installroot="$target" \
--releasever=/ \
--setopt=group_package_types=mandatory \
--setopt=tsflags=nodocs \
--setopt=install_weak_deps=False \
-y install ${packages[@]}
dnf -c "$dnf_config" --installroot="$target" -y clean all
for file in "$target"/etc/{redos,system}-release; do
if [ -r "$file" ]; then
version="$(sed 's/^[^0-9\]*\([0-9.]\+\).*$/\1/' "$file")"
break
fi
done
cat > "$target"/etc/sysconfig/network << EOF
NETWORKING=yes
HOSTNAME=localhost.localdomain
EOF
rm -rf "$target"/usr/{bin/localedef,sbin/build-locale-archive}
# cracklib
rm -rf "$target"/usr/share/cracklib
# docs and man pages
rm -rf "$target"/usr/share/{man,doc,info,gnome/help}
# i18n
env ls -d "$target"/usr/share/i18n/*/* | grep -E -v 'en$|ru$|en_US|ru_RU|UTF-8' | xargs rm -rf
# dnf cache
rm -rf "$target"/var/cache/dnf
mkdir -p --mode=0755 "$target"/var/cache/dnf
# sln
rm -rf "$target"/sbin/sln
# ldconfig
rm -rf "$target"/etc/ld.so.cache "$target"/var/cache/ldconfig
mkdir -p --mode=0755 "$target"/var/cache/ldconfig
# create docker image
image_id_raw=$(tar --numeric-owner -c -C "$target" . | docker import -)
container_id=$(docker create $image_id_raw bash)
image_id=$(docker commit $container_id)
if [[ "x$tag" == "x" ]]; then
docker tag $image_id $name:$version
else
docker tag $image_id $name:$tag
fi
docker rm $container_id
rm -rf "$target"
Затем необходимо предоставить скрипту права на исполнение командой:
chmod +x ./create_minimal_image_moby.sh
При запуске скрипта с опцией -h будет выведена краткая справка по его использованию:
./create_minimal_image_moby.sh -h
create_minimal_image_moby.sh [OPTIONS] NAME
NAME Имя создаваемого docker-образа.
OPTIONS:
-d "путь" Указывает путь к файлу конфигурации dnf.
По умолчанию используется системный конфигурационный файл (/etc/dnf/dnf.conf).
-b "путь" Директория, в которой будет производиться сборка.
По умолчанию '/tmp'.
-t "тег" Тег, которым будет помечен docker-образ.
По умолчанию используется версия из файла /etc/redos-release.
Вы можете указать дополнительные опции, как описано выше, или указать только имя образа, который требуется создать.
Пример:
./create_minimal_image_moby.sh ro8
В результате выполнения данный образ станет доступен при просмотре имеющихся образов:
docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
ro8 8.0.2 f15e293e15bd 7 minutes ago 283MB
registry.red-soft.ru/ubi8/ubi-minimal latest ce2ca5ca47d4 4 weeks ago 102MB
registry.red-soft.ru/ubi8 latest 4e5d2ab41464 4 weeks ago 242MB
... Дата последнего изменения: 04.02.2026
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.