Текст и данные · Инструкция
Docker Rootless mode: как настроить без root
Docker Rootless mode позволяет уменьшить привилегии всей контейнерной инфраструктуры, а не только процесса внутри.
Короткий ответ
Docker Rootless mode запускает и daemon, и контейнеры без root-привилегий пользователя хоста. Для типичной Linux-установки нужны newuidmap/newgidmap, диапазоны минимум 65 536 subordinate UID/GID, затем dockerd-rootless-setuptool.sh install и проверка rootless context.
Чем rootless отличается от обычного Docker и userns-remap
В обычной конфигурации Docker daemon работает с root-привилегиями, и доступ к его сокету фактически даёт очень мощный контроль над хостом. Rootless mode переносит и daemon, и контейнеры в user namespace обычного пользователя, поэтому сам dockerd не требует root после выполнения предварительных системных условий. Это принципиально отличается от userns-remap: там UID контейнера также переназначаются на subordinate IDs, но daemon остаётся root-процессом. Rootless особенно полезен на рабочей станции разработчика, в среде с несколькими пользователями и там, где не хочется выдавать постоянный root-доступ для запуска контейнеров. При этом у режима есть сетевые и системные ограничения, и часть низкоуровневых сценариев, которые ожидают root или специфические драйверы, может не подойти.
Совет: Если задача решается обычным rootless-контейнером приложения, не добавляйте --privileged только ради удобства: это противоречит цели режима.
Настройка Rootless Docker на Linux
- Установите newuidmap/newgidmap через пакет uidmap и проверьте записи пользователя в /etc/subuid и /etc/subgid. Docker указывает минимум 65 536 subordinate UID/GID для пользователя rootless daemon.
- Запустите dockerd-rootless-setuptool.sh install от обычного пользователя, не через sudo. При пакетной установке Docker 20.10+ скрипт обычно доступен в /usr/bin; при отсутствии может понадобиться пакет docker-ce-rootless-extras.
- Установщик создаёт CLI context rootless. Проверьте docker context ls и docker info; в Security Options должен отображаться rootless. При ручном сценарии можно указать DOCKER_HOST на сокет в /run/user/$UID/docker.sock.
- Для systemd используйте systemctl --user enable docker и при необходимости sudo loginctl enable-linger $(whoami), чтобы пользовательский сервис мог стартовать без активной интерактивной сессии.
Предупреждение: Не запускайте установочный скрипт через sudo: rootless daemon должен принадлежать тому пользователю, под которым вы будете работать.
Что проверить после установки
- Команда docker info должна показывать rootless в Security Options, а активный CLI context — указывать на rootless daemon. Проверьте простой контейнер, затем публикацию порта, bind mount из домашнего каталога и перезапуск пользовательского сервиса. Отдельно проверьте владельцев файлов на bind mounts: в rootless mapping UID 0 внутри контейнера соответствует UID пользователя, запустившего rootless Docker, а остальные UID используют subordinate диапазон. Не переносите data dir rootless daemon на NFS: Docker отдельно предупреждает, что каталог данных ~/.local/share/docker не должен находиться на NFS. Если используется systemd, сервис живёт в ~/.config/systemd/user/docker.service, а не в системном /etc/systemd/system.
Важно: Тестируйте именно те операции, которые нужны проекту: «hello-world работает» ещё не проверяет bind mounts, порты и автозапуск.
Ограничения, из-за которых rootless иногда не подходит
Rootless меняет модель взаимодействия с сетью, cgroups, файловыми правами и некоторыми драйверами. Например, Docker прямо указывает, что macvlan не поддерживается в rootless mode. Приложения, которым нужен прямой доступ к устройствам, низкоуровневым сетевым функциям или привилегированным операциям хоста, требуют отдельной проверки. Ещё один источник путаницы — одновременно работающий системный rootful daemon: можно думать, что вы используете rootless, а CLI на самом деле подключён к прежнему сокету. Поэтому контекст и docker info нужно проверять после установки и после смены shell-конфигурации. Если задача — CI или общий сервер, заранее продумайте, какой пользователь владеет daemon, где лежат данные и как запускается user service после перезагрузки.
Совет: Перед миграцией существующих workloads сначала выпишите требования к сети, устройствам и bind mounts — именно они чаще всего выявляют несовместимость.
Минимальный чек-лист готовности
- newuidmap и newgidmap доступны; /etc/subuid и /etc/subgid содержат достаточный диапазон; установщик выполнен без sudo; rootless context активен; docker info подтверждает rootless; тестовый контейнер запускается; нужные порты доступны; bind mounts имеют ожидаемые владельцы; systemd user service переживает перезагрузку; проект не зависит от macvlan или другой функции, несовместимой с rootless.
Практическая миграция проекта на rootless
Не переносите весь стек на rootless за один шаг. Сначала выберите один сервис без устройств и сложной сети, запустите его через активный rootless context и проверьте volumes, published ports, DNS и restart после logout пользователя. Затем сравните владельцев файлов в bind-mounted каталоге: то, что внутри контейнера выглядит как root, на хосте в rootless mapping связано с UID пользователя daemon и subordinate диапазонами. После этого проверьте systemctl --user status docker и перезагрузку хоста с включённым linger, если сервис должен стартовать без интерактивного входа. Следующим шагом переносите сервисы с базами и persistent volumes, но только после резервной копии. Workloads с macvlan, прямым доступом к устройствам или особыми network capabilities тестируйте последними. Такой порядок позволяет быстро понять, ограничение связано с приложением или самим rootless режимом, и даёт простой путь отката без одновременной смены всех переменных инфраструктуры.
Совет: После миграции всегда проверяйте `docker context show` и `docker info`: наличие старого rootful daemon легко маскирует ошибочно выбранный сокет.
Как не перепутать rootless daemon с обычным rootful Docker
На одном хосте могут одновременно существовать системный Docker daemon и rootless daemon пользователя, поэтому команда `docker ps` сама по себе ничего не доказывает. После установки выполните `docker context show`, затем `docker info` и проверьте раздел Security Options: там должен присутствовать `rootless`. Сравните сокет, к которому подключается клиент, с ожидаемым `$XDG_RUNTIME_DIR/docker.sock`, обычно это `/run/user/$UID/docker.sock`. Если системный daemon оставлен запущенным, не полагайтесь на привычку и явно контролируйте context в shell, скриптах и CI. Ещё одна проверка — остановить пользовательский сервис `systemctl --user stop docker` и убедиться, что команды в rootless context перестали обращаться к daemon; после запуска сервис должен снова стать доступен. Для автозапуска используйте пользовательский systemd unit и linger, как описано в Docker Docs, а не системный unit с `User=`. Такой тест особенно полезен перед переносом production-сервиса: он подтверждает не только то, что контейнер стартует, но и то, что оператор действительно работает с непривилегированным daemon, ради которого режим и включался.
Что учитывать
Rootless меняет модель взаимодействия с сетью, cgroups, файловыми правами и некоторыми драйверами. Например, Docker прямо указывает, что macvlan не поддерживается в rootless mode. Приложения, которым нужен прямой доступ к устройствам, низкоуровневым сетевым функциям или привилегированным операциям хоста, требуют отдельной проверки. Ещё один источник путаницы — одновременно работающий системный rootful daemon: можно думать, что вы используете rootless, а CLI на самом деле подключён к прежнему…
Источники и проверка
Фактическая часть сверена по первичным источникам (в т.ч. Rootless mode). Пример и формулировки — редакция N1RO на 2026-09-21.