Установка Docker на Ubuntu 24.04/22.04 VPS: официальный способ
- 3 октября 2026 г.
- 09:00
- Автор: Adrien Roche
- Уроки

Перед началом: KVM VPS, поддерживаемая Ubuntu и пользователь с sudo
Docker Engine не поставляется со своим ядром. Каждый контейнер использует ядро хоста и опирается на namespaces, cgroups и netfilter, поэтому демону нужен VPS, где ядро принадлежит вам. Именно это даёт KVM (полная виртуализация) VPS. На контейнерных тарифах на базе OpenVZ или LXC ядро принадлежит провайдеру, и Docker либо отказывается запускаться, либо работает лишь при включённой вложенности. Проверьте это до установки чего-либо:
systemd-detect-virt # expect: kvm
. /etc/os-release && echo "$VERSION_CODENAME" # noble (24.04) or jammy (22.04)
uname -m # x86_64 or aarch64
Docker выпускает пакеты для 64-битных Ubuntu 24.04 LTS (noble) и 22.04 LTS (jammy) на архитектурах x86_64 и arm64. Также нужен пользователь с правами sudo; разделы про группу docker и rootless-режим ниже предполагают обычную учётную запись, а не root.
Установка Docker Engine из официального apt-репозитория
Есть четыре распространённых способа установить Docker на Ubuntu, и лишь один из них Docker документирует и поддерживает для серверов:
| Способ | Пакет | Вывод |
|---|---|---|
| apt-репозиторий Docker | docker-ce с download.docker.com | Рекомендуется: актуальные релизы, обновления через apt upgrade, плагины Compose и Buildx в комплекте. |
| Репозиторий universe Ubuntu | docker.io | Работает, но сборка Ubuntu отстаёт от апстрима и не содержит плагинов. |
| Snap | snap install docker | Изолированная установка со своими путями; частый источник неожиданных ошибок «permission denied». На серверах избегайте. |
| Скрипт быстрой установки | get.docker.com | Те же пакеты, но код без проверки передаётся в root-шелл. Только для одноразовых машин. |
Шаг 1: удалите конфликтующие пакеты
Если в образе VPS уже есть docker.io из Ubuntu, старый docker-compose или podman-docker, удалите их, чтобы две сборки не боролись за /usr/bin/docker. Этот цикл взят из документации Docker и безвреден на чистой системе; каталог /var/lib/docker он не трогает:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove $pkg
done
Шаг 2: добавьте GPG-ключ Docker и источник apt
Ключ кладётся в /etc/apt/keyrings/ и указывается через signed-by=, что ограничивает доверие одним репозиторием вместо глобального доверия через устаревший apt-key. Кодовое имя читается из /etc/os-release, поэтому один и тот же блок работает и на 24.04, и на 22.04:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
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
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Ошибка подписи на последнем apt-get update почти всегда означает, что файл ключа недоступен для чтения; повторите строку с chmod.
Шаг 3: установите движок и его плагины
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker-ce даёт демон, docker-ce-cli даёт клиент, containerd.io даёт рантайм под ними, а два плагина дают docker buildx и docker compose. В Ubuntu post-install-скрипт пакета сразу запускает docker.service и включает автозапуск при загрузке.
Шаг 4: проверка через hello-world
sudo docker run hello-world
docker --version
sudo docker info | head -n 20
hello-world служит окончательным тестом: клиент связывается с демоном, демон скачивает крошечный образ с Docker Hub, создаёт контейнер, запускает его и передаёт вывод обратно. Если вы видите «Hello from Docker!», работают все уровни. На исправной установке 24.04 или 22.04 команда docker info показывает Storage Driver: overlay2 и Cgroup Version: 2.
Запуск Docker без sudo: группа docker
Демон слушает Unix-сокет /var/run/docker.sock, принадлежащий root:docker, поэтому члены группы docker могут пользоваться CLI без sudo:
sudo groupadd docker # usually exists already; harmless if it does
sudo usermod -aG docker $USER
newgrp docker # or log out and back in
docker run hello-world
Осознайте, какие права вы только что выдали. Любой, кто имеет доступ к этому сокету, может выполнить docker run -v /:/host --privileged ... и прочитать или перезаписать любой файл на VPS, поэтому членство в группе docker равнозначно правам root, причём без запроса пароля и без записи в журнал sudo. Относитесь к нему в точности как к доступу через sudo; наше руководство о смене пользователя и повышении привилегий в Ubuntu объясняет, почему это различие важно на многопользовательской машине.
Плагин Docker Compose
Пакет docker-compose-plugin предоставляет Compose v2 в виде подкоманды docker compose (через пробел). Старый бинарник на Python docker-compose снят с поддержки, и ставить его рядом не стоит. Проверьте версию, затем протестируйте на минимальном compose.yaml:
docker compose version
mkdir -p ~/web && cd ~/web
cat > compose.yaml <<'EOF'
services:
web:
image: nginx:alpine
ports:
- "127.0.0.1:8080:80"
restart: unless-stopped
EOF
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080
docker compose down
Две детали выбраны намеренно: restart: unless-stopped возвращает контейнер к жизни после перезагрузки, а порт привязан к 127.0.0.1, а не ко всем интерфейсам; причины объясняются в разделе про фаервол.
Rootless-режим: демон, работающий не от root
В rootless-режиме демон и контейнеры работают внутри пользовательского namespace, поэтому побег из контейнера приводит в непривилегированную учётную запись, а не к root. Это правильный выбор, когда VPS используют несколько человек. Требуются диапазоны subordinate UID/GID (Ubuntu создаёт их для обычных пользователей в /etc/subuid и /etc/subgid), утилиты uidmap, пользовательская сессия D-Bus и дополнительные rootless-пакеты Docker:
sudo apt-get install -y uidmap dbus-user-session docker-ce-rootless-extras
grep "^$USER:" /etc/subuid /etc/subgid # each should show a range of 65536 IDs
# optional: stop the system-wide daemon if you only want rootless
sudo systemctl disable --now docker.service docker.socket
dockerd-rootless-setuptool.sh install
Скрипт настройки создаёт systemd-юнит для пользователя и выводит две переменные, нужные вашей оболочке. Добавьте их в ~/.bashrc, затем сделайте так, чтобы пользовательский демон стартовал при загрузке без входа в систему:
export PATH=/usr/bin:$PATH
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
systemctl --user enable docker
sudo loginctl enable-linger $(whoami)
У rootless-режима есть реальные ограничения: порты ниже 1024 нельзя опубликовать, пока вы не выполните sudo setcap cap_net_bind_service=ep $(which rootlesskit) и не перезапустите пользовательский демон; overlay-сети недоступны; данные лежат в ~/.local/share/docker. В Ubuntu 24.04 AppArmor ограничивает непривилегированные user namespaces; deb-пакеты содержат нужный rootlesskit профиль, но при установке из статического бинарника его придётся добавить вручную, как описано в документации по rootless-режиму.
Поведение при загрузке, хранилище и ротация логов
Работают ли ваши контейнеры после перезагрузки, определяют две отдельные вещи: демон должен быть включён, а у каждого контейнера должна быть политика перезапуска. Пакеты Ubuntu включают службу за вас; проверьте это, а если состояния юнитов покажутся непонятными, наш справочник по просмотру служб через systemctl разбирает каждый столбец:
systemctl is-enabled docker.service containerd.service
sudo systemctl enable docker.service containerd.service # only if the line above said disabled
Контейнеры, запущенные без --restart, после перезагрузки остаются выключенными; используйте --restart unless-stopped в командной строке или restart: unless-stopped в Compose для всего постоянного.
Всё, что хранит Docker (слои образов, файловые системы контейнеров, тома, логи), лежит в /var/lib/docker, и на небольшом VPS именно этот каталог заполняет диск. Следите за ним через docker system df, освобождайте висящие слои командой docker system prune и читайте запрос подтверждения, прежде чем добавлять -a: этот флаг удаляет и все образы, не используемые запущенными контейнерами. Если у VPS есть второй диск, укажите на него data-root в /etc/docker/daemon.json до того, как скачаете что-то объёмное.
Логи заслуживают отдельного предупреждения. Драйвер по умолчанию json-file пишет каждую строку stdout контейнера в /var/lib/docker/containers/<id>/<id>-json.log и не выполняет ротацию, пока вы её не настроите. Болтливый контейнер может съесть весь диск за неделю. Задайте общие для демона лимиты в первый же день:
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" },
"live-restore": true
}
EOF
sudo systemctl restart docker
Параметры логирования применяются к контейнерам, созданным после перезапуска, поэтому долгоживущие контейнеры нужно один раз пересоздать. live-restore позволяет перезапускать демон для обновлений, не убивая работающие контейнеры.
Docker и ufw: опубликованные порты обходят ваш фаервол
Именно на этом спотыкается большинство владельцев публичных VPS. Docker управляет своими правилами iptables: когда вы публикуете порт через -p 8080:80, демон вставляет DNAT-правило в цепочку PREROUTING таблицы nat и разрешающее правило в FORWARD. Правила ufw живут в INPUT, через который перенаправляемый трафик не проходит. Поэтому ufw deny 8080 не даёт эффекта, а контейнер с базой данных, опубликованный на 0.0.0.0:5432, доступен из всего интернета, хотя ufw сообщает, что порт закрыт. Ищите 0.0.0.0: в столбце PORTS вывода docker ps или запустите ss -tlnp; наше руководство по проверке открытых портов в Linux показывает, как читать этот вывод и подтвердить доступность снаружи.
Два чистых решения, в порядке предпочтения:
- Привяжите опубликованные порты к loopback.
-p 127.0.0.1:8080:80оставляет сервис доступным только с самого VPS, обычно за обратным прокси вроде nginx или Caddy, который вы открываете осознанно. Контейнерам, которые общаются только друг с другом,-pне нужен вовсе. - Фильтруйте в цепочке
DOCKER-USER. Docker обрабатывает эту цепочку до своих правилFORWARDи никогда её не переписывает. Поскольку к моменту попадания пакета сюда DNAT уже выполнен, сопоставляйте исходный порт через conntrack:
sudo iptables -I DOCKER-USER -i eth0 ! -s 203.0.113.10 -p tcp \
-m conntrack --ctorigdstport 8080 --ctdir ORIGINAL -j DROP
Замените eth0 на свой публичный интерфейс, а 203.0.113.10 замените на адрес, которому разрешён доступ. Эти правила не сохраняются между перезагрузками; сохраните их с помощью пакета iptables-persistent. Установка "iptables": false в daemon.json ломает сеть контейнеров так, что отладка становится крайне трудной; не трогайте этот параметр.
Полное удаление Docker
Сначала вычистите пакеты, затем удалите каталоги с данными, которые apt намеренно оставляет на месте:
sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker /var/lib/containerd
sudo rm -f /etc/apt/sources.list.d/docker.list /etc/apt/keyrings/docker.asc
sudo apt-get autoremove -y
Для rootless-установки сначала выполните dockerd-rootless-setuptool.sh uninstall от имени пользователя, а затем удалите ~/.local/share/docker.
Всё это предполагает сервер, где у вас есть root, вы управляете ядром и можете переписывать iptables, ни у кого не спрашивая. Если вам нужна такая машина, KVM Linux VPS с полным root-доступом от rdp.monster поставляется с Ubuntu 24.04 или 22.04, выделенными CPU и RAM, безлимитным трафиком (fair-use), без KYC, с оплатой криптовалютой, от $8.99 в месяц, и выдаётся примерно через 10 секунд после подтверждения платежа, так что проверку hello-world из этой статьи вы сможете запустить на своём сервере сразу после оформления заказа.
Часто задаваемые вопросы
Какую версию Docker ставит apt в Ubuntu и как её обновлять?
apt-get install docker-ce ставит новейший стабильный релиз, доступный для вашего кодового имени Ubuntu, а каждый последующий sudo apt-get update && sudo apt-get upgrade обновляет его. Выполните docker version, чтобы увидеть версии клиента и сервера. Чтобы зафиксировать конкретный релиз, посмотрите кандидатов через apt-cache madison docker-ce, установите docker-ce=<version> вместе с соответствующим docker-ce-cli, а затем выполните apt-mark hold для обоих пакетов.Почему появляется ошибка «permission denied while trying to connect to the Docker daemon socket»?
root:docker, поэтому обычный пользователь получает permission denied. Либо добавляйте к командам sudo, либо включите себя в группу через sudo usermod -aG docker $USER и начните новую сессию входа (или выполните newgrp docker), поскольку изменения групп действуют только в новых сессиях. Если ошибка сохраняется, проверьте членство командой groups, убедитесь, что демон работает, через systemctl status docker, и проверьте, что DOCKER_HOST не указывает на несуществующий rootless-сокет.Что выбрать на Ubuntu Server: установку Docker через snap или apt?
daemon.json и данных, а темп обновлений задаёт snapd, а не вы. Эти особенности проявляются загадочными ошибками permission denied и сбоями bind-монтирования. Пакеты apt следуют стандартным соглашениям Ubuntu, нормально интегрируются с systemd и получают обновления апстрима через тот же apt upgrade, который вы и так запускаете.Сколько RAM и дискового пространства нужно VPS для Docker?
/var/lib/docker, и 20 ГБ заканчиваются быстро без docker system prune и ротации логов. Выбирайте выделенные CPU и RAM вместо общих burst-ресурсов, поскольку сборки дают резкие пики, а контейнеры плохо переносят своп.Adrien Roche, Редактор по инфраструктуре и хостингу
Системный инженер с более чем 10-летним опытом эксплуатации парков Windows Server и Linux. Адриен ведёт документацию по инфраструктуре rdp.monster и пишет наши руководства по RDP, VPS-хостингу, администрированию серверов, сетям и инструментам приватности.




