RDP Monster

Установка Docker на Ubuntu 24.04/22.04 VPS: официальный способ

Установка Docker на Ubuntu 24.04/22.04 VPS: официальный способ

Перед началом: 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-репозиторий Dockerdocker-ce с download.docker.comРекомендуется: актуальные релизы, обновления через apt upgrade, плагины Compose и Buildx в комплекте.
Репозиторий universe Ubuntudocker.ioРаботает, но сборка Ubuntu отстаёт от апстрима и не содержит плагинов.
Snapsnap 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 показывает, как читать этот вывод и подтвердить доступность снаружи.

Два чистых решения, в порядке предпочтения:

  1. Привяжите опубликованные порты к loopback. -p 127.0.0.1:8080:80 оставляет сервис доступным только с самого VPS, обычно за обратным прокси вроде nginx или Caddy, который вы открываете осознанно. Контейнерам, которые общаются только друг с другом, -p не нужен вовсе.
  2. Фильтруйте в цепочке 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 и как её обновлять?

Репозиторий ставит последний стабильный Docker Engine, а apt upgrade поддерживает его в актуальном состоянии.
При настроенном apt-репозитории Docker команда 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»?

Ваш пользователь не может читать /var/run/docker.sock; вступите в группу docker или используйте sudo.
Сокет демона принадлежит root:docker, поэтому обычный пользователь получает permission denied. Либо добавляйте к командам sudo, либо включите себя в группу через sudo usermod -aG docker $USER и начните новую сессию входа (или выполните newgrp docker), поскольку изменения групп действуют только в новых сессиях. Если ошибка сохраняется, проверьте членство командой groups, убедитесь, что демон работает, через systemctl status docker, и проверьте, что DOCKER_HOST не указывает на несуществующий rootless-сокет.

Что выбрать на Ubuntu Server: установку Docker через snap или apt?

Используйте apt с репозиторием Docker; snap добавляет причуды изоляции без выигрыша на сервере.
Предпочтительнее apt из собственного репозитория Docker. Snap строго изолирован: он не может читать файлы вне вашего домашнего каталога без дополнительных подключений интерфейсов, использует другие пути для daemon.json и данных, а темп обновлений задаёт snapd, а не вы. Эти особенности проявляются загадочными ошибками permission denied и сбоями bind-монтирования. Пакеты apt следуют стандартным соглашениям Ubuntu, нормально интегрируются с systemd и получают обновления апстрима через тот же apt upgrade, который вы и так запускаете.

Сколько RAM и дискового пространства нужно VPS для Docker?

Сам движок лёгкий; подбирайте VPS под контейнеры и их образы.
Docker Engine в простое занимает несколько десятков мегабайт RAM, поэтому реальный бюджет определяет ваша нагрузка. Одно небольшое веб-приложение с базой данных спокойно работает в 2 ГБ; более тяжёлые стеки или несколько проектов требуют 4 ГБ и больше. Диск важнее, чем принято думать: образы, кеш сборки и логи попадают в /var/lib/docker, и 20 ГБ заканчиваются быстро без docker system prune и ротации логов. Выбирайте выделенные CPU и RAM вместо общих burst-ресурсов, поскольку сборки дают резкие пики, а контейнеры плохо переносят своп.

Adrien Roche, Редактор по инфраструктуре и хостингу

Системный инженер с более чем 10-летним опытом эксплуатации парков Windows Server и Linux. Адриен ведёт документацию по инфраструктуре rdp.monster и пишет наши руководства по RDP, VPS-хостингу, администрированию серверов, сетям и инструментам приватности.

Регистрация в программе для реселлеров

Ваши данные

Если у вас есть вопросы, contact us by clicking here !
Имя и фамилия(Обязательно)
Укажите ваш email: у вас должен быть аккаунт на manager.rdp.monster !

Ваша компания

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

Мы используем файлы cookie!

Мы используем файлы cookie, чтобы улучшить ваш опыт просмотра, предлагать персонализированную рекламу или контент и анализировать наш трафик. Нажимая «Принять», вы соглашаетесь с использованием файлов cookie.