Короткий ответ: на Ubuntu 24.04 ставьте только Docker CE из официального репозитория download.docker.com: пакеты docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, docker-compose-plugin. Команда — docker compose (плагин v2), не docker-compose. Скрипт get.docker.com для продакшена не используйте. Сначала снесите конфликты docker.io, docker-compose, docker-compose-v2.
Гайд для чистого VPS Ubuntu 24.04 LTS, факты на 13–14 сентября 2026. Базовая настройка сервера — в первой настройке Ubuntu. Дальше по серии Docker нужен для n8n. Команды копируйте как есть. После каждого шага есть проверка.
Что ставим и чего избегать
Ubuntu в репозитории universe отдаёт пакеты docker.io и docker-compose-v2. Это не Docker CE. Они конфликтуют с официальными пакетами и дают другой набор команд. Официальная инструкция Docker прямо требует снести их до установки CE: Install Docker Engine on Ubuntu.
| Нужно | Не нужно |
|---|---|
| Репозиторий download.docker.com, канал stable | Пакеты Ubuntu: docker.io, docker-compose, docker-compose-v2 |
| Пакеты docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, docker-compose-plugin | Скрипт https://get.docker.com на продакшен-VPS |
Команда docker compose (плагин v2) |
Бинарник docker-compose с дефисом (Compose v1 / отдельный пакет) |
Проверка docker run hello-world и docker compose version |
Публиковать порты в 0.0.0.0 «чтобы заработало», не глядя на ufw |
Пример версии из той же официальной страницы для Ubuntu Noble: docker-ce/noble 5:29.8.0-1~ubuntu.24.04~noble. Это ориентир на дату гайда, не «обязательно заморозить именно этот билд навсегда». Список живых версий всегда смотрите командой apt list --all-versions docker-ce после подключения репозитория.
Скрипт convenience с get.docker.com Docker рекомендует только для тестовых и dev-машин: он ставит latest без вопросов, не заточен под апгрейд уже установленного движка и не заменяет репозиторий apt. На VPS, который будет жить месяцами, ставьте пакеты из apt-репозитория Docker.
Снести конфликтующие пакеты
Даже на «чистом» образе иногда уже есть docker.io из cloud-init или панели хостера. Снесите список из документации целиком. Если пакета нет, apt просто напишет, что удалять нечего — это нормально.
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove -y "$pkg" || true; done
sudo apt update
command -v docker || echo 'docker CLI пока нет — так и должно быть до установки CE'
command -v docker-compose || echo 'docker-compose с дефисом нет — хорошо'
Образы и тома в /var/lib/docker при apt remove не удаляются. На новом VPS каталога обычно нет. Если это переустановка и нужен чистый старт — это уже отдельное решение: данные сами не сотрутся.
Проверка: dpkg -l | grep -E 'docker|containerd|runc' не должен показывать ii на docker.io, docker-compose, docker-compose-v2. Если видите rc — это только конфиги удалённого пакета, на установку CE не мешает.
Подключить репозиторий Docker CE
Ключ и источник — только с download.docker.com. Блок ниже — из официальной инструкции, формат Deb822 (docker.sources), не старый однострочный .list.
sudo apt update
sudo apt install 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
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
apt-cache policy docker-ce | head -n 20
Проверка: в apt-cache policy docker-ce кандидат должен быть с download.docker.com/linux/ubuntu, сюита noble (24.04), канал stable. Если apt предлагает только docker.io из ubuntu.com — файл источника не подхватился, не ставьте пакеты.
Посмотреть линейку CE:
apt list --all-versions docker-ce
В документации Docker на эту дату пример начинается с docker-ce/noble 5:29.8.0-1~ubuntu.24.04~noble. Ваш список может содержать и более новые patch той же мажорной ветки — это нормально. Для продакшена разумнее поставить то, что сейчас в stable, и записать точную строку версии в свои заметки.
Установить пакеты и проверить hello-world
Пять пакетов одним apt, не вычёркивайте compose-plugin и buildx:
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
sudo docker version
sudo docker run hello-world
docker compose version
Что должно получиться:
systemctl status docker—active (running).sudo docker version— и Client, и Server, без ошибки демона.sudo docker run hello-worldскачивает тестовый образ и печатает, что установка успешна; контейнер сразу завершается.docker compose versionпечатаетDocker Compose version v2.... Если команда «не найдена», плагин не встал — не ставьте отдельный пакетdocker-compose.
Если нужен pin как в примере документации:
VERSION_STRING=5:29.8.0-1~ubuntu.24.04~noble
sudo apt install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin
Строку VERSION_STRING берите из apt list --all-versions docker-ce, не выдумывайте суффикс. На Ubuntu 24.04 он вида ~ubuntu.24.04~noble.
Минимальный Compose, чтобы проверить плагин не только версией, но и запуском:
mkdir -p ~/apps/compose-check
cd ~/apps/compose-check
cat > compose.yaml <<'EOF'
services:
hi:
image: hello-world
EOF
sudo docker compose run --rm hi
Снова должно появиться приветствие hello-world. Файл называется compose.yaml — Compose v2 его находит сам. Команда с дефисом docker-compose здесь не нужна и не должна быть установлена.
Группа docker, ufw и порты
Демон Docker всегда работает как root. Сокет /var/run/docker.sock доступен членам группы docker. Официальная страница post-install прямо предупреждает: группа docker даёт привилегии уровня root — см. Linux post-installation и Docker daemon attack surface. На VPS с несколькими людьми в группу кладите только тех, кому можно root.
sudo usermod -aG docker "$USER"
id -nG
echo 'выйдите из SSH и зайдите снова, затем:'
# docker run --rm hello-world
После нового логина id -nG должен содержать docker, а docker run --rm hello-world — работать без sudo. newgrp docker включает группу в текущей сессии, но для постоянства нужен новый вход. Если раньше вызывали sudo docker, каталог ~/.docker может оказаться root: тогда sudo chown "$USER":"$USER" "$HOME/.docker" -R.
Второе предупреждение, его часто пропускают. Опубликованные порты контейнеров обходят ufw. Docker ставит правила в таблицу nat раньше цепочек INPUT/OUTPUT, которыми управляет ufw. Если сделать docker run -p 8080:80 ..., порт 8080 будет открыт с интернета даже при ufw deny 8080. Это не баг вашего конфига, так устроен стек: Packet filtering and firewalls.
- Не публикуйте порты на
0.0.0.0, если сервис должен быть только за nginx. Пишите127.0.0.1:5678:5678, как в гайде по n8n. - Не считайте
ufw statusполной картиной: смотрите ещёss -tulpnиsudo iptables -t nat -L -n. - Правила «поверх Docker» — в цепочке
DOCKER-USER, не в обычных правилах ufw.
Проверка слушающих сокетов после тестового контейнера:
sudo docker ps -a
ss -tulpn | grep docker || true
sudo ufw status verbose
hello-world портов не оставляет. Если позже поднимете панель или БД с -p 5432:5432 без loopback — это дыра, даже при «зелёном» ufw.
После установки ещё раз сверьтесь, что apt тянет CE, а не docker.io:
dpkg -l docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | awk 'NR==1 || /^ii/'
apt-cache policy docker-ce | sed -n '1,15p'
docker compose version
command -v docker-compose && echo 'есть docker-compose с дефисом — удалите пакет' || echo 'дефисного docker-compose нет'
В dpkg -l все пять пакетов — ii. В policy — download.docker.com. docker compose version — v2. Если command -v docker-compose что-то нашёл, это конфликт: снимите пакет и пользуйтесь только пробелом в команде.
Апгрейд CE потом — снова через apt из того же репозитория: sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin. Convenience-скрипт повторно гонять не нужно.
Следующий практический стек: n8n + Postgres + nginx. HTTPS для прокси — Certbot и nginx.
FAQ
Чем docker.io из Ubuntu отличается от docker-ce?
docker.io — пакет дистрибутива, не официальный Docker CE. Он конфликтует с docker-ce, docker-ce-cli и плагинами с download.docker.com. На Ubuntu 24.04 для этого гайда нужен только CE из репозитория Docker.
Почему нельзя docker-compose с дефисом?
Это старый бинарник Compose v1 или пакет Ubuntu docker-compose-v2. Канон — плагин v2: команда docker compose (пробел). Проверка: docker compose version. Пакет docker-compose-plugin ставится вместе с CE.
Можно ли поставить через curl https://get.docker.com | sh?
Для продакшен-VPS — нет. Docker сам помечает скрипт как convenience для dev/test: мало контроля, ставит latest, не предназначен обновлять уже стоящий движок. Ставьте apt-репозиторий и пять пакетов CE.
Почему после ufw deny порт контейнера всё равно открыт?
Публикация портов Docker идёт через nat и обходит правила ufw. Либо не публикуйте порт наружу (bind на 127.0.0.1 и проксируйте nginx), либо фильтруйте в цепочке DOCKER-USER. ufw status здесь не источник истины.
Безопасно ли добавлять себя в группу docker?
Группа docker равна root-доступу к хосту: кто может говорить с docker.sock, может запустить привилегированный контейнер и выйти на файловую систему. На личном VPS это приемлемо. Не добавляйте туда непривилегированных пользователей «чтобы без sudo».