Nextdocs — Руководство по развёртыванию
Документ описывает установку платформы Nextdocs на вашей инфраструктуре:
требования к ресурсам, топологию сети, развёртывание через Docker Compose
(один сервер / VM) и Kubernetes (кластер), а также проверку работоспособности
и обслуживание.
Версия документа | 1.0 |
Способы установки | Docker Compose, Kubernetes |
Поддержка |
Содержание
1. Архитектура
Nextdocs — это набор контейнеризованных микросервисов за единым реверс-прокси.
Сервисы общаются через шину сообщений NATS и разделяют кластер PostgreSQL
(отдельная база на каждый сервис). Полнотекстовый и семантический поиск
обеспечивают векторная база Weaviate и сервис эмбеддингов. Файлы (изображения)
хранятся в S3-совместимом хранилище MinIO.
Компонент | Назначение |
|---|---|
nginx | Реверс-прокси, TLS-терминация, единая точка входа |
frontend | Веб-интерфейс (SPA) |
api | Основной API: проекты, документы, права доступа, интеграция с GitHub |
auth | Аутентификация (JWT/JWKS), авторизация |
crdt | Совместное редактирование в реальном времени (WebSocket) |
chat | Чат |
comments | Комментарии и упоминания |
rag | Поиск по документам (Retrieval-Augmented Generation) |
agent | AI-ассистент |
gpt-doc | Автоматическая генерация документации |
prompts | Хранилище промптов |
doc-parser | Разбор загружаемых документов |
text-converter | Конвертация форматов документов |
lsp | Анализ кодовых репозиториев |
embeddings | Локальная модель векторных представлений (bge-m3) |
weaviate | Векторная база данных |
postgres | Реляционная база данных |
nats | Шина сообщений и событий |
minio | Объектное хранилище (S3-совместимое) |
2. Требования
2.1. Программное обеспечение
Сценарий | Требования |
|---|---|
Docker Compose | Docker Engine 24+, Docker Compose v2, ОС Linux x86-64 |
Kubernetes | Кластер 1.27+, |
2.2. Аппаратные ресурсы
Полная платформа в типовой нагрузке потребляет немного. Рекомендованный минимум:
Конфигурация | vCPU | RAM | Диск | Подходит для |
|---|---|---|---|---|
Минимальная | 4 | 8 GB | 100 GB SSD | Демо, небольшая команда (≤ 25 пользователей) |
Рекомендованная | 8 | 16 GB | 250 GB SSD | Прод, средняя команда (до ~200 пользователей) |
С масштабированием | 16+ | 32 GB+ | 500 GB+ SSD | Большая нагрузка, несколько реплик |
Диск растёт в первую очередь за счёт PostgreSQL, Weaviate (векторный индекс) и
MinIO (изображения). Закладывайте отдельный том под данные.
2.3. Сеть и доступ
Доменное имя и DNS-записи:
<ваш-домен>иapi.<ваш-домен>указывают на сервер/балансировщик.TLS-сертификаты для этих доменов (можно через cert-manager / Let's Encrypt).
Доступ контейнеров в интернет (для внешних LLM-провайдеров и интеграций).
Учётные данные для приватного registry с образами Nextdocs (выдаются при поставке).
Ключи внешних провайдеров LLM (OpenAI / Anthropic), если используются AI-функции.
3. Топология сети
Трафик клиента приходит на nginx, который терминирует TLS и маршрутизирует
запросы. Внутренние сервисы изолированы в приватной сети и недоступны извне
напрямую.
graph TB
Client([Пользователь / Браузер])
LB[Балансировщик / DNS]
subgraph edge["Публичная зона"]
NGINX[nginx<br/>:80 / :443<br/>TLS-терминация]
FE[frontend]
end
subgraph internal["Приватная сеть (изолирована)"]
API[api]
AUTH[auth]
CRDT[crdt]
CHAT[chat]
COMM[comments]
RAG[rag]
AGENT[agent]
GPTDOC[gpt-doc]
PROMPTS[prompts]
DOCP[doc-parser]
TC[text-converter]
LSP[lsp]
EMB[embeddings]
PG[(postgres)]
NATS{{nats}}
WEAV[(weaviate)]
MINIO[(minio)]
end
EXT[Внешние сервисы:<br/>LLM-провайдеры, GitHub]
Client --> LB --> NGINX
NGINX --> FE
NGINX --> API & AUTH & CHAT & COMM & RAG & AGENT & PROMPTS & DOCP
NGINX -->|WebSocket| CRDT
NGINX -->|WebSocket| NATS
API --- PG & NATS & AUTH & MINIO
AUTH --- PG & NATS
CRDT --- PG & NATS
CHAT --- PG & NATS
COMM --- PG & NATS
GPTDOC --- PG & TC & NATS
DOCP --- PG & TC
RAG --- WEAV & API & EMB
AGENT --- RAG & CHAT & API
EMB --- WEAV
AGENT -.-> EXT
RAG -.-> EXT
GPTDOC -.-> EXT
API -.-> EXT
3.1. Маршрутизация запросов
nginx обслуживает два виртуальных хоста — интерфейс и API-шлюз:
flowchart LR
subgraph site["<ваш-домен>"]
S1["/ → frontend"]
S2["/robots.txt, /sitemap-*.xml → api"]
end
subgraph apigw["api.<ваш-домен>"]
A1["/core/ → api"]
A2["/auth/ → auth"]
A3["/chat/ → chat"]
A4["/comments/ → comments"]
A5["/rag/ → rag"]
A6["/agent/ → agent"]
A7["/prompts/ → prompts"]
A8["/doc-parser/ → doc-parser"]
A9["/ws/crdt → crdt (WebSocket)"]
A10["/ws/nats → nats (WebSocket)"]
end
4. Ресурсы сервисов
Рекомендованные значения для продакшена. requests — гарантированный минимум
(Kubernetes резервирует под него ресурсы), limits — верхний предел. В Docker
Compose учитывается только limits (deploy.resources.limits).
CPU в обычной работе используется слабо; ресурсы заданы с запасом под всплески
(импорт данных, AI-инференс, разбор документов).
Сервис | CPU req | CPU limit | RAM req | RAM limit | Постоянный диск | Реплики |
|---|---|---|---|---|---|---|
nginx | 25m | 200m | 32Mi | 128Mi | — | 2 |
frontend | 10m | 100m | 16Mi | 64Mi | — | 2 |
api | 50m | 1 | 64Mi | 1Gi | 20Gi (репозитории, медиа) | 2 |
auth | 100m | 1 | 256Mi | 1Gi | — | 2 |
crdt | 50m | 1 | 128Mi | 1Gi | — | 2+ |
chat | 25m | 500m | 32Mi | 256Mi | — | 1–2 |
comments | 25m | 500m | 32Mi | 256Mi | — | 1–2 |
rag | 100m | 1 | 192Mi | 1Gi | 10Gi | 1–2 |
agent | 100m | 1 | 192Mi | 1Gi | 10Gi | 1–2 |
gpt-doc | 100m | 1 | 256Mi | 1Gi | 10Gi | 1 |
prompts | 25m | 300m | 64Mi | 256Mi | — | 1 |
doc-parser | 100m | 1 | 128Mi | 1Gi | — | 1–2 |
text-converter | 50m | 1 | 128Mi | 1Gi | 10Gi | 1–2 |
lsp | 50m | 1 | 64Mi | 512Mi | 20Gi | 1 |
embeddings | 250m | 2 | 2Gi | 3Gi | 5Gi (модель) | 1 |
weaviate | 250m | 2 | 256Mi | 2Gi | 50Gi+ | 1 |
postgres | 250m | 2 | 256Mi | 2Gi | 50Gi+ | 1 |
nats | 50m | 500m | 64Mi | 512Mi | 10Gi | 1–3 |
minio | 100m | 1 | 256Mi | 2Gi | 50Gi+ | 1 |
Итого по requests: ≈ 1.8 vCPU / 4.7 GB RAM. Самые ресурсоёмкие
компоненты — embeddings (модель в памяти), weaviate, postgres и minio.
Заметки по сайзингу
embeddingsгрузит ML-модель целиком в RAM (~1.5–2 GB). При больших объёмах
индексации его можно вынести на GPU-узел для ускорения.
crdtхранит активные документы в памяти — при горизонтальном
масштабировании включите «липкие» сессии (sticky sessions, см. §7.4).
weaviate,postgres,minioрастут с объёмом данных — следите за диском.
5. Доступ к образам
Образы Nextdocs публикуются в GitHub Container Registry (ghcr.io) в
организации nextdocs-ai (например, ghcr.io/nextdocs-ai/api). Это приватный
реестр — для доступа нужен Personal Access Token (PAT) с правомread:packages. Токен выдаётся вместе с поставкой.
5.1. Docker / Docker Compose
Логин с помощью PAT (рекомендуется передавать токен через stdin, а не в аргументе):
echo <PAT> | docker login ghcr.io -u <github-username> --password-stdin
После входа docker compose pull скачает все образы автоматически.
5.2. Kubernetes
Создайте imagePullSecret для ghcr.io и сошлитесь на него в манифестах:
kubectl create secret docker-registry nextdocs-registry \
--docker-server=ghcr.io \
--docker-username=<github-username> \
--docker-password=<PAT> \
-n nextdocs
# в spec.template.spec каждого Deployment/StatefulSet:
imagePullSecrets:
- name: nextdocs-registry
6. Установка через Docker Compose
Подходит для развёртывания на одном сервере или виртуальной машине.
Шаг 1. Подготовка
# Распакуйте поставочный архив или склонируйте репозиторий развёртывания
cd nextdocs-deploy
echo <PAT> | docker login ghcr.io -u <github-username> --password-stdin
Шаг 2. Конфигурация
cp .env.example .env
Заполните обязательные переменные в .env (см. §8): домен, пароли баз данных,
секрет аутентификации, учётные данные MinIO и, при необходимости, ключи LLM.
Шаг 3. TLS-сертификаты
Поместите сертификаты в каталог nginx/ssl/ согласно вашему домену
(fullchain.pem и privkey.pem).
Шаг 4. Запуск
docker compose pull # скачать образы
docker compose up -d # запустить всё в фоне
docker compose ps # проверить статус
Сервисы стартуют в правильном порядке автоматически (по зависимостям и
health-check). Первый запуск инициализирует базы данных и создаёт bucket в MinIO.
Шаг 5. Полезные команды
docker compose logs -f api # логи отдельного сервиса
docker compose up -d --no-deps api # перезапуск одного сервиса
docker compose down # остановить всё (данные в томах сохранятся)
7. Установка в Kubernetes
Соответствие сущностей:
Тип сервиса | Kubernetes-объекты |
|---|---|
Без состояния (api, auth, rag, …) |
|
С состоянием (postgres, weaviate, nats, minio) |
|
Точка входа |
|
Конфигурация |
|
Изоляция приватной сети |
|
7.1. Топология в кластере
graph TB
CF([Внешний LB / DNS]) -->|HTTPS| ING
subgraph ns["namespace: nextdocs"]
ING[Ingress]
subgraph dep["Deployments (без состояния)"]
FE[frontend]
API[api]
AUTH[auth]
CRDT[crdt]
SVC[chat · comments · rag · agent<br/>gpt-doc · prompts · doc-parser<br/>text-converter · lsp · embeddings]
end
subgraph sts["StatefulSets (с состоянием + PVC)"]
PG[(postgres)]
NATS{{nats}}
WEAV[(weaviate)]
MINIO[(minio)]
end
CFG[ConfigMap + Secret]
NP[NetworkPolicy]
end
ING --> FE & API & AUTH & SVC
ING -->|WebSocket, sticky| CRDT
SVC --- PG & NATS & WEAV & MINIO
API --- PG & NATS & MINIO
AUTH --- PG & NATS
CRDT --- PG & NATS
7.2. Конфигурация и секреты
kubectl create namespace nextdocs
# Несекретные переменные окружения
kubectl create configmap nextdocs-env --from-env-file=.env.public -n nextdocs
# Секреты: пароли БД, секрет auth, ключи LLM, креды MinIO
kubectl create secret generic nextdocs-secrets \
--from-literal=API_DB_PASSWORD=... \
--from-literal=AUTH_SECRET=... \
--from-literal=MINIO_ROOT_PASSWORD=... \
--from-literal=OPENAI_API_KEY=... \
-n nextdocs
# Доступ к приватному registry (см. §5.2)
kubectl create secret docker-registry nextdocs-registry ... -n nextdocs
7.3. Пример Deployment (api)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: nextdocs
spec:
replicas: 2
selector:
matchLabels: { app: api }
template:
metadata:
labels: { app: api, tier: backend }
spec:
imagePullSecrets:
- name: nextdocs-registry
containers:
- name: api
image: ghcr.io/nextdocs-ai/api:<version>
ports:
- containerPort: 8080
envFrom:
- configMapRef: { name: nextdocs-env }
- secretRef: { name: nextdocs-secrets }
resources:
requests: { cpu: "50m", memory: "64Mi" }
limits: { cpu: "1", memory: "1Gi" }
livenessProbe:
httpGet: { path: /ping, port: 8080 }
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet: { path: /ping, port: 8080 }
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: api
namespace: nextdocs
spec:
selector: { app: api }
ports:
- { port: 8080, targetPort: 8080 }
7.4. Ingress (WebSocket + sticky sessions)
Сервисы crdt и nats работают по WebSocket, для crdt нужны «липкие» сессии.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nextdocs
namespace: nextdocs
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
ingressClassName: nginx
tls:
- hosts: [ "api.example.com", "example.com" ]
secretName: nextdocs-tls
rules:
- host: api.example.com
http:
paths:
- { path: /core, pathType: Prefix, backend: { service: { name: api, port: { number: 8080 } } } }
- { path: /auth, pathType: Prefix, backend: { service: { name: auth, port: { number: 3030 } } } }
- { path: /chat, pathType: Prefix, backend: { service: { name: chat, port: { number: 8082 } } } }
- { path: /comments, pathType: Prefix, backend: { service: { name: comments, port: { number: 8090 } } } }
- { path: /rag, pathType: Prefix, backend: { service: { name: rag, port: { number: 8000 } } } }
- { path: /agent, pathType: Prefix, backend: { service: { name: agent, port: { number: 8000 } } } }
- { path: /prompts, pathType: Prefix, backend: { service: { name: prompts, port: { number: 8081 } } } }
- { path: /doc-parser, pathType: Prefix, backend: { service: { name: doc-parser, port: { number: 8000 } } } }
- { path: /ws/crdt, pathType: Prefix, backend: { service: { name: crdt, port: { number: 5555 } } } }
- { path: /ws/nats, pathType: Prefix, backend: { service: { name: nats, port: { number: 9222 } } } }
- host: example.com
http:
paths:
- { path: /, pathType: Prefix, backend: { service: { name: frontend, port: { number: 80 } } } }
7.5. StatefulSet (пример: postgres)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: nextdocs
spec:
serviceName: postgres
replicas: 1
selector: { matchLabels: { app: postgres } }
template:
metadata: { labels: { app: postgres, tier: backend } }
spec:
imagePullSecrets: [ { name: nextdocs-registry } ]
containers:
- name: postgres
image: postgres:16
ports: [ { containerPort: 5432 } ]
envFrom:
- secretRef: { name: nextdocs-secrets }
resources:
requests: { cpu: "250m", memory: "256Mi" }
limits: { cpu: "2", memory: "2Gi" }
volumeMounts:
- { name: data, mountPath: /var/lib/postgresql/data }
volumeClaimTemplates:
- metadata: { name: data }
spec:
accessModes: [ "ReadWriteOnce" ]
resources: { requests: { storage: 50Gi } }
Сервисы
api,rag,agent,gpt-doc,lsp,text-converterиспользуют
общий каталог репозиториев. В Kubernetes это том с доступом ReadWriteMany
(NFS / CephFS / облачный файловый том).
7.6. Изоляция приватной сети
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-isolation
namespace: nextdocs
spec:
podSelector:
matchLabels: { tier: backend }
policyTypes: [ Ingress ]
ingress:
- from:
- podSelector: {}
- namespaceSelector:
matchLabels: { name: ingress-nginx }
7.7. Автомасштабирование (опционально)
Кандидаты на горизонтальное масштабирование: api, rag, agent,doc-parser, text-converter, nginx.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: api, namespace: nextdocs }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: api }
minReplicas: 2
maxReplicas: 8
metrics:
- type: Resource
resource: { name: cpu, target: { type: Utilization, averageUtilization: 70 } }
Не масштабируйте автоматически базы данных (
postgres,weaviate,minio),embeddings(тяжёлая модель) иcrdt(состояние сессий в памяти).
8. Конфигурация (переменные окружения)
Основные переменные. Полный список — в .env.example.
Переменная | Описание |
|---|---|
| Базовый домен (например, |
| Пароли баз данных сервисов |
| Секрет для подписи токенов аутентификации |
| Адрес шины сообщений ( |
| Учётные данные объектного хранилища |
| Ключи LLM-провайдеров (для AI-функций) |
| Интеграция с GitHub (опционально) |
| URL возврата OAuth ( |
Безопасность: замените все значения по умолчанию и тестовые пароли на
уникальные стойкие секреты до запуска в продакшене.
9. Проверка работоспособности
После запуска убедитесь, что сервисы отвечают:
# Docker Compose
docker compose ps # все сервисы в состоянии "running"/"healthy"
# Kubernetes
kubectl get pods -n nextdocs # все поды в "Running", READY 1/1
Эндпоинты для health-check:
Сервис | Проверка |
|---|---|
api |
|
auth |
|
nats |
|
Веб-интерфейс | Откройте |
10. Резервное копирование
Резервируйте постоянные данные:
Что | Как |
|---|---|
PostgreSQL |
|
MinIO | Репликация bucket или периодическая выгрузка объектов |
Weaviate | Снимки (snapshots) векторного индекса |
NATS (JetStream) | Резерв тома с состоянием потоков |
Пример дампа PostgreSQL (Docker Compose):
docker compose exec postgres pg_dumpall -U <db_user> > backup_$(date +%F).sql
11. Обновление
# Docker Compose
echo <PAT> | docker login ghcr.io -u <github-username> --password-stdin
docker compose pull # скачать новые версии образов
docker compose up -d # пересоздать обновлённые контейнеры
# Kubernetes
kubectl set image deployment/api api=ghcr.io/nextdocs-ai/api:<new-version> -n nextdocs
kubectl rollout status deployment/api -n nextdocs
Перед обновлением в продакшене сделайте резервную копию баз данных (§10).
Рекомендуется фиксировать конкретные версии образов (теги), а неlatest.
12. Диагностика
Симптом | Возможная причина и действия |
|---|---|
Сервис не стартует | Проверьте логи: |
502/503 от nginx | Проверьте, что целевой сервис здоров и прошёл readiness-проверку. |
Не работает совместное редактирование | Убедитесь, что WebSocket-маршруты ( |
Не загружаются изображения | Проверьте доступность MinIO и наличие bucket; проверьте креды MinIO. |
AI-функции не отвечают | Проверьте ключи LLM-провайдеров и доступ контейнеров в интернет. |
Ошибки доступа к БД | Сверьте пароли в |
| Проверьте |
13. Чеклист готовности к продакшену
Все пароли и секреты заменены на уникальные стойкие значения.
Настроены валидные TLS-сертификаты для обоих доменов.
Postgres, Weaviate, MinIO, NATS используют постоянные тома (PVC).
Настроено регулярное резервное копирование (§10) и проверено восстановление.
На всех сервисах заданы
requests/limits(§4).Приватная сеть изолирована (NetworkPolicy в Kubernetes).
Настроены liveness/readiness-проверки.
Подключён мониторинг (метрики и оповещения).
Образы зафиксированы по версиям (теги), а не
latest.Общий том репозиториев доступен в режиме ReadWriteMany (для Kubernetes).
По вопросам развёртывания и поддержки: [email protected]