Главная/Подготовка среды/Урок

1.2. Установка Docker Engine

Цели

После этого материала вы сможете:

  • объяснить, из каких компонентов состоит установка Docker и зачем нужен каждый;
  • удалить конфликтующие пакеты, установленные из репозитория дистрибутива;
  • подключить официальный apt repository Docker с проверкой подписи;
  • установить Docker Engine, CLI, containerd, Buildx и Compose plugin;
  • проверить установку и прочитать версии всех компонентов;
  • восстановить работу, если в выводе docker version отсутствует блок Server;
  • объяснить, почему установка через snap или apt install docker.io не подходит для курса;
  • зафиксировать версию Docker, если это требуется.

Предварительные знания

  • 1.1. Требования к Linux — система проверена и пригодна;
  • работа с sudo;
  • базовое представление о том, что такое пакетный репозиторий.

Ключевые термины

ТерминОбъяснение
Docker EngineСервер: daemon dockerd, который создаёт и запускает containers. Пакет docker-ce
Docker CLIКлиент: программа docker, отправляющая команды daemon. Пакет docker-ce-cli
containerdОтдельный runtime, которым dockerd управляет containers. Пакет containerd.io
BuildxПлагин CLI для сборки образов через BuildKit. Пакет docker-buildx-plugin
Compose pluginПлагин CLI, реализующий команду docker compose. Пакет docker-compose-plugin
apt repositoryИсточник пакетов для apt. Официальный репозиторий Docker отличается от репозитория Ubuntu
GPG keyКриптографический ключ, которым подписан репозиторий. Позволяет apt убедиться, что пакеты не подменены
deb822Современный формат файлов источников apt: многострочный, в /etc/apt/sources.list.d/*.sources

Теория

Из чего состоит установка

Слово «Docker» обозначает не одну программу, а набор компонентов. Понимание их ролей избавляет от большинства недоразумений.

text
  docker (CLI)                   пакет docker-ce-cli
      │  отправляет HTTP-запросы через Unix socket
      ▼
  dockerd (daemon)               пакет docker-ce
      │  управляет через gRPC
      ▼
  containerd                     пакет containerd.io
      │  порождает
      ▼
  containerd-shim → runc         пакет containerd.io
      │  создаёт
      ▼
  процесс приложения

Плюс два плагина CLI, которые устанавливаются отдельными пакетами и добавляют подкоманды:

  • docker buildx — сборка через BuildKit (пакет docker-buildx-plugin);
  • docker compose — работа с многокомпонентными системами (пакет docker-compose-plugin).

Подробно архитектура разбирается в разделе 02. Сейчас достаточно знать, что установить нужно все пять пакетов.

Почему не apt install docker.io

В репозитории Ubuntu есть пакет docker.io. Он устанавливается одной командой и работает. Курс его не использует по трём причинам.

  1. Версия отстаёт. Пакет собирается сопровождающими Ubuntu и обновляется реже. На LTS-версии он может отставать на год и более. Часть материала курса (containerd image store, современные возможности BuildKit) требует свежей версии.
  2. Состав отличается. Buildx и Compose plugin ставятся отдельными пакетами с другими именами, и их версии тоже отстают.
  3. Официальная документация описывает другой путь. Курс требует проверять всё по официальным источникам; расхождение установки с документацией создаёт постоянные мелкие несовпадения.

Аналогично не подходит установка через snap: там иная файловая структура, иные пути и ограничения confinement, из-за которых часть упражнений курса не воспроизводится.

Факт против рекомендации. Факт: docker.io и snap-версия работают. Рекомендация: для этого курса используйте официальный репозиторий, иначе часть команд даст другой результат.

Что делает подключение репозитория

Три шага, каждый со своим смыслом.

  1. Скачивание GPG-ключа. Ключ кладётся в /etc/apt/keyrings/docker.asc. Им подписан репозиторий Docker; apt использует ключ, чтобы убедиться в подлинности метаданных и пакетов.
  2. Создание файла источника. Файл описывает, откуда брать пакеты, для какого релиза, какие компоненты и каким ключом проверять.
  3. Обновление индекса. apt update скачивает список доступных пакетов из нового источника.

Ключ кладётся именно в /etc/apt/keyrings/, а не добавляется в общий keyring через устаревший apt-key add. Причина: ключ, добавленный в общий keyring, доверяет всем репозиториям, а не только своему. Привязка ключа к конкретному источнику через Signed-By ограничивает доверие.

Формат deb822

Официальная документация Docker сейчас использует формат deb822 — многострочный файл .sources вместо однострочного .list. Оба формата работают; deb822 читается лучше и явно указывает архитектуру и ключ.

Многие руководства в интернете показывают старый формат:

text
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable

Это не ошибка — но курс следует текущей документации.


Внутренний механизм

Что происходит при apt install docker-ce

  1. apt разрешает зависимости: docker-ce требует containerd.io, docker-ce-cli и ряд системных библиотек.
  2. Пакеты скачиваются и проверяются по подписи.
  3. Файлы распаковываются: бинарники в /usr/bin, unit-файлы systemd в /lib/systemd/system, плагины CLI в /usr/libexec/docker/cli-plugins.
  4. Post-install скрипт создаёт системную группу docker (без участников), регистрирует и запускает docker.service и docker.socket.
  5. При первом запуске dockerd создаёт каталог данных /var/lib/docker, выбирает storage driver и настраивает сетевой bridge docker0.

После этого daemon работает и слушает Unix socket /var/run/docker.sock. Права на socket — владелец root, группа docker, режим 0660. Именно поэтому команды сразу после установки требуют sudo: обычный пользователь не входит в группу docker.

Почему плагины CLI ставятся отдельно

docker buildx и docker compose — не встроенные подкоманды, а исполняемые файлы в каталоге плагинов. CLI при запуске просматривает /usr/libexec/docker/cli-plugins и ~/.docker/cli-plugins и регистрирует найденное как подкоманды.

Практическое следствие: если docker compose version выдаёт «is not a docker command», значит пакет docker-compose-plugin не установлен, а сам Docker при этом работает нормально.


Команды и примеры

Шаг 1. Удаление конфликтующих пакетов

bash
for pkg in docker.io docker-doc docker-compose docker-compose-v2 \
           podman-docker containerd runc; do
    sudo apt remove -y "$pkg"
done

Что делает: последовательно удаляет пакеты, которые конфликтуют с официальными. Если пакет не установлен, apt сообщит об этом и продолжит.

Ожидаемый результат: для не установленных пакетов — Package 'docker-doc' is not installed, so not removed. Это нормально.

Данные и образы, созданные предыдущей установкой, не удаляются этой командой: они остаются в /var/lib/docker. Полное удаление данных разбирается в уроке 1.6.

Шаг 2. Подготовка apt

bash
sudo apt update
sudo apt install -y ca-certificates curl

Что делает: обновляет индекс пакетов и устанавливает корневые сертификаты (нужны для HTTPS) и curl (нужен для скачивания ключа).

Шаг 3. Добавление GPG-ключа

bash
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
     -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

Разбор аргументов:

Команда / флагЗначение
install -m 0755 -dСоздаёт каталог с указанными правами. Надёжнее, чем mkdir + chmod
curl -fВозвращать ошибку при HTTP-статусе 4xx/5xx, а не сохранять страницу ошибки
curl -sТихий режим, без индикатора прогресса
curl -SНо ошибки всё же показывать
curl -LСледовать за редиректами
chmod a+rДать всем право чтения — apt работает от _apt, а не от root

Проверка, что ключ скачан корректно:

bash
head -1 /etc/apt/keyrings/docker.asc
text
-----BEGIN PGP PUBLIC KEY BLOCK-----

Если вместо этого вы видите HTML — скачалась страница ошибки; проверьте сеть и повторите.

Шаг 4. Подключение репозитория

bash
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

Что делает: создаёт файл источника в формате deb822. Подстановки $( ... ) вычисляются shell до передачи в tee, поэтому в файл попадают конкретные значения.

Разбор полей:

ПолеЗначение
Types: debБинарные пакеты (не исходники)
URIsАдрес репозитория
SuitesКодовое имя релиза Ubuntu, например noble
Components: stableКанал. Есть также test и nightly — для курса не нужны
ArchitecturesАрхитектура, например amd64. Ограничивает загрузку метаданных только нужной архитектурой
Signed-ByКлюч, которым проверяется этот источник

Проверка результата:

bash
cat /etc/apt/sources.list.d/docker.sources

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

Убедитесь, что apt update завершился без ошибок и в выводе присутствует строка с download.docker.com.

Шаг 5. Установка пакетов

bash
sudo apt install -y \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin

Что делает: устанавливает все пять компонентов. Порядок в команде значения не имеет.

Ожидаемый результат: apt скачает около 100–130 MB и распакует примерно 400–500 MB. В конце вывода — сообщения о создании и запуске сервисов.

Шаг 6. Проверка установки

bash
sudo docker version

Ожидаемый результат — два блока, Client и Server:

text
Client: Docker Engine - Community
 Version:           29.0.1
 API version:       1.53
 Go version:        go1.25.3
 ...

Server: Docker Engine - Community
 Engine:
  Version:          29.0.1
  API version:      1.53 (minimum version 1.44)
  ...
 containerd:
  Version:          1.7.28
 runc:
  Version:          1.3.1
 docker-init:
  Version:          0.19.0

Наличие блока Server — главный признак успеха: он означает, что CLI смог связаться с работающим daemon.

Если блока Server нет

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

text
Client: Docker Engine - Community
 Version:           29.0.1
 ...

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Это означает ровно одно: CLI установлен и работает, но daemon не отвечает. Шаг 5 обычно запускает службу сам — post-install скрипт пакета docker-ce регистрирует и стартует docker.service. Но делает он это не в каждой среде: запуск пропускается, если systemd не является процессом с PID 1 (chroot, часть container-образов, WSL без systemd) или если в системе есть /usr/sbin/policy-rc.d, запрещающий пакетам стартовать службы. Автозагрузка также могла быть отключена вручную при прошлой установке.

Поэтому первое действие — включить автозагрузку и запустить daemon явно:

bash
sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
sudo docker version

Разбор:

Команда / флагЗначение
systemctl enableВключает автозагрузку: служба будет стартовать при следующей загрузке системы
--nowДополнительно запускает службу немедленно, не дожидаясь перезагрузки
systemctl statusПоказывает фактическое состояние службы и последние строки её журнала
--no-pagerПечатает вывод сразу, не открывая less. Без этого флага вывод придётся закрывать клавишей q

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

Ожидаемый результат status:

text
● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-07-29 10:12:44 MSK; 3s ago

Ключевые слова — enabled (автозагрузка включена) и active (running) (служба работает). После этого sudo docker version показывает оба блока.

enable --now docker относится к docker.service. Второй unit, docker.socket, включается пакетом отдельно, а при старте службы подтягивается автоматически — docker.service объявляет Requires=docker.socket. Оба unit и механизм socket activation разбираются в уроке 1.3.

Если блок Server не появился и после этого, причина не в автозагрузке, и status уже показал её в поле Active:

Что в ActiveЧто это значитЧто делать
active (running), но ошибка соединения осталасьDaemon работает; проблема в правах на socketУбедитесь, что команда выполняется с sudo; далее — урок 1.5
activating (auto-restart)Daemon стартует и сразу падает, systemd перезапускает его по кругуsudo journalctl -u docker.service -n 30 — причина всегда в журнале; см. урок 1.3
failed или inactive (dead)Daemon не смог запуститьсяТам же: sudo journalctl -u docker.service -n 30
Unit docker.service could not be foundПакет docker-ce не установлен — шаг 5 завершился с ошибкойПовторить шаг 5 и прочитать вывод apt целиком
System has not been booted with systemd as init systemСистема без systemd; systemctl в ней не работаетКурс рассчитан на систему с systemd. Для разовой проверки daemon запускается вручную: sudo dockerd в отдельном терминале

Версии плагинов проверяются отдельно:

bash
docker buildx version
docker compose version
text
github.com/docker/buildx v0.34.1 ...
Docker Compose version v2.40.3

Обратите внимание: эти две команды не требуют обращения к daemon, поэтому работают без sudo.

Полная информация о системе:

bash
sudo docker info

Команда выводит несколько десятков строк. Ключевые для нас поля разбираются в уроке 1.4.

Фиксация версии (при необходимости)

Если нужно установить конкретную версию, а не последнюю:

bash
# посмотреть доступные версии
apt-cache madison docker-ce | awk '{print $3}'
text
5:29.0.1-1~ubuntu.24.04~noble
5:28.5.2-1~ubuntu.24.04~noble

Установка конкретной версии:

bash
VERSION_STRING="5:28.5.2-1~ubuntu.24.04~noble"
sudo apt install -y \
    docker-ce="$VERSION_STRING" \
    docker-ce-cli="$VERSION_STRING" \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin

Чтобы apt upgrade не обновил пакет автоматически:

bash
sudo apt-mark hold docker-ce docker-ce-cli

Отменить фиксацию:

bash
sudo apt-mark unhold docker-ce docker-ce-cli

Как отменить установку

Удаление пакетов:

bash
sudo apt purge -y docker-ce docker-ce-cli containerd.io \
                  docker-buildx-plugin docker-compose-plugin

Опасная команда. Следующая команда удаляет все образы, containers и volumes безвозвратно. Восстановление невозможно, если нет резервных копий или образы не опубликованы в registry. Перед выполнением проверьте содержимое: sudo du -sh /var/lib/docker и sudo docker volume ls. Полная процедура удаления описана в уроке 1.6.

bash
sudo rm -rf /var/lib/docker /var/lib/containerd

Удаление репозитория и ключа:

bash
sudo rm /etc/apt/sources.list.d/docker.sources
sudo rm /etc/apt/keyrings/docker.asc
sudo apt update

Практический пример

Проверка, что установлены все компоненты и их версии согласованы.

Создайте файл:

text
docker-check/
└── verify-install.sh
bash
#!/usr/bin/env bash
# verify-install.sh — проверка полноты установки Docker.
set -uo pipefail

fail=0

check() {
    local name="$1"; shift
    if out="$("$@" 2>&1)"; then
        printf '  [+] %-20s %s\n' "$name" "$(echo "$out" | head -1)"
    else
        printf '  [!] %-20s НЕ РАБОТАЕТ\n' "$name"
        fail=1
    fi
}

echo "=== Компоненты Docker ==="
check "docker CLI"   docker --version
check "buildx"       docker buildx version
check "compose"      docker compose version

echo
echo "=== Связь с daemon ==="
if server="$(docker version --format '{{.Server.Version}}' 2>&1)"; then
    printf '  [+] %-20s %s\n' "Server" "$server"
else
    printf '  [!] %-20s %s\n' "Server" "$server"
    echo "      Возможные причины: daemon не запущен либо нет прав на socket."
    fail=1
fi

echo
echo "=== Runtime ==="
check "containerd"   containerd --version
check "runc"         runc --version

exit "$fail"

Запуск:

bash
chmod +x verify-install.sh
sudo ./verify-install.sh

Ожидаемый вывод:

text
=== Компоненты Docker ===
  [+] docker CLI            Docker version 29.0.1, build ...
  [+] buildx                github.com/docker/buildx v0.34.1 ...
  [+] compose               Docker Compose version v2.40.3

=== Связь с daemon ===
  [+] Server               29.0.1

=== Runtime ===
  [+] containerd            containerd github.com/containerd/containerd ...
  [+] runc                  runc version 1.3.1

Скрипт возвращает exit code 0 при полном успехе и 1 при любой проблеме — это делает его пригодным для использования в автоматических проверках.

Проверка результата

bash
sudo docker run --rm hello-world

Ожидаемый результат — сообщение, начинающееся с Hello from Docker!. Разбор того, что при этом произошло, — в уроке 1.4.

Флаг --rm удаляет container сразу после завершения, чтобы не оставлять мусор.

Типичные ошибки

ОшибкаПричинаИсправление
E: Unable to locate package docker-ceРепозиторий не подключён или apt update не выполнялся после его добавленияПроверить /etc/apt/sources.list.d/docker.sources, выполнить sudo apt update
Suites: пустое в файле источникаДистрибутив не заполняет UBUNTU_CODENAME, а VERSION_CODENAME содержит собственное имяПодставить кодовое имя Ubuntu вручную: noble, jammy, resolute
The following signatures couldn't be verifiedКлюч не скачан, повреждён или не читается пользователем _aptПерескачать ключ, выполнить sudo chmod a+r /etc/apt/keyrings/docker.asc
docker: 'compose' is not a docker commandНе установлен docker-compose-pluginsudo apt install docker-compose-plugin
Используется docker-compose с дефисомЭто Compose v1, снятый с поддержкиИспользовать docker compose без дефиса
В выводе docker version есть только блок ClientDaemon не запущен: post-install скрипт не стартовал службу либо автозагрузка отключенаsudo systemctl enable --now docker, затем sudo systemctl status docker --no-pager
Cannot connect to the Docker daemonDaemon не запущен, либо нет прав на socketСначала sudo systemctl enable --now docker; далее см. урок 1.3 и урок 1.5
Конфликт с ранее установленным docker.ioСтарые пакеты не удаленыВыполнить шаг 1 и повторить установку
Установка через curl ... | sh из непроверенного источникаСкрипт get.docker.com удобен, но выполняет произвольный код от rootПрочитать скрипт перед выполнением или использовать пошаговую установку через apt

Контрольные вопросы

На понимание:

  1. Почему установка состоит из пяти пакетов, а не из одного?
  2. Зачем ключ кладётся в /etc/apt/keyrings/, а не добавляется через apt-key add?
  3. Что означает поле Signed-By в файле источника?
  4. Почему docker buildx version работает без sudo, а docker version — не всегда?
  5. Почему пакет docker.io из репозитория Ubuntu не подходит для этого курса?

На применение:

  1. Как установить конкретную версию Docker Engine и запретить её автоматическое обновление?
  2. Как проверить, что репозиторий подключён правильно, не устанавливая пакеты?
  3. Как убедиться, что установлены все пять компонентов, одной последовательностью команд?

На диагностику:

  1. docker version выводит блок Client, но вместо Server — ошибка соединения. Назовите две разные причины и способ различить их.
  2. После apt update появляется ошибка о невозможности проверить подпись репозитория Docker. С чего начать проверку?

Краткое резюме

  1. Установка Docker — это пять пакетов: docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, docker-compose-plugin.
  2. Перед установкой удаляются конфликтующие пакеты дистрибутива.
  3. Официальный репозиторий подключается с явной привязкой GPG-ключа через Signed-By.
  4. Документация использует формат deb822 (.sources); старый формат .list также работает.
  5. Кодовое имя релиза берётся из /etc/os-release с приоритетом UBUNTU_CODENAME.
  6. Наличие блока Server в выводе docker version — главный признак успешной установки; если блока нет, daemon не запущен: sudo systemctl enable --now docker.
  7. Buildx и Compose — плагины CLI, они устанавливаются отдельными пакетами.
  8. docker compose (v2) заменил docker-compose (v1); версия с дефисом снята с поддержки.
  9. Версию можно зафиксировать через apt-mark hold.
  10. Удаление пакетов не удаляет данные: образы и volumes остаются в /var/lib/docker.

Официальные источники

ИсточникСсылкаЧто подтверждает
Install Docker Engine on Ubuntuhttps://docs.docker.com/engine/install/ubuntu/Полная последовательность установки: удаление конфликтующих пакетов, GPG-ключ, файл источника в формате deb822, список пакетов, проверка через hello-world
Install Docker Enginehttps://docs.docker.com/engine/install/Обзор способов установки и поддерживаемых платформ
Docker Compose installationhttps://docs.docker.com/compose/install/linux/Установка Compose v2 как плагина CLI
Migrate to Compose v2https://docs.docker.com/compose/releases/migrate/Прекращение поддержки docker-compose v1
Docker CLI pluginshttps://docs.docker.com/reference/cli/docker/Механизм плагинов CLI и структура команд
sources.list(5) man pagehttps://manpages.ubuntu.com/manpages/noble/man5/sources.list.5.htmlФормат deb822 и поля Types, URIs, Suites, Signed-By

Навигация

← Предыдущий материал
Вернуться к разделу
Следующий материал → Docker daemon
Главное оглавление

Markdown на GitHub ↗