Dokploy на Ubuntu 24.04: пошаговая установка
Установщик 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, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть DokployDocker: почему `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, доступы появляются в личном кабинете, раздел «Доступ».
| Сценарий | CPU | RAM | Диск | Что реально получится |
|---|---|---|---|---|
| Минимум | 2 vCPU | 2 ГБ | 40 ГБ NVMe | Панель и 1–2 лёгких приложения, swap на 4 ГБ обязателен |
| Рабочий вариант | 2–4 vCPU | 4 ГБ | 80 ГБ NVMe | 4–6 приложений с базой, сборки проходят спокойно |
| Комфорт | 4–8 vCPU | 8–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 — десятки моделей в одном окне. Оплата картой РФ и по СБП.