Как установить и настроить Dokploy на VPS
Установка Dokploy — это одна команда, и через три минуты у вас своя панель деплоя вместо Vercel и Heroku. Проблемы начинаются после: админка висит на голом HTTP, сертификат не выпускается, первая сборка падает с exit code: 137. Разберём весь путь — что скрипт делает с сервером, как повесить домен с HTTPS, как закрыть порт 3000 (спойлер: ufw deny не сработает) и какой конфигурации хватит.
Содержание
- Что такое Dokploy и что он ставит на ваш VPS
- Установка Dokploy: одна команда и что она делает
- Домен панели и сертификат Let's Encrypt
- Безопасность: закрыть порт 3000 и не сломать панель
- Первый деплой: Git, сборка, домен и переменные
- Бэкапы, обновления и обслуживание
- Какой сервер под Dokploy брать в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Dokploy и что он ставит на ваш VPS
Dokploy — self-hosted PaaS: панель, из которой вы деплоите приложения из Git, поднимаете базы, разворачиваете docker-compose.yml и раздаёте домены с автоматическим Let's Encrypt. Под капотом не Kubernetes, а Docker Swarm плюс Traefik — на одном сервере это предсказуемо и чинится обычными командами docker. Актуальная стабильная версия на конец августа 2026 — v0.30.2, и на сервере появляются ровно три компонента:
| Компонент | Тип | Образ | Порты наружу |
|---|---|---|---|
dokploy | swarm-сервис | dokploy/dokploy:v0.30.2 | 3000/tcp |
dokploy-postgres | swarm-сервис | postgres:16 | нет, только внутри сети |
dokploy-traefik | обычный контейнер | traefik:v3.6.7 | 80/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 — десятки моделей в одном окне. Оплата картой РФ и по СБП.