Directus — платформа для самостоятельного размещения с доступным исходным кодом (source-available), которая превращает SQL-базу в управляемый контентный хаб с веб-интерфейсом, REST и GraphQL API, политиками доступа, автоматизациями и подключением ИИ-агентов через Model Context Protocol (MCP).
Изменяемые возможности и лицензионные условия сверены с официальными источниками 10 сентября 2026 года. Команды развёртывания приведены как воспроизводимый шаблон, но не проверялись запуском в рамках этой редакции.
Оглавление
- Что Directus добавляет к SQL-базе — модель платформы и общая схема.
- Возможности Directus 12 — версии, черновики, MCP и лицензирование.
- Архитектура мультисайтового хаба — компоненты и зоны данных.
- Права для людей и агентов — роли и ограничения.
- Подключение сайта по API — REST и SDK.
- Полезные сценарии — публикация, агенты и база знаний.
- Базовое развёртывание на VPS — Compose, HTTPS и проверка.
- Бэкапы и обновления — сохранность данных и порядок работ.
- Чеклист перед production — контрольная проверка.
- Официальные источники.
Что Directus добавляет к SQL-базе
Directus подключается к существующей SQL-базе и создаёт поверх неё несколько рабочих слоёв:
- Studio — веб-интерфейс для редакторов и администраторов.
- REST и GraphQL API — автоматически формируются для коллекций и связей.
- Политики доступа — ограничивают операции на уровне коллекций, записей и полей.
- Flows — автоматизации по событиям, расписанию, webhook или ручному запуску.
- MCP-сервер — даёт совместимым ИИ-клиентам управляемый доступ к данным и инструментам Directus.
База остаётся самостоятельным слоем архитектуры. Сайты, внутренние приложения и агенты работают с одними данными через общий API и единые правила доступа.
flowchart LR
DB[(PostgreSQL)] --> D[Directus]
D -->|REST / GraphQL| S1[Сайт 1]
D -->|REST / GraphQL| S2[Сайт 2]
D -->|MCP| A[ИИ-агенты]
D -->|Flows| F[Автоматизации]
D -->|Studio| U[Редакторы]Возможности Directus 12 для контентного хаба
Черновики и осознанная публикация
При включённом версионировании новые записи открываются как черновики. Редактор может сохранять изменения отдельно от основной версии, сравнивать поля и продвигать выбранную версию в публикацию отдельным действием. Индикаторы версии доступны в Studio.
Это позволяет дать агенту право создавать и редактировать черновики, сохранив публикацию за человеком.
Перевод и работа с JSON
Directus 12 умеет автоматически создавать схему переводов для коллекции и поддерживает перевод с помощью ИИ. Для материалов, где ошибка критична, результат всё равно требует человеческой вычитки.
JSON-поля поддерживают фильтрацию вложенных значений на уровне базы:
GET /items/articles?filter={"metadata":{"_json":{"color":{"_eq":"blue"}}}}OAuth 2.1 для MCP
MCP-клиент может действовать от имени вошедшего пользователя после его согласия. К запросам применяются существующие политики этого пользователя. Такой режим удобнее статического общего токена: сохраняются индивидуальная идентичность, отзыв доступа и аудит действий.
Лицензирование MSCL
Directus 12 распространяется по Monospace Sustainable Core License (MSCL). Исходный код доступен, а спустя четыре года соответствующая версия переходит на GPL-3.0.
По актуальному FAQ Directus действуют такие основные режимы:
| Режим | Основные условия |
| Core | Без регистрации; 3 места, 25 коллекций и без SSO по FAQ Directus |
| Open Innovation Grant | Для организаций с выручкой менее $5 млн и штатом менее 50 человек; неограниченные места, коллекции и Flows |
| Платные лицензии | Для организаций и требований, выходящих за условия Core или OIG |
Для Core и OIG обязательна анонимная телеметрия. OIG не включает поддержку и не разрешает автономную air-gapped эксплуатацию. Для работы без связи требуется Enterprise.
Один ключ OIG включает пять активаций для сред одного проекта. Активация привязывается к базе проекта и PUBLIC_URL. Перед уничтожением инстанса лицензию нужно деактивировать, иначе слот останется занятым.
Что проверить при обновлении до 12.2 и 12.3
Directus 12.2
- TinyMCE заменён на Tiptap.
tinymceOverrides, плагины, скины и CSS для TinyMCE больше не применяются. - HTML, который новый редактор мог бы нормализовать иначе, сначала блокируется для редактирования и требует подтверждения.
- Новые минимальные политики получают более узкий доступ к
directus_settings. Существующие политики автоматически не сужаются, поэтому их следует проверить вручную. IMPORT_MAX_FILE_SIZEограничивает импорт и снимки схемы значением 50 МБ по умолчанию.ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSIONв 12.2 ограничивал результат трансформации изображения значением 3000 пикселей по каждой стороне.
Directus 12.3
- Пакет
@directus/cli, также доступный какd6sилиdirectus-cli, синхронизирует схему и настройки через JSON-файлы:sync pull,sync diff,sync push. - Update Items и Delete Items во Flows с одновременно пустыми
keyиqueryтеперь возвращаютnullи ничего не меняют. Для явной обработки всей коллекции используется{"limit": -1}. - Лимит результата трансформации изображения по умолчанию поднят до 6000 пикселей.
- Метод хранилища
exists()при ошибке проверки выбрасывает исключение, которое расширение должно обработать. - Docker-образ запускается через
docker-entrypoint.cjs. ПользовательскийCMD, вызывающийpm2-runtimeнапрямую, требуется адаптировать. - Chat и MCP ищут нужные инструменты вместо предварительной загрузки полного списка.
Архитектура мультисайтового хаба
Для небольшого проекта можно собрать базовый контур из PostgreSQL, Directus и обратного прокси-сервера. Redis и отдельное файловое хранилище добавляются по требованиям к кэшу, медиа и эксплуатации.
flowchart TB
N[Caddy или Nginx] --> D[Directus]
D --> DB[(PostgreSQL)]
D --> R[(Redis)]
D --> M[Хранилище файлов]
W[Сайты] --> N
A[Агенты] --> N
U[Редакторы] --> NКонтент удобно разделить на логические зоны:
| Зона | Содержимое | Основные потребители |
| Sites | Страницы, статьи, блоки | Сайты и редакторы |
| Knowledge | Канонические документы и справочники | Люди, RAG (генерация с поиском контекста) и агенты |
| Agents | Задачи, промпты, результаты и журналы | Оркестратор и администраторы |
| Media | Изображения, аудио, PDF | Все разрешённые клиенты |
Создайте коллекцию sites и добавьте связь с ней в контентные коллекции. Политики смогут фильтровать записи по сайту без отдельных инсталляций и префиксов в названиях.
Права для людей и агентов
Минимальный набор ролей:
| Роль | Доступ |
| Admin | Полное администрирование |
| Editor | Работа с контентом назначенного сайта |
| Agent-Writer | Чтение знаний и создание черновиков |
| Agent-Reader | Только чтение разрешённых коллекций |
| Public | Чтение опубликованного контента |
Условный пример ограничения редактора одним сайтом:
{
"collection": "articles",
"action": "update",
"permissions": {
"site": { "_eq": "pimenov.ai" }
},
"fields": ["title", "body", "status", "tags"]
}Для каждого агента используйте отдельного пользователя или индивидуальную OAuth-идентичность. Это сохраняет раздельный аудит, позволяет отозвать доступ одному агенту и исключает общий секрет с избыточными правами. Удаление через MCP оставляйте выключенным, если сценарий его не требует.
Подключение сайта по API
REST-запрос опубликованных материалов одного сайта:
curl "https://directus.example.com/items/articles?filter[site][_eq]=pimenov.ai&filter[status][_eq]=published&fields=title,slug,body,tags.*" \
-H "Authorization: Bearer $DIRECTUS_TOKEN"Пример с SDK, то есть набором инструментов разработчика, для Astro:
import {
createDirectus,
readItems,
rest,
staticToken,
} from '@directus/sdk';
const client = createDirectus(import.meta.env.DIRECTUS_URL)
.with(staticToken(import.meta.env.DIRECTUS_TOKEN))
.with(rest());
export function getArticles(site: string) {
return client.request(
readItems('articles', {
fields: ['title', 'slug', 'body', 'tags.*'],
filter: {
site: { _eq: site },
status: { _eq: 'published' },
},
}),
);
}Для проверки запустите сайт в режиме разработки и выведите результат getArticles('pimenov.ai'). Пустой массив при наличии ожидаемых записей может быть связан с фильтром, отсутствием доступа токена к коллекции или полям либо с недоступными связями. Проверьте код ответа и настройки политики отдельно от результата запроса.
Полезные сценарии
Несколько сайтов с общей редакцией
Задача: хранить материалы нескольких сайтов в одной системе.
Исходные данные: коллекции sites и articles, связанные полем site.
Действие: создайте политики, фильтрующие записи по значению связи, а каждый фронтенд настройте на запрос своего сайта и опубликованного статуса.
Проверка: токен первого сайта не получает материалы второго, а публичный запрос не видит черновики.
Ограничение: ошибочная политика может открыть соседний сайт, поэтому проверяйте её отдельными тестовыми пользователями.
Конвейер «агент → черновик → редактор»
Задача: разрешить агенту готовить материал без автоматической публикации.
Исходные данные: роль агента с доступом к знаниям и созданию черновиков, а также редактор с правом публикации.
Действие: агент читает базу знаний, создаёт черновик или версию записи, после чего редактор сравнивает изменения и выполняет публикацию.
Проверка: материал виден редактору в Studio, но отсутствует в публичном API до публикации.
Ограничение: агенту не нужны административные права, доступ к публикации или разрешение на удаление.
База знаний для поиска и RAG
Задача: давать агентам актуальный контекст из канонических документов.
Исходные данные: коллекция документов, процесс разбиения текста и индекс поиска.
Действие: Flow реагирует на изменение документа и передаёт его внешнему процессу разбиения и индексирования, а агент ищет релевантные фрагменты с отдельной ролью чтения.
Проверка: после изменения документа индекс обновляется, а поиск возвращает новую версию фрагмента.
Ограничение: векторный поиск, модель эмбеддингов и обработку длинных задач обычно реализуют внешним сервисом или расширением.
Базовое развёртывание на VPS
В примере предполагается Ubuntu 22.04 или новее, Docker с Compose, домен и обратный прокси-сервер с HTTPS. PostgreSQL и Redis запускаются сервисами из шаблона ниже.
services:
database:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- ./database:/var/lib/postgresql/data
environment:
POSTGRES_USER: directus
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: directus
healthcheck:
test: ["CMD", "pg_isready", "-U", "directus"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
restart: unless-stopped
directus:
image: directus/directus:${DIRECTUS_VERSION} # Закрепите проверенную версию, не используйте latest.
restart: unless-stopped
ports:
- "127.0.0.1:8055:8055" # Снаружи запросы принимает обратный прокси-сервер.
volumes:
- ./uploads:/directus/uploads
- ./extensions:/directus/extensions
depends_on:
database:
condition: service_healthy
environment:
KEY: ${DIRECTUS_KEY}
SECRET: ${DIRECTUS_SECRET}
DB_CLIENT: pg
DB_HOST: database
DB_PORT: 5432
DB_DATABASE: directus
DB_USER: directus
DB_PASSWORD: ${DB_PASSWORD}
CACHE_ENABLED: "true"
CACHE_STORE: redis
REDIS: redis://cache:6379
ADMIN_EMAIL: ${ADMIN_EMAIL}
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
PUBLIC_URL: https://directus.example.com # Абсолютный URL нужен для активации лицензии.
LICENSE_KEY: ${LICENSE_KEY} # Оставьте пустым для Core или укажите выданный ключ.Сохраните этот файл как docker-compose.yml. Рядом создайте .env и добавьте его в .gitignore:
DIRECTUS_VERSION=<проверенная-версия>
DB_PASSWORD=<случайный-пароль-базы>
DIRECTUS_KEY=<случайное-значение>
DIRECTUS_SECRET=<случайное-значение>
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=<надёжный-пароль>
# Оставьте пустым для Core или укажите ключ OIG/платной лицензии.
LICENSE_KEY=Секреты можно сгенерировать командами:
openssl rand -hex 16
openssl rand -hex 32Ограничьте доступ к .env и запустите сервисы:
chmod 600 .env
docker compose up -d
docker compose logs -f directusCaddy может завершать HTTPS и передавать запросы локальному Directus:
directus.example.com {
reverse_proxy 127.0.0.1:8055
encode gzip
}После запуска проверьте:
https://directus.example.com/server/healthотвечает без ошибки.- В Studio можно войти под администратором.
- Тестовый редактор видит только разрешённый сайт.
- Публичный запрос возвращает опубликованную запись и скрывает черновик.
- После перезапуска контейнеров данные и загруженные файлы сохраняются.
Бэкапы и обновления
Ежедневно сохраняйте дамп PostgreSQL и каталог загрузок. Копию нужно отправлять за пределы production-сервера.
#!/usr/bin/env bash
set -euo pipefail
cd "$HOME/directus"
STAMP=$(date +%Y%m%d-%H%M)
BACKUP_DIR="$HOME/backups"
mkdir -p "$BACKUP_DIR"
docker compose exec -T database pg_dump -U directus directus \
| gzip > "$BACKUP_DIR/db-$STAMP.sql.gz"
tar -czf "$BACKUP_DIR/uploads-$STAMP.tar.gz" \
-C "$HOME/directus" uploads
find "$BACKUP_DIR" -type f -mtime +14 -deleteСохраните скрипт как ~/directus/backup.sh, сделайте его исполняемым и добавьте в cron, например:
chmod +x ~/directus/backup.sh
15 3 * * * /bin/bash /home/<user>/directus/backup.sh >> /home/<user>/backups/backup.log 2>&1Перед обновлением:
- Прочитайте release notes целевой версии.
- Создайте свежий бэкап и проверьте возможность восстановления.
- Выполните
sync diff, если схема управляется через Directus CLI. - Обновите закреплённую версию образа.
- Запустите контейнеры и проверьте миграции, эндпоинт состояния, API, Studio и критичные Flows.
Чеклист перед production
KEY, SECRET, пароли и токены находятся вне git.PUBLIC_URL содержит абсолютный production-адрес.Официальные источники
- Документация Directus
- Обзор Directus 12
- Изменения Directus 12.2
- Изменения Directus 12.3
- Версионирование контента
- FAQ Open Innovation Grant
- Релизы Directus на GitHub
Следующий шаг
Strapi — open-source Headless CMS для тех, кто хочет владеть своими данными
Если вы проектируете общий контентный контур для нескольких сайтов или агентов, полезно заранее проверить модель данных, границы ролей и требования к лицензии.
Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov


