MAATRIX / Блог / Как установить и настроить Dokploy на VPS

Как установить и настроить Dokploy на VPS

Как установить и настроить Dokploy на VPS

MAATRIX

Установка Dokploy — это одна команда, и через три минуты у вас своя панель деплоя вместо Vercel и Heroku. Проблемы начинаются после: админка висит на голом HTTP, сертификат не выпускается, первая сборка падает с exit code: 137. Разберём весь путь — что скрипт делает с сервером, как повесить домен с HTTPS, как закрыть порт 3000 (спойлер: ufw deny не сработает) и какой конфигурации хватит.

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

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

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

Что такое Dokploy и что он ставит на ваш VPS

Dokploy — self-hosted PaaS: панель, из которой вы деплоите приложения из Git, поднимаете базы, разворачиваете docker-compose.yml и раздаёте домены с автоматическим Let's Encrypt. Под капотом не Kubernetes, а Docker Swarm плюс Traefik — на одном сервере это предсказуемо и чинится обычными командами docker. Актуальная стабильная версия на конец августа 2026 — v0.30.2, и на сервере появляются ровно три компонента:

КомпонентТипОбразПорты наружу
dokployswarm-сервисdokploy/dokploy:v0.30.23000/tcp
dokploy-postgresswarm-сервисpostgres:16нет, только внутри сети
dokploy-traefikобычный контейнерtraefik:v3.6.780/tcp, 443/tcp, 443/udp

Redis больше нет — его выпилили в v0.29.9, и упоминание dokploy-redis выдаёт устаревшую инструкцию. Traefik запущен обычным контейнером, поэтому его логи смотрят через docker logs dokploy-traefik, а два остальных — через docker service logs. Состояние живёт в каталоге /etc/dokploy (конфиги Traefik, файлы приложений, логи) и docker-volume dokploy-postgres — бэкап без них бесполезен. Требования из документации, 2 ГБ RAM и 30 ГБ диска, — минимум без запаса: связка в покое ест около 500 МБ, образы занимают 2,5–3 ГБ.

Установка Dokploy: одна команда и что она делает

Две проверки перед запуском экономят полчаса. Свободны ли порты: установщик проверяет 80, 443 и 3000 (ss -tulnp | grep -E ':(80|443|3000) '), типовой виновник на «предустановленных» образах — Nginx, и вы получите Error: something is already running on port 80. Нет ли своего Docker Swarm: скрипт молча делает docker swarm leave --force и разбирает работавший кластер.

Сама установка — curl -sSL https://dokploy.com/install.sh | sh; для конкретной версии добавьте перед этим export DOKPLOY_VERSION=v0.30.2. Внутри: ставится Docker 28.5.0 (версия прибита гвоздями в скрипте), инициализируется swarm, создаются сеть dokploy-network и каталог /etc/dokploy, а пароль Postgres и секрет авторизации кладутся в Docker Secrets dokploy_postgres_password и dokploy_auth_secret.

Три грабли на этом этапе:

  • Не определился адрес для swarm. Скрипт берёт приватный адрес с не-docker интерфейса, иначе публичный через ifconfig.io. Сервер без исходящего интернета получит Error: Could not determine server IP address automatically. Обход: curl -sSL https://dokploy.com/install.sh | sudo ADVERTISE_ADDR=203.0.113.10 sh.
  • Пул адресов Swarm перекрывает вашу сеть. Overlay-сети берутся из 10.0.0.0/8 и конфликтуют с WireGuard. Пул задают до установки: export DOCKER_SWARM_INIT_ARGS="--default-addr-pool 172.20.0.0/16 --default-addr-pool-mask-length 24".
  • Docker потом не обновляется. Скрипт делает apt-mark hold docker-ce docker-ce-cli docker-ce-rootless-extras, и apt upgrade молча пропускает их: apt-mark showhold покажет, apt-mark unhold вернёт.

В docker service ls должны быть dokploy и dokploy-postgres, в docker ps — они плюс dokploy-traefik. Если панель не открывается, а docker service logs dokploy показывает Migration failed [Error: getaddrinfo ENOTFOUND dokploy-postgres], это гонка старта — Postgres поднялся позже панели, лечится docker service scale dokploy=0 и следом dokploy=1. Дальше http://<IP>:3000: первый зарегистрировавшийся становится владельцем, регистрация закрывается.

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

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

Развернуть Dokploy

Домен панели и сертификат Let's Encrypt

Сразу после установки Dokploy кладёт в /etc/dokploy/traefik/dynamic/dokploy.yml заглушку с роутером на хост dokploy.docker.localhost и единственным entryPoint web: через Traefik панель не отдаётся, и пока домен не задан, вход только :3000 по HTTP, с паролем в открытом виде. Заведите A-запись panel.example.com с TTL 300 и задайте домен в Settings → Web Server → Domain. Тот же файл перезапишется роутером на websecure с редиректом с HTTP; file-провайдер Traefik работает с watch: true, перезапускать ничего не нужно.

Почту меняйте обязательно — в дефолтном /etc/dokploy/traefik/traefik.yml стоит заглушка:

certificatesResolvers:
  letsencrypt:
    acme:
      email: test@localhost.com
      storage: /etc/dokploy/traefik/dynamic/acme.json
      httpChallenge:
        entryPoint: web

Сертификаты лежат в acme.json внутри /etc/dokploy и попадают в бэкап каталога, а проверка идёт по HTTP-01 через 80-й порт: закрывать 80 нельзя никогда, даже если сайт работает только по HTTPS, — иначе через 60 дней автопродление тихо перестанет работать.

Типовая ошибка в docker logs dokploy-traefik: Unable to obtain ACME certificate ... acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://panel.example.com/.well-known/acme-challenge/xxxx. Причины по частоте: A-запись не разошлась (dig +short panel.example.com должен вернуть IP сервера); домен проксируется Cloudflare в режиме «оранжевое облако», и на challenge отвечает он; 80-й закрыт. Лимиты Let's Encrypt — 5 неудачных валидаций в час и 50 сертификатов в неделю на домен, так что экспериментируйте на поддомене.

Безопасность: закрыть порт 3000 и не сломать панель

Панель опубликована директивой --publish published=3000,target=3000,mode=host — админка с доступом к /var/run/docker.sock торчит в интернет по HTTP. Как только домен с HTTPS заработал, 3000 надо закрыть, и первое, что все пробуют, не работает: ufw deny 3000/tcp порт не закроет. Опубликованные Docker порты обрабатываются в его собственных цепочках iptables, до правил UFW дело не доходит — примените правило и постучитесь curl -I http://<IP>:3000 с другой машины, ответ придёт. Правильный способ — снять публикацию у swarm-сервиса:

docker service update --publish-rm published=3000,target=3000,mode=host dokploy

Панель останется доступна по https://panel.example.com; вернуть порт для отладки можно тем же --publish-add. Сервис создан с --update-order stop-first, так что на 20–40 секунд панель ляжет. Альтернатива — правило в цепочке, которую Docker уважает: iptables -I DOCKER-USER -p tcp --dport 3000 ! -s 203.0.113.0/24 -j DROP. Базовый фаервол нужен в любом случае: ufw allow 22/tcp, ufw allow 80,443/tcp, ufw --force enable.

И три честных момента, о которых не пишут крупным шрифтом:

  • chmod 777 /etc/dokploy. Установщик делает каталог с конфигами Traefik и файлами приложений доступным на запись всем пользователям системы. Понижать права вручную рискованно — часть операций панель выполняет от имени контейнера, — так что не пускайте на эту машину посторонние учётки.
  • Не публикуйте порт 8080. В traefik.yml стоит api: insecure: true: дашборд включён, и наружу это карта всей маршрутизации без пароля.
  • Учётка панели — фактически root, она управляет Docker-сокетом. В Settings → Profile включите passkey или 2FA: сброс пароля делается только с консоли сервера.

Первый деплой: Git, сборка, домен и переменные

Схема простая: Projects → Create Project → Create Service → Application.

Источник кода. GitHub App (Settings → Git) даёт приватные репозитории и вебхуки автодеплоя, но настраивать его надо после появления домена с HTTPS — иначе GitHub некуда слать вебхук. Универсальный путь — SSH-ключ: Settings → SSH Keys → Generate RSA SSH Key, публичную часть в Deploy keys репозитория. URL обязан быть вида git@github.com:user/repo.git — с HTTPS-адресом deploy key не работает.

Сборка и домен. По умолчанию стоит Nixpacks: сам определяет стек, но выедает 1,5–2 ГБ на сборке среднего Next.js-приложения, тогда как Dockerfile предсказуемее. Домен вешается во вкладке Domains: Host, Path, Container Port и тумблер HTTPS. Container Port — самая частая ошибка: это порт внутри контейнера (у Node-приложения обычно 3000, у Nginx-образа 80), а не порт на хосте. Для типа Application домен применяется сразу, для Docker Compose маршруты задаются лейблами Traefik и требуют передеплоя.

Переменные и база. Не дублируйте пароль базы в каждом сервисе: объявите общую переменную на уровне проекта и подставляйте ссылкой DATABASE_URL=${{project.DATABASE_URL}} (есть и уровень окружения — ${{environment.VAR}}). Create Service → Database → PostgreSQL поднимет базу в той же dokploy-network, и приложение достучится по имени сервиса: postgresql://user:pass@my-db:5432/app.

Бэкапы, обновления и обслуживание

Бэкап панели — Web Server → Backups, предварительно заведя хранилище в Settings → S3 Destinations. Dokploy снимает дамп dokploy-postgres, забирает /etc/dokploy, кладёт в один zip и заливает по cron-расписанию. Важно: восстановление — не слияние, Dokploy очищает текущий /etc/dokploy и дропает базу панели, разворачивая архив поверх. После переезда зайдите в Web Server → Server → Update IP и переподключите Git-провайдеров. Ручной вариант, если S3 пока нет:

docker exec $(docker ps -q -f name=dokploy-postgres) \
  pg_dump -U dokploy dokploy | gzip > /root/dokploy-$(date +%F).sql.gz
tar czf /root/etc-dokploy-$(date +%F).tar.gz /etc/dokploy

Данные приложений сюда не входят: для баз есть Backups у сервиса, для файлов — Volume Backups. Всё, что приложение пишет мимо тома, исчезнет при первом редеплое.

Обновлениеcurl -sSL https://dokploy.com/install.sh | sh -s update: под капотом docker pull и docker service update --image dokploy/dokploy:v0.30.2 dokploy, приложения не трогаются, панель недоступна около полуминуты.

Диск. Каждый деплой оставляет слои образов и кэш сборщика: при ежедневных деплоях пары приложений за месяц набегает 15–20 ГБ. Смотреть docker system df, чистить docker builder prune -af и docker image prune -af --filter "until=168h"; в панели есть Docker Cleanup по расписанию. Симптом переполнения узнаваем: панель перестаёт открываться, Postgres уходит в recovery mode.

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

Сама панель лёгкая — около 500 МБ в покое; ресурсы съедают сборки и ваши приложения.

Минимум: 2 vCPU, 4 ГБ RAM, 60 ГБ NVMe. Документация называет 2 ГБ, и формально на них всё ставится, но первая же сборка фронтенда через Nixpacks упрётся в потолок и даст в логе деплоя exit code: 137 — это OOM-killer. Если всё-таки берёте 2 ГБ, добавьте swap: fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile плюс строка /swapfile none swap sw 0 0 в /etc/fstab. Сборку он спасёт, но замедлит.

Комфортный вариант: 4 vCPU, 8 ГБ RAM, 120–160 ГБ NVMe. Пять–десять приложений, пара баз, кэш сборок и место под бэкапы — без ночной уборки диска и без гонки за память между сборкой и продакшеном. Диск важнее, чем кажется: официальные 30 ГБ уходят на Dokploy и одно-два приложения.

Локация — Великобритания, Лондон. RTT из Москвы 40–50 мс, до Франкфурта и Амстердама около 10 мс: панель отзывчива и для вас, и для команды в ЕС, европейские пользователи получают нормальный TTFB, а площадка в европейском правовом контуре снимает вопросы GDPR. Франция — по той же логике, Россия нужна при обработке персданных россиян по 152-ФЗ, США — если нужен чистый IP.

Dokploy есть в каталоге apps.maatrix.io — при заказе он разворачивается автоматически, вручную вставлять curl ... | sh не нужно. Автоустановка работает на Ubuntu и Debian; берите Ubuntu 24.04 LTS. Доступы появятся в личном кабинете, в разделе «Доступ», а первые два действия после входа — задать домен панели с HTTPS и включить passkey или 2FA. Оплата картами российских банков, по СБП или криптовалютой.

И честно: один узел с Dokploy — не отказоустойчивость: панель, база и приложения падают вместе с сервером. Для небольшого продакшена это нормальный размен на простоту; под SLA нужен отдельный сервер для базы.

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

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

Развернуть Dokploy

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

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

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

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

Можно ли поставить Dokploy туда, где уже работает Nginx или панель хостинга?

Нет. Установщик проверяет порты 80, 443 и 3000 и выходит с Error: something is already running on port 80, а ещё выполняет docker swarm leave --force, разбирая существующий кластер. Нужна чистая машина.

Панель открывается, а сайт по домену отдаёт 404 page not found.

Так отвечает Traefik, когда роутера для этого хоста нет. Проверьте, что домен добавлен во вкладке Domains у приложения, A-запись указывает на IP сервера, а в Container Port стоит порт, который слушает контейнер, а не 80.

Как обновлять Dokploy и не потерять приложения?

Командой curl -sSL https://dokploy.com/install.sh | sh -s update: она обновляет только сервис панели, контейнеры приложений не трогаются. Перед этим сделайте бэкап через Web Server → Backups: проект младше 1.0, и миграции схемы между релизами не всегда обратимы.

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

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