Как установить и настроить Dify на VPS
Dify обещает собрать RAG-приложение или ИИ-агента мышкой, без единой строки кода, — и обещание держит, но только после того, как стек поднят и настроен. На своём сервере это около десяти контейнеров, полтора десятка переменных в .env, которые нельзя оставлять по умолчанию, и плагины моделей, которые надо откуда-то скачать. Разбираем установку Dify на VPS по существу: что решить до заказа сервера, что править в конфиге, где ломается HTTPS и как подключить модели, чтобы база знаний начала индексироваться.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Из чего состоит Dify на сервере
Dify — не одно приложение, а платформа: конструктор чат-ботов, агентов и workflow, движок RAG с базами знаний, HTTP-API на каждое собранное приложение и логи диалогов. В self-hosted-варианте всё это разъезжается по контейнерам, и понимать, кто за что отвечает, придётся — иначе любая поломка выглядит как «Dify не работает».
docker compose ps --services
# api
# db
# nginx
# plugin_daemon
# redis
# sandbox
# ssrf_proxy
# weaviate
# web
# worker
api— бэкенд на Python под Gunicorn, внутренний порт 5001. Обслуживает и консоль, и Service API опубликованных приложений.worker— тот же образ в режиме Celery-воркера. На нём висит вся асинхронщина: разбор загруженных файлов, нарезка на чанки, обращение к модели эмбеддингов. Воркер лёг — документы в базе знаний навсегда остаются в статусе «в очереди», а консоль при этом выглядит здоровой.web— фронтенд на Next.js, порт 3000.db— PostgreSQL: приложения, датасеты, пользователи, логи диалогов, ключи провайдеров в зашифрованном виде.redis— брокер очередей Celery и кэш.weaviate— векторное хранилище по умолчанию.sandbox— изолированная песочница для узла Code, порт 8194. Именно она выполняет ваш Python или JavaScript из workflow, а не контейнерapi.ssrf_proxy— Squid, через который ходят узлы HTTP Request: чтобы собранное пользователем приложение не постучалось в169.254.169.254или в соседний контейнер.plugin_daemon— порт 5002. В ветке 1.x провайдеры моделей и инструменты вынесены из ядра в плагины, и демон запускает их отдельными процессами.nginx— единственный контейнер, который публикует порты наружу: 80 и 443. Все остальные общаются во внутренней сети Docker.
Отсюда два вывода, важных для выбора железа. Первый: Dify требователен не к процессору, а к памяти — держать одновременно приходится Postgres, векторную базу, два Python-процесса и демон плагинов. Документация проекта просит не меньше 2 vCPU и 4 ГБ RAM, и это нижняя граница, а не рекомендация. Второй: Dify не запускает модели. Инференс всегда снаружи — облачный API или ваш собственный Ollama либо vLLM. Видеокарта самой платформе не нужна.
Что решить до заказа сервера: локация, домен, порты
Локация решается первой, потому что переиграть её потом — это переезд с бэкапом. Dify 1.x активно ходит в интернет за двумя вещами: за плагинами в маркетплейс marketplace.dify.ai и за ответами модели в API провайдера. С российского адреса ломается и то и другое: OpenAI отвечает не таймаутом, а внятным отказом.
{"error":{"code":"unsupported_country_region_territory",
"message":"Country, region, or territory not supported",
"type":"request_forbidden"}}
Google для Gemini выдаёт User location is not supported for the API use. с кодом 400, Anthropic — сухой 403. Перевыпуск ключа не помогает: провайдер смотрит на исходящий IP. Поэтому платформу ставят за пределами РФ. Великобритания (Лондон) — практичный выбор, если пользователи в Европе и России: провайдеры отвечают штатно, маркетплейс плагинов открывается, а RTT из Москвы до Лондона по типовым маршрутам заметно меньше, чем до Нью-Йорка.
Домен заводите до установки, A-запись должна резолвиться. Причина не в красоте: половина переменных в .env — это URL, и сертификат выпускается на имя. Работать по голому IP формально можно, но без HTTPS браузер отключает защищённый контекст, и голосовой ввод в чате отвалится молча — navigator.mediaDevices на небезопасном origin просто не существует.
Фаервол — наружу только SSH и веб:
ufw allow 22/tcp
ufw allow 80,443/tcp
ufw enable
ufw status numbered
Ключевая гигиена: наружу не должно смотреть ничего, кроме контейнера nginx. Порты 5001, 3000, 5432, 8194 и 5002 остаются во внутренней сети. Проверять это лучше снаружи, а не через ufw status: опубликованный контейнером порт прописывает правила в цепочку DOCKER-USER и через ufw не фильтруется.
nmap -Pn -p 22,80,443,3000,5001,5432,8194 ваш_ip
В строках всего, кроме 22, 80 и 443, должно стоять filtered, а не open.
В MAATRIX Dify лежит в каталоге приложений apps.maatrix.io и разворачивается автоматически при заказе сервера, на Ubuntu или Debian: адрес панели и стартовые доступы появляются в личном кабинете, в разделе «Доступ». Собирать стек руками не нужно — сразу переходите к настройке из следующего раздела.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть DifyПервый вход, `.env` и пароли по умолчанию
Свежая установка встречает мастером на /install, где создаётся владелец рабочего пространства. Здесь скрыт неприятный момент: страница открыта любому, кто первым найдёт адрес. Если сервер с доменом простоял ночь до вашего первого входа, аккаунт владельца мог завести кто-то другой. Страховка — переменная INIT_PASSWORD в .env: пока она задана, мастер требует её ввести. Заходите на /install сразу после развёртывания, а не «завтра».
Конфигурация живёт в одном файле — docker/.env рядом с docker-compose.yaml. Значения по умолчанию рассчитаны на запуск с ноутбука и в продакшене недопустимы:
| Переменная | Значение из примера | Почему менять обязательно |
|---|---|---|
SECRET_KEY | пустое | Подписывает сессии и шифрует ключи провайдеров в базе |
DB_PASSWORD | difyai123456 | Пароль Postgres известен всему интернету |
REDIS_PASSWORD | difyai123456 | То же самое для очередей и кэша |
WEAVIATE_API_KEY | WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih | Дефолт из репозитория, одинаковый у всех |
SANDBOX_API_KEY | dify-sandbox | Доступ к исполнению кода |
SECRET_KEY генерируется как openssl rand -base64 42. Отнеситесь к нему как к мастер-ключу: им шифруются API-ключи моделей, сложенные в Postgres. Смените его позже — и все подключённые провайдеры разом перестанут работать, а восстановить прежнее значение будет неоткуда. Положите его в менеджер паролей в первый же день.
Вторая группа переменных — адреса, и их путают чаще всего:
| Переменная | Что задаёт |
|---|---|
CONSOLE_API_URL | Куда фронтенд консоли шлёт запросы |
CONSOLE_WEB_URL | Базовый адрес консоли в письмах и ссылках-приглашениях |
SERVICE_API_URL | Адрес, который Dify показывает в разделе API приложения |
APP_WEB_URL | Адрес опубликованных веб-приложений |
FILES_URL | Откуда модель забирает загруженный файл или картинку |
Если оставить их пустыми, всё работает по тому же origin, через встроенный nginx, — для одного домена это правильный вариант. Наполовину заполненные адреса дают классику: консоль открыта по https://, запросы уходят на http://, и браузер режет их как Mixed Content. Отдельная ловушка — FILES_URL: по нему модель скачивает вложения пользователя, и если там остался localhost, мультимодальный запрос упадёт на попытке получить картинку, хотя текстом чат отвечает нормально.
И самое обидное правило: после правки .env команда docker compose restart бесполезна. Она перезапускает процессы со старым окружением. Переменные перечитываются только при пересоздании контейнеров:
docker compose down
docker compose up -d
docker compose logs -f --tail=50 api
HTTPS, домен и nginx перед Dify
Вариантов два, и смешивать их не надо.
Встроенный nginx. В .env включается HTTPS и указываются имена файлов сертификата, которые лежат в каталоге docker/nginx/ssl:
NGINX_HTTPS_ENABLED=true
NGINX_SSL_CERT_FILENAME=fullchain.pem
NGINX_SSL_CERT_KEY_FILENAME=privkey.pem
NGINX_ENABLE_CERTBOT_CHALLENGE=true
CERTBOT_DOMAIN=dify.example.com
CERTBOT_EMAIL=admin@example.com
NGINX_CLIENT_MAX_BODY_SIZE=50M
Сертификат получает профиль certbot из того же compose-файла; продление запускается отдельной командой в контейнере и ставится в cron. Подход хорош тем, что весь TLS описан в одном месте.
Внешний реверс-прокси. Нужен, когда на сервере уже живёт nginx или Caddy с другими сайтами. Тогда порт публикации Dify переносят на нестандартный — EXPOSE_NGINX_PORT=8080, иначе стек не поднимется: Docker ответит Bind for 0.0.0.0:80 failed: port is already allocated.
Во внешнем конфиге обязательны две вещи, о которых вспоминают только после жалоб. Первая — отключённая буферизация: ответы модели приходят потоком SSE, и с буферизацией пользователь смотрит на пустой экран, а потом получает всю простыню разом. Вторая — увеличенные таймауты: длинный workflow или индексация большого PDF легко переживают стандартные 60 секунд, и на минуте ровно прилетает 504 Gateway Time-out.
proxy_buffering off;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
client_max_body_size 50M;
Лимит на размер загружаемого файла живёт в двух местах сразу: NGINX_CLIENT_MAX_BODY_SIZE отвечает за прокси, UPLOAD_FILE_SIZE_LIMIT (в примере конфига 15, это мегабайты) — за само приложение. Поднимать надо оба, иначе результат не изменится. Рядом лежит GUNICORN_TIMEOUT — при тяжёлых синхронных операциях его увеличивают вместе с таймаутами прокси.
Подключение моделей: плагины, ключи и эмбеддинги
В ветке 1.x провайдеры моделей — это плагины, а не встроенный список. Путь один: «Настройки → Поставщик модели → Установить из маркетплейса», выбрать OpenAI, Anthropic, Gemini, DeepSeek или Ollama, дождаться установки и вписать ключ. Установка идёт через plugin_daemon, который качает пакет с marketplace.dify.ai. Если сервер стоит за закрытым фаерволом или в блокируемом регионе, установка виснет и заканчивается ошибкой демона плагинов — это не поломка Dify, а отсутствие сети. Обходной путь — скачать пакет .difypkg вручную и загрузить через «Установить из локального файла».
Дальше — шаг, который пропускают почти все. Мало установить провайдера, нужно назначить системные модели в том же разделе, и их там четыре роли:
- Reasoning Model — модель по умолчанию для новых приложений.
- Embedding Model — без неё база знаний не создаётся вообще: индексация в режиме High Quality обращается к модели эмбеддингов на каждый чанк.
- Rerank Model — переранжирование результатов поиска, опционально, но заметно повышает качество ответов RAG.
- Speech-to-Text — голосовой ввод.
Если модель отвечает в тестовом окне, а в приложении — нет, дело обычно в незаполненной роли, а не в ключе. Разбор остальных причин — в материале про то, почему Dify не подключается к модели.
Локальные модели подключаются через провайдера Ollama, и здесь один и тот же вопрос повторяется годами: адрес http://localhost:11434 изнутри контейнера ведёт в сам контейнер, а не на хост, и вы получаете отказ в соединении. Правильный адрес — http://host.docker.internal:11434, и в compose должен быть проброс extra_hosts: - "host.docker.internal:host-gateway". Как поднять сам Ollama, разобрано отдельно — локальный запуск LLM через Ollama.
Честно про совмещение: Dify рядом с локальной моделью на одном VPS — это сложение требований. Модель 7B в квантовании Q4 занимает около 4,5 ГБ только весами, плюс контекст, плюс 4 ГБ на сам Dify; на процессоре без видеокарты генерация вдобавок будет медленной независимо от объёма памяти. Практичнее держать платформу на небольшом сервере, а инференс — во внешнем API или на отдельной машине с GPU. Если провайдеров несколько и хочется единых ключей с бюджетами, между Dify и моделями ставят шлюз — LiteLLM на VPS.
База знаний, векторное хранилище, бэкап и обновление
Векторная база выбирается переменной VECTOR_STORE, а контейнеры разведены по профилям Compose — поднимается только выбранный. По умолчанию это weaviate; доступны qdrant, milvus, pgvector, elasticsearch. Важное ограничение, о котором лучше знать заранее: переключение переменной не переносит данные. Уже проиндексированные документы придётся загружать и индексировать заново, а это повторные обращения к модели эмбеддингов и повторный счёт за них.
Режим индексации выбирается на каждую базу знаний отдельно. High Quality гоняет каждый чанк через модель эмбеддингов — качество поиска выше, но это деньги и время на загрузке. Economy строит инвертированный индекс по ключевым словам, к модели не обращается и стоит ноль: для документации с точной терминологией нередко достаточно, для разговорных вопросов — заметно хуже.
Данные лежат в bind-каталогах рядом с compose-файлом, и бэкапить нужно четыре вещи:
docker/volumes/db/data— Postgres: приложения, датасеты, диалоги;docker/volumes/app/storage— исходные загруженные файлы;docker/volumes/weaviate— векторный индекс;docker/.env— без него дамп базы бесполезен, потому что ключи провайдеров зашифрованыSECRET_KEY.
cd /opt/dify/docker
docker compose exec -T db pg_dump -U postgres dify | gzip > /var/backups/dify-$(date +%F).sql.gz
tar czf /var/backups/dify-storage-$(date +%F).tar.gz volumes/app/storage .env
Обновление версии — это всегда «сначала бэкап». Порядок: остановить стек, снять дамп, обновить репозиторий, сравнить свой .env с новым .env.example и дописать появившиеся переменные вручную, затем подтянуть образы и поднять снова. Именно на этом шаге чаще всего теряют платформу: новый .env.example копируют поверх рабочего .env, затирая SECRET_KEY, — и все подключённые модели превращаются в нерасшифровываемый мусор. Миграции схемы при MIGRATION_ENABLED=true прогоняются автоматически при старте контейнера api; если переменная выключена, запускать их придётся руками:
docker compose exec api flask db upgrade
И не держите теги latest в проде — фиксируйте конкретную версию образов langgenius/dify-api и langgenius/dify-web, чтобы docker compose pull не подтянул мажорное обновление в неподходящий момент. Что ломается чаще всего после апгрейда, собрано в частых ошибках Dify на сервере.
Какой сервер взять в MAATRIX под Dify
Считаем по составу стека, а не на глаз: одновременно работают Postgres, Redis, векторная база, фронтенд на Node.js, api и worker плюс демон плагинов, поднимающий каждый плагин отдельным процессом. Требование разработчиков — от 2 vCPU и 4 ГБ RAM.
Честный минимум: 2 vCPU, 4 ГБ RAM, 40 ГБ NVMe. Ровно документационный порог. Стек поднимется, консоль откроется, один-два чат-бота на внешнем API будут работать нормально. Чего на нём не будет: запаса на индексацию. Когда worker разбирает крупный PDF, а Postgres и векторная база пишут параллельно, память кончается, OOM-killer выбирает самый жирный процесс — и документ навсегда остаётся в статусе ошибки, причём в веб-интерфейсе это выглядит как «Dify сломался». Swap на такой конфигурации не опция, а обязательный элемент. Плагинов держите минимум необходимого.
Комфортный вариант: 4 vCPU, 8 ГБ RAM, 80 ГБ NVMe. Это конфигурация, на которой платформой пользуется команда: несколько приложений, база знаний на тысячи документов, полдесятка плагинов, спокойные обновления без гонки за памятью. Диск считайте не по объёму документов, а кратно ему: исходные файлы в storage, чанки и метаданные в Postgres, векторы в индексе плюс растущие логи диалогов. Подробный расчёт памяти под разные сценарии — в материале сколько RAM нужно для Dify. Локальная модель рядом прибавляет свой вес: 8 ГБ на Dify плюс 4,5 ГБ на 7B в Q4 — это уже 16 ГБ, и лучше отдельная машина.
Локация — Великобритания, Лондон. Прямое следствие второго раздела: с британского адреса OpenAI, Anthropic и Google отвечают штатно, маркетплейс плагинов открывается, а до пользователей в Европе и в России ходить ближе, чем через Атлантику; соседство с GDPR-контуром — плюс, если среди клиентов европейские компании. США берут, когда нужен именно американский IP. Россия оправдана в одном сценарии: данные обязаны оставаться в РФ по 152-ФЗ, а модели используются российские, — тогда за плагинами придётся ходить через прокси.
Заказ занимает несколько минут: выбираете локацию и конфигурацию, отмечаете приложение Dify из каталога apps.maatrix.io — оно ставится автоматически на Ubuntu или Debian. Адрес панели и стартовые доступы появятся в личном кабинете, в разделе «Доступ»; первым делом зайдите на страницу мастера и создайте владельца. Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT: иностранная карта не понадобится, хотя сервер стоит в Лондоне.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть DifyОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Нужна ли видеокарта, чтобы поставить Dify?
Нет. Dify не выполняет инференс, а оркеструет запросы к моделям — считает либо облачный провайдер, либо отдельный сервер с Ollama или vLLM. GPU понадобится только во втором случае и только той машине, где крутится модель.
Правлю .env, перезапускаю контейнеры, ничего не меняется. Почему?
docker compose restart перезапускает процессы со старым окружением. Переменные перечитываются только при пересоздании: docker compose down && docker compose up -d. После смены URL-переменных ещё и обновите страницу консоли с очисткой кэша.
Можно ли развернуть Dify на сервере в России?
Стек поднимется и будет работать, но плагины из маркетплейса и API OpenAI, Anthropic и Google с российского IP недоступны — приходит unsupported_country_region_territory. Российская локация имеет смысл только с российскими моделями и требованиями 152-ФЗ; в остальных случаях берите UK или US.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.