MAATRIX / Блог / Dokploy на Ubuntu 24.04: пошаговая установка

Dokploy на Ubuntu 24.04: пошаговая установка

Dokploy на Ubuntu 24.04: пошаговая установка

MAATRIX

Установщик Dokploy — одна строка, и на чистом образе Ubuntu 24.04 она отрабатывает минуты за три. Ломается обычно не она, а то, что вокруг: Docker из snap, старый docker.io из репозитория Ubuntu, занятый 3000-й порт, отсутствие swap и swarm, который не может выбрать, какой адрес анонсировать. Ниже — установка Dokploy на Ubuntu по шагам, с проверкой после каждого и с текстами ошибок.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что именно ставится и чего Dokploy ждёт от системы

Dokploy — self-hosted PaaS на TypeScript: git-деплой по вебхуку, автоматический Let's Encrypt, базы, шаблоны сервисов. Ключевая деталь, отличающая установку от «поднять ещё один контейнер»: инсталлятор переводит демон Docker в режим кластера, и приложения становятся swarm-сервисами.

КомпонентГде искать
Панельswarm-сервис dokploy, порт 3000
Состояние/etc/dokploy (traefik/, applications/, compose/, logs/)
База и кэшконтейнеры dokploy-postgres и dokploy-redis
Проксиdokploy-traefik, конфиг /etc/dokploy/traefik/traefik.yml
Сеть приложенийoverlay-сеть dokploy-network

Требования: Ubuntu или Debian, amd64 или arm64, root, свободные 80, 443 и 3000. И честно про зрелость: версии вида 0.2x.x, ломающие изменения между релизами случаются, отката миграций базы нет — снапшот перед обновлением обязателен.

Подготовка Ubuntu 24.04: что проверить до установщика

Берите чистый образ: Nginx, Apache или другая панель на борту гарантируют конфликт по 80 и 443. Начните с портов.

ss -tlnp '( sport = :80 or sport = :443 or sport = :3000 )'

Пусто — отлично. Увидели users:(("nginx",pid=812,fd=6)) — сначала systemctl disable --now nginx. Порт 3000 занят чаще, чем кажется.

Обновление без зависания. На 24.04 apt upgrade умеет замереть на синем диалоге Which services should be restarted? — это needrestart, и в неинтерактивной сессии команда висит вечно.

sed -i 's/^#\?\$nrconf{restart}.*/$nrconf{restart} = "a";/' /etc/needrestart/needrestart.conf
apt update && apt -y full-upgrade && apt -y install curl git jq ca-certificates

Docker из snap — убрать: snap list docker, и если пакет есть — snap remove --purge docker. Snap-версия живёт в песочнице, держит данные в /var/snap/docker/common/var-lib-docker и не монтирует произвольные каталоги хоста: bind-mount /etc/dokploy не поднимется, а вместо понятной ошибки вы увидите отказы AppArmor в journalctl -k.

Swap. Облачные образы 24.04 идут без него, swapon --show не выводит ничего. Сборки едят память рывками, и без swap первая же уронит панель.

fallocate -l 4G /swapfile && chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

Часы. timedatectl show -p NTPSynchronized --value должен вернуть yes: расхождение времени ломает выпуск сертификатов Let's Encrypt.

Развернуть за пару минут

Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Dokploy

Docker: почему `apt install docker.io` — плохая идея

Посмотрите, что предлагает система: apt-cache policy docker.io. В noble-updates лежит 26-я ветка, официальный репозиторий Docker отдаёт 28-ю. Плагины docker compose и docker buildx в Ubuntu идут отдельно и отстают сильнее, а Dokploy собирает приложения именно ими.

Установщик поставит Docker и сам, через get.docker.com. Сделать это заранее стоит по другой причине: daemon.json настраивают до инициализации swarm, потом часть параметров меняется только с пересозданием сетей.

curl -fsSL https://get.docker.com | sh
docker compose version

Скрипт подключает официальный репозиторий Docker для noble и ставит docker-ce вместе с плагинами compose и buildx; ручной вариант разобран в установке Docker на Ubuntu 24.04. Проверьте результат: docker info --format '{{.ServerVersion}} {{.Driver}}' должен ответить вроде 28.1.1 overlay2. Драйвер обязан быть overlay2; видите vfs — вы на контейнерной виртуализации (LXC, OpenVZ) без overlayfs, где каждый слой образа копируется целиком: диск разбухает в разы, сборки замедляются кратно. Под Dokploy берите KVM.

Дальше — /etc/docker/daemon.json и systemctl restart docker:

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" },
  "default-address-pools": [ { "base": "10.210.0.0/16", "size": 24 } ]
}

Первое лечит болячку по умолчанию: журналы контейнеров в Ubuntu не ротируются вообще, болтливое приложение пишет десятки гигабайт в /var/lib/docker/containers/*/*-json.log. Второе уводит docker-сети из 10.0.0.0/8: если там же живёт ваш WireGuard, после swarm init маршруты до него пропадут (разбор). И не добавляйте репозиторий Docker в Unattended-Upgrade::Allowed-Origins: автообновление перезапустит docker.service, а с ним все swarm-задачи.

Установка одной командой и проверка результата

Запускать строго от root — sudo -i, затем:

curl -sSL https://dokploy.com/install.sh | sh

На 2 vCPU это 2–4 минуты, почти всё время — скачивание образов, суммарно около 1,2 ГБ. Работайте в tmux: обрыв SSH посреди docker swarm init оставит систему в половинчатом состоянии, и второй заход упрётся в This node is already part of a swarm.

Скрипт проверяет права, ОС и архитектуру, ставит Docker при необходимости, выполняет docker swarm init, создаёт сеть dokploy-network и каталоги в /etc/dokploy, поднимает Postgres, Redis, Traefik и сервис dokploy.

Самый частый обрыв — на инициализации кластера, когда у машины несколько интерфейсов: демон отказывается угадывать и пишет could not choose an IP address to advertise since this system has multiple addresses on different interfaces. Лечится заранее — docker swarm init --advertise-addr 203.0.113.10 с публичным адресом, дальше установщик увидит активный swarm и трогать его не станет.

Проверяем: docker info --format '{{.Swarm.LocalNodeState}}' вернёт active, а docker service ls — примерно это:

ID             NAME      MODE         REPLICAS   IMAGE
n7x2f0a1c9qd   dokploy   replicated   1/1        dokploy/dokploy:latest

Если в REPLICAS стоит 0/1, интерфейс не откроется, и смотреть надо не в docker logs, а в docker service ps dokploy --no-trunc, колонка ERROR: там будет либо task: non-zero exit (1), либо port is already allocated — 3000 всё-таки занят.

Первый вход, домен и HTTPS

Панель слушает 3000. Откройте http://IP_СЕРВЕРА:3000 — там форма регистрации. Первый зарегистрированный пользователь становится владельцем, дальше открытая регистрация закрывается. Не тяните: сервер с открытым 3000 и без администратора — приглашение занять вашу панель.

Пока домена нет, пароль летит по голому HTTP. Аккуратнее прокинуть порт по SSH и зарегистрироваться на http://127.0.0.1:3000:

ssh -L 3000:127.0.0.1:3000 root@203.0.113.10

Дальше домен: заведите A-запись, дождитесь распространения (dig +short dokploy.example.com), в панели укажите домен и почту для Let's Encrypt. Traefik подхватит роутер из /etc/dokploy/traefik/dynamic/, туда же пишется acme.json. Права 644 на этом файле молча выключают резолвер:

The ACME resolver "letsencrypt" is skipped from the resolvers list because:
unable to get ACME account: permissions 644 for acme.json are too open, please use 600

Вторая типовая ошибка — домен недоступен для проверки; смотрим docker logs dokploy-traefik | grep -i acme:

Unable to obtain ACME certificate for domains "dokploy.example.com":
acme: error: 403 :: urn:ietf:params:acme:error:unauthorized ::
Invalid response from http://dokploy.example.com/.well-known/acme-challenge/... : 404

Причин ровно три: A-запись указывает не туда; 80-й порт закрыт фаерволом (HTTP-01-проверка идёт по нему, не по 443); домен проксируется Cloudflare с оранжевым облаком. С Cloudflare сертификат выпускают в режиме DNS only, потом включают прокси и SSL Full (strict) — на Flexible будет редирект по кругу. И помните про лимиты: 5 неудачных проверок в час на домен, 50 сертификатов в неделю, так что отлаживайте на caServer: https://acme-staging-v02.api.letsencrypt.org/directory.

Фаервол, доступ и обслуживание

Базовый набор правил:

ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp
ufw --force enable && ufw status numbered

Порт 3000 сюда не попал: после привязки домена панель открывается по HTTPS. Но закрыть его через ufw deny 3000 не выйдет, и здесь у Dokploy своя специфика. Совет «правьте цепочку DOCKER-USER» для swarm-сервисов не работает: опубликованные через ingress-сеть порты обрабатываются в отдельной цепочке, правило идёт туда.

iptables -I DOCKER-INGRESS 1 -p tcp --dport 3000 ! -s 203.0.113.5 -j DROP

И честно: цепочку перестраивает сам демон, и после systemctl restart docker правило исчезнет — надёжнее закрывать 3000 фаерволом провайдера.

Dokploy не ходит к самому себе по SSH, он работает через сокет /var/run/docker.sock — вход только по ключу и PermitRootLogin prohibit-password ничего не сломают. Зато верно обратное: доступ в панель равен root на сервере, ведь оттуда можно задеплоить контейнер с примонтированным сокетом.

Бэкап — каталог состояния плюс дамп базы:

tar czf /root/dokploy-etc-$(date +%F).tar.gz /etc/dokploy
docker exec dokploy-postgres pg_dump -U dokploy -d dokploy > /root/dokploy-db-$(date +%F).sql

Имя пользователя уточните через docker inspect dokploy-postgres | grep POSTGRES_.

Мусор и логи. Раз в неделю смотрите docker system df, чистка — docker system prune -af --filter "until=168h"; флаг --volumes сносит тома с данными, добавляйте осознанно (куда уходит место). Системный журнал по умолчанию занимает до 10% раздела: поставьте SystemMaxUse=500M в /etc/systemd/journald.conf.

Обновление — кнопка в панели либо docker service update --force --image dokploy/dokploy:latest dokploy. Образ идёт с тегом latest — зафиксировать версию штатно нельзя.

Какой сервер под Dokploy взять в MAATRIX

Практическая деталь: Dokploy есть в каталоге apps.maatrix.io и при заказе ставится на сервер автоматически — вручную вставлять команды не нужно. Автоустановка работает на Ubuntu и Debian, доступы появляются в личном кабинете, раздел «Доступ».

СценарийCPURAMДискЧто реально получится
Минимум2 vCPU2 ГБ40 ГБ NVMeПанель и 1–2 лёгких приложения, swap на 4 ГБ обязателен
Рабочий вариант2–4 vCPU4 ГБ80 ГБ NVMe4–6 приложений с базой, сборки проходят спокойно
Комфорт4–8 vCPU8–16 ГБ160 ГБ NVMeДесятки сервисов, параллельные сборки, нагруженный Postgres

Логика без округления вверх. Служебная часть скромная: четыре контейнера в простое — примерно треть гигабайта. Съедает память не панель, а сборки. Nixpacks на типичном Next.js пиково просит 2–3 ГБ, и на 2 ГБ вы получите в логе деплоя exit code: 137 — это 128 + 9, процесс убит OOM-killer'ом ядра (dmesg -T | grep -i 'killed process'). Лечится swap-файлом, переменной NODE_OPTIONS=--max-old-space-size=1536 или сборкой образа на другой машине.

Второй расход специфичен для Swarm: при редеплое новая задача поднимается до остановки старой, памяти на это время нужно вдвое больше. На 4 ГБ заметно, на 8 ГБ нет; если упёрлись, помогает docker service update --update-order stop-first <имя>. Диск берите с запасом: /var/lib/docker за месяц активных деплоев набирает 15–25 ГБ.

Локация — UK, Лондон. Причина инженерная: сервер непрерывно тянет образы с Docker Hub и ghcr.io, пакеты с npm и PyPI, код с GitHub. С британского адреса всё это доступно без зеркал, а пинг до Москвы держится в районе 40–60 мс — панель отзывчивая, терминал не лагает. Франция равноценна для континентальной Европы и GDPR, США берут, когда приложению нужен американский IP, Россия оправдана требованием 152-ФЗ — но там закладывайте зеркала реестров, иначе сборки будут капризничать.

Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT: иностранная карта не нужна. Смежное чтение: Docker Swarm на VPS и панель против чистого сервера.

Развернуть за пару минут

Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Dokploy

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

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

Подойдёт ли Ubuntu 22.04 или Debian вместо 24.04?

Установщик поддерживает обе системы. 24.04 LTS удобнее: свежее ядро, актуальные пакеты Docker, поддержка до 2029 года. А промежуточные версии вроде Ubuntu 25.04 брать не стоит: девять месяцев жизни, и обновляться придётся посреди прода.

Можно ли поставить Dokploy без Docker Swarm?

Нет, Swarm — часть архитектуры: приложения запускаются как swarm-сервисы, установщик инициализирует кластер сам. Не нужен режим кластера — смотрите на панели поверх обычного Docker или на docker compose с Caddy.

Хватит ли 2 ГБ RAM для Dokploy на Ubuntu 24.04?

Для самой панели — да, служебные контейнеры укладываются примерно в 300 МБ. Но сборки фронтенда на 2 ГБ падают с exit code: 137: либо 4 ГБ swap и медленная сборка, либо 4 ГБ памяти.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.