Чтобы установить 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.
# 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Удалите конфликтующие пакеты
Пакеты 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Добавьте ключ подписи 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Подключите репозиторий
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Установите пакеты
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Проверьте, что 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:
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, служба здесь сама не запускается:
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 и начните новый сеанс:
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 обращаются друг к другу по имени сервиса через сеть проекта, и публиковать порт для этого не нужно.
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 проверяет эту цепочку раньше собственных правил и не трогает то, что вы в неё добавили. Фильтровать нужно по исходному порту назначения, потому что к этому моменту адрес в пакете уже переписан:
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 с открытым исходным кодом делает именно это автоматически.
*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 МБ:
{
"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, обновите скрипт или добавьте небольшую обёртку:
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.