Directus — платформа для самостоятельного размещения с доступным исходным кодом (source-available), которая превращает SQL-базу в управляемый контентный хаб с веб-интерфейсом, REST и GraphQL API, политиками доступа, автоматизациями и подключением ИИ-агентов через Model Context Protocol (MCP).

Изменяемые возможности и лицензионные условия сверены с официальными источниками 10 сентября 2026 года. Команды развёртывания приведены как воспроизводимый шаблон, но не проверялись запуском в рамках этой редакции.

Оглавление

  1. Что Directus добавляет к SQL-базе — модель платформы и общая схема.
  2. Возможности Directus 12 — версии, черновики, MCP и лицензирование.
  3. Архитектура мультисайтового хаба — компоненты и зоны данных.
  4. Права для людей и агентов — роли и ограничения.
  5. Подключение сайта по API — REST и SDK.
  6. Полезные сценарии — публикация, агенты и база знаний.
  7. Базовое развёртывание на VPS — Compose, HTTPS и проверка.
  8. Бэкапы и обновления — сохранность данных и порядок работ.
  9. Чеклист перед production — контрольная проверка.
  10. Официальные источники.

Что 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. Перед уничтожением инстанса лицензию нужно деактивировать, иначе слот останется занятым.

🔴
Если активированный инстанс не может связаться с сервером лицензий более семи дней, он переходит на Core. При превышении лимитов Core инстанс блокируется. Если ключ задан через переменную окружения, но первичная активация недоступна, Directus не запустится.

Что проверить при обновлении до 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 ищут нужные инструменты вместо предварительной загрузки полного списка.
⚠️
Перед обновлением сделайте бэкап и проверьте конфигурацию редактора, крупные импорты, трансформации изображений, массовые операции Flows, расширения хранилища и пользовательский Docker CMD.

Архитектура мультисайтового хаба

Для небольшого проекта можно собрать базовый контур из 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 и добавьте связь с ней в контентные коллекции. Политики смогут фильтровать записи по сайту без отдельных инсталляций и префиксов в названиях.

Права для людей и агентов

Минимальный набор ролей:

Notion image
РольДоступ
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 directus

Caddy может завершать HTTPS и передавать запросы локальному Directus:

directus.example.com {
  reverse_proxy 127.0.0.1:8055
  encode gzip
}

После запуска проверьте:

  1. https://directus.example.com/server/health отвечает без ошибки.
  2. В Studio можно войти под администратором.
  3. Тестовый редактор видит только разрешённый сайт.
  4. Публичный запрос возвращает опубликованную запись и скрывает черновик.
  5. После перезапуска контейнеров данные и загруженные файлы сохраняются.

Бэкапы и обновления

Ежедневно сохраняйте дамп 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

Перед обновлением:

  1. Прочитайте release notes целевой версии.
  2. Создайте свежий бэкап и проверьте возможность восстановления.
  3. Выполните sync diff, если схема управляется через Directus CLI.
  4. Обновите закреплённую версию образа.
  5. Запустите контейнеры и проверьте миграции, эндпоинт состояния, API, Studio и критичные Flows.

Чеклист перед production

PostgreSQL не опубликован в интернете.
Directus доступен снаружи только через HTTPS и обратный прокси-сервер.
KEY, SECRET, пароли и токены находятся вне git.
Администратор использует двухфакторную аутентификацию.
Для каждого агента настроена отдельная идентичность и минимальная политика.
Публичная политика возвращает только опубликованные записи.
MCP включён только при необходимости; удаление выключено.
Бэкапы базы и файлов регулярно уходят на другой носитель.
Восстановление из бэкапа проверено.
PUBLIC_URL содержит абсолютный production-адрес.
Условия Core, OIG или платной лицензии подходят проекту.
Обязательная телеметрия Core или OIG учтена в требованиях проекта.
Для лицензированного инстанса доступен сервер лицензий Directus.
После обновления проверены политики, Flows, расширения и редактор.

Официальные источники

Следующий шаг

Strapi — open-source Headless CMS для тех, кто хочет владеть своими данными

Если вы проектируете общий контентный контур для нескольких сайтов или агентов, полезно заранее проверить модель данных, границы ролей и требования к лицензии.

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov