Руководства

Установка Docker на Ubuntu 24.04 и Debian 12/13

Как установить Docker и Docker Compose на Ubuntu 24.04 и Debian 12/13 из официального репозитория, запускать docker без sudo и не дать ему обойти UFW.

Опубликовано ~11 мин чтения

Чтобы установить Docker на Ubuntu 24.04 или Debian 12/13, удалите конфликтующие пакеты дистрибутива, добавьте ключ подписи Docker и его apt-репозиторий на download.docker.com, затем установите docker-ce вместе с CLI, containerd.io и плагинами Buildx и Compose. Демон запустится сам, а sudo docker run --rm hello-world подтвердит, что всё работает. Блок ниже делает всю работу целиком на Ubuntu 24.04 и 22.04 и на Debian 12 и 13: дистрибутив и его кодовое имя (noble, jammy, bookworm или trixie) он берёт из /etc/os-release.

Ubuntu 24.04 · 22.04 · Debian 12 · 13
# 1. удаляем конфликтующие пакеты
#    (сообщения "not installed" и "Unable to locate package" здесь не ошибка)
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
  sudo apt-get remove -y $pkg
done

# 2. ключ подписи Docker
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
. /etc/os-release                  # задаёт $ID (ubuntu или debian) и $VERSION_CODENAME
sudo curl -fsSL https://download.docker.com/linux/$ID/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# 3. репозиторий Docker
sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/$ID
Suites: $VERSION_CODENAME
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

# 4. Engine, CLI, containerd, Buildx и Compose
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 5. проверка
sudo docker run --rm hello-world
docker --version && docker compose version

На первом шаге apt почти наверняка пожалуется на пакеты, которых в системе нет. Это нормально. В английской локали сообщения выглядят как Package 'docker.io' is not installed, so not removed и E: Unable to locate package docker-compose-v2, в русской — Пакет «docker.io» не установлен, поэтому не может быть удалён и E: Невозможно найти пакет docker-compose-v2.

Если hello-world вывел «Hello from Docker!», движок работает. Ниже — что делает каждый шаг, как поставить Docker на Rocky Linux и как справиться с тремя вещами, на которых спотыкаются на свежем сервере: sudo, файрвол и диск.

Какой способ установки выбрать?

Поставить Docker на сервер можно тремя распространёнными способами, и они не равноценны:

  • Пакет дистрибутива docker.io (apt install docker.io). Docker Engine в сборке и с патчами от Ubuntu или Debian. Обычно он отстаёт от релизов самого Docker, а Compose и Buildx приходят отдельными пакетами с другими именами. Для быстрой пробы подойдёт.
  • Официальный apt-репозиторий Docker — способ из этой инструкции. Свежие релизы, все компоненты из одного источника, обновления вместе с остальной системой, и именно такую установку подразумевают документация Docker и большинство руководств. Разумный выбор по умолчанию для сервера, который будет работать долго.
  • Скрипт быстрой установки с get.docker.com. Он подключает тот же репозиторий одной командой, ничего не спрашивая. Для продакшена Docker его не рекомендует; он описан в статье docker: command not found (англ.).

Что бы вы ни выбрали, используйте что-то одно. docker.io и docker-ce конфликтуют, поэтому первый шаг сначала удаляет пакеты дистрибутива. Snap (snap install docker) на сервере лучше не использовать: он ограничивает доступ к файлам домашним каталогом и не создаёт группу docker.

Как установить Docker на Ubuntu 24.04 или 22.04?

Та же процедура, но с адресами Ubuntu, прописанными явно, — так видно, что делает каждый шаг. Она без изменений работает на 24.04 (noble) и 22.04 (jammy).

  1. 1Удалите конфликтующие пакеты

    Пакеты Ubuntu docker.io, docker-compose-v2, containerd и runc конфликтуют с пакетами Docker. Их удаление не трогает образы и тома в /var/lib/docker.

    Ubuntu
    for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
      sudo apt-get remove -y $pkg
    done
  2. 2Добавьте ключ подписи Docker
    Ubuntu
    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

    Ключ лежит в /etc/apt/keyrings, и на него ссылается только источник Docker, поэтому за пакеты из других репозиториев он поручиться не может. Это современная замена устаревшему apt-key add.

  3. 3Подключите репозиторий
    Ubuntu
    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 $VERSION_CODENAME)
    Components: stable
    Architectures: $(dpkg --print-architecture)
    Signed-By: /etc/apt/keyrings/docker.asc
    EOF

    Это формат deb822, в котором Ubuntu 24.04 хранит и собственные источники. Однострочный вариант в /etc/apt/sources.list.d/docker.list работает так же; используйте один из двух, а не оба сразу. На производных дистрибутивах вроде Linux Mint замените VERSION_CODENAME на UBUNTU_CODENAME.

  4. 4Установите пакеты
    Ubuntu
    sudo apt-get update
    apt-cache policy docker-ce        # кандидат должен быть с download.docker.com
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    Если apt отвечает E: Unable to locate package docker-ce (в русской локали — E: Невозможно найти пакет docker-ce), репозиторий не подключён или после его добавления не был выполнен sudo apt-get update. Вывод apt-cache policy docker-ce покажет, видит ли apt пакет вообще.

  5. 5Проверьте, что Docker запущен
    Ubuntu
    systemctl status docker --no-pager       # active (running), автозапуск включён
    sudo docker run --rm hello-world
    sudo docker version                      # показывает и Client, и Server

Как установить Docker на Debian 12 и 13?

Точно так же, как на Ubuntu, только в обоих адресах — debian. Docker собирает пакеты для Debian 12 (bookworm) и Debian 13 (trixie), поэтому меняется только кодовое имя из /etc/os-release:

Debian 12 · 13 — после цикла удаления из шага 1
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/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

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

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  • Нет sudo? В Debian, установленном с паролем root, sudo нет. Выполняйте команды от root без него или загляните в статью sudo: command not found (англ.).
  • iptables в Debian 12 и 13. docker-ce тянет за собой пакет iptables, который в обоих релизах работает поверх nftables. Docker сразу использует его для своих правил, настраивать ничего не нужно.
  • «The repository … does not have a Release file» (в русской локали — Репозиторий «…» не содержит файла Release.) значит, что у Docker нет пакетов для этого кодового имени или что в адресе на машине с Debian стоит ubuntu (или наоборот). Проверьте командой cat /etc/apt/sources.list.d/docker.sources.

Как установить Docker на Rocky Linux 9?

На Rocky, AlmaLinux и RHEL подключите .repo-файл Docker через dnf config-manager. В отличие от Debian и Ubuntu, служба здесь сама не запускается:

Rocky Linux 9
sudo dnf remove -y podman runc        # только если установлены: они конфликтуют
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo docker run --rm hello-world

На CentOS Stream 9 путь к репозиторию — /linux/centos/docker-ce.repo. Оговорка про файрвол ниже относится и к firewalld: опубликованные контейнером порты остаются доступными, даже если публичная зона firewalld их не перечисляет.

Как запускать docker без sudo?

Добавьте пользователя в группу docker и начните новый сеанс:

docker без sudo
sudo usermod -aG docker $USER
# выйдите и войдите снова (или newgrp docker — только для этой оболочки)
docker run --rm hello-world

Почему Docker обходит UFW и порты контейнеров открыты?

Потому что Docker пишет собственные правила iptables, и трафик до правил UFW просто не доходит. Когда вы публикуете порт (-p 8080:80 или ports: в Compose), Docker добавляет правило NAT, которое перенаправляет входящие пакеты на адрес контейнера. Дальше эти пакеты идут через цепочку FORWARD ядра, а не через INPUT, где стоят разрешающие и запрещающие правила UFW. Поэтому ufw deny 8080 ничего не меняет, ufw status этот порт даже не показывает, а база данных или админка, опубликованная таким образом, открыта всему интернету.

Это самая частая ошибка с Docker на VPS. Проверяйте со второй машины, а не с самого сервера:

со своего компьютера
nc -zv 203.0.113.10 8080          # "succeeded" = порт доступен из интернета

Другие способы проверки и то, как читать их результат, — в статье как проверить открытые порты в Linux (англ.). Исправить это правильно можно двумя способами.

1. Публикуйте внутренние сервисы на 127.0.0.1 или не публикуйте вовсе. Порт, привязанный к адресу loopback, доступен только программам на самом сервере — например, обратному прокси на хосте (англ.). Контейнеры одного проекта Compose обращаются друг к другу по имени сервиса через сеть проекта, и публиковать порт для этого не нужно.

compose.yaml
services:
  app:
    image: nginx
    ports:
      - "127.0.0.1:8080:80"        # доступен только с самого сервера
  db:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: change-me
    # без "ports:" — app обращается к нему как db:5432 в сети Compose

В docker run это -p 127.0.0.1:8080:80. Для подстраховки можно задать "ip": "127.0.0.1" в /etc/docker/daemon.json — тогда loopback станет адресом по умолчанию для всех публикуемых портов, а порт, который должен быть публичным, придётся указывать явно, в виде 0.0.0.0:443:443.

2. Фильтруйте в цепочке DOCKER-USER, если порт должен оставаться публичным, но только для некоторых адресов. Docker проверяет эту цепочку раньше собственных правил и не трогает то, что вы в неё добавили. Фильтровать нужно по исходному порту назначения, потому что к этому моменту адрес в пакете уже переписан:

порт 8080 только для 203.0.113.7
ip route show default             # ваш публичный интерфейс, например eth0 или ens18

sudo iptables -I DOCKER-USER -i eth0 ! -s 203.0.113.7 -p tcp \
  -m conntrack --ctorigdstport 8080 --ctdir ORIGINAL -j DROP

Правила, добавленные вручную, исчезают после перезагрузки. Чтобы они сохранились, добавьте их отдельным блоком в конец /etc/ufw/after.rules и выполните sudo ufw reload; утилита ufw-docker с открытым исходным кодом делает именно это автоматически.

конец /etc/ufw/after.rules
*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -i eth0 ! -s 203.0.113.7 -p tcp -m conntrack --ctorigdstport 8080 --ctdir ORIGINAL -j DROP
-A DOCKER-USER -j RETURN
COMMIT

Как не дать логам контейнеров забить диск?

Ограничьте их в /etc/docker/daemon.json. Драйвер логов Docker по умолчанию, json-file, хранит всё, что контейнер пишет в stdout, без ограничения по размеру, так что один болтливый контейнер способен заполнить небольшой диск за несколько недель. Ротация по 10 МБ с тремя файлами ограничивает логи каждого контейнера примерно 30 МБ:

/etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
применить
sudo dockerd --validate --config-file=/etc/docker/daemon.json   # "configuration OK"
sudo systemctl restart docker          # останавливает контейнеры; политики перезапуска поднимут их снова
docker compose up -d --force-recreate  # в каждом проекте Compose: у старых контейнеров остаются старые настройки

Если файл уже существует, допишите ключи, а не перезаписывайте его, и оставьте значения строками в кавычках. Ограничения распространяются только на контейнеры, созданные после изменения, — поэтому последняя строка пересоздаёт их. Посмотреть, что занимает место:

куда делось место?
docker system df                                   # образы, контейнеры, тома, кеш сборки
sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail
docker image prune -a                              # неиспользуемые образы (сначала спросит)
docker builder prune                               # кеш сборки

Если диск уже заполнен, начните со статьи No space left on device.

docker compose или docker-compose: что использовать?

Используйте docker compose (через пробел). Это Compose v2 — плагин Docker CLI, который ставит пакет docker-compose-plugin, так что отдельно устанавливать Docker Compose на Ubuntu не нужно. docker-compose через дефис — это Compose v1, отдельная программа на Python, которая перестала получать обновления в 2023 году. YAML-файлы те же, изменилась только команда. Если старый скрипт всё ещё вызывает docker-compose, обновите скрипт или добавьте небольшую обёртку:

/usr/local/bin/docker-compose (по желанию)
printf '#!/bin/sh\nexec docker compose "$@"\n' | sudo tee /usr/local/bin/docker-compose >/dev/null
sudo chmod +x /usr/local/bin/docker-compose

Как обновить или удалить Docker?

Docker обновляется вместе с остальной системой, потому что его пакеты приходят из apt-репозитория. Но unattended-upgrades в Debian и Ubuntu по умолчанию берёт пакеты только из собственных архивов дистрибутива, так что сам Docker автоматически не обновится. Время от времени запускайте обновление вручную:

обновление
sudo apt-get update
sudo apt-get install --only-upgrade docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
# или просто: sudo apt-get upgrade

Обновление перезапускает демон, а вместе с ним и все контейнеры. Задайте сервисам политику перезапуска (restart: unless-stopped в Compose), чтобы они поднимались сами. Параметр "live-restore": true в daemon.json позволяет контейнерам продолжать работу, пока перезапускается демон, — например, при патч-обновлении.

Чтобы удалить Docker полностью, сначала скопируйте данные из томов, которые ещё нужны: вторая строка ниже безвозвратно удаляет все образы, контейнеры и тома.

удаление
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 /etc/apt/sources.list.d/docker.sources /etc/apt/keyrings/docker.asc

Что нужно VPS, чтобы на нём работал Docker?

Собственное ядро. Docker опирается на пространства имён, cgroups, overlay-файловые системы и netfilter, и виртуальная машина KVM управляет всем этим сама, как и физический сервер. При контейнерной виртуализации вроде OpenVZ или LXC Docker часто не запускается или требует обходных решений; в чём разница и как узнать, что у вас, — в сравнении KVM и OpenVZ (англ.). Сам демон лёгкий. Размер сервера определяют контейнеры, которые вы запускаете, плюс место на диске под их образы.

В VMHeaven шаблоны Ubuntu 24.04 и 22.04, Debian 13 и 12 и Rocky Linux 9 принимают команды выше без изменений. Ubuntu 20.04 и Debian 11 по-прежнему доступны, но у обеих закончилась основная поддержка, так что новый хост под Docker начинайте на актуальном релизе. Начального тарифа Standard KVM — 2 vCore, 4 ГБ RAM и 20 ГБ хранилища — хватает на несколько небольших контейнеров, например обратный прокси, веб-приложение и его базу данных. Тарифы по дистрибутивам собраны на страницах VPS на Ubuntu и Debian VPS.

Частые вопросы

Почему apt пишет «Невозможно найти пакет docker-ce»?

Это русская версия ошибки «E: Unable to locate package docker-ce»: apt не видит репозиторий Docker. Либо он не подключён, либо после его добавления не был выполнен sudo apt-get update. Проверьте файл /etc/apt/sources.list.d/docker.sources и вывод apt-cache policy docker-ce — кандидат должен приходить с download.docker.com.

Как установить Docker Compose на Ubuntu?

Отдельно ничего ставить не нужно: пакет docker-compose-plugin из репозитория Docker устанавливается вместе с docker-ce, а команда пишется через пробел — docker compose. Старый docker-compose через дефис — это Compose v1, который не обновляется с 2023 года; YAML-файлы у обеих версий одни и те же.

Почему порт контейнера открыт, хотя UFW его закрывает?

Docker пишет собственные правила iptables для опубликованных портов: входящие пакеты перенаправляются в контейнер и проходят через цепочку FORWARD, а не INPUT, где стоят правила UFW, поэтому UFW их не видит. Публикуйте внутренние сервисы только на 127.0.0.1 (например, -p 127.0.0.1:8080:80), не публикуйте порт, если он нужен только другим контейнерам, а публичные порты фильтруйте в цепочке DOCKER-USER.

Читайте также

Все статьи раздела