> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/on-premises/ru/nachalo-raboty/microservices.md).

# Микросервисы

Рекомендуемый способ развертывания и управления экземплярами Overleaf Server CE и Overleaf Pro — использовать Toolkit.

Toolkit упрощает создание вашего экземпляра Overleaf с помощью набора пользовательских скриптов, которые скрывают оркестрацию необходимых микросервисов. Просто запустите включённый в комплект скрипт инициализации, укажите несколько параметров конфигурации, таких как пути к постоянному хранилищу, и Toolkit позаботится о подготовке и подключении микросервисов, из которых состоит ваш экземпляр Overleaf Server CE или Pro.

Это позволяет вам сосредоточиться на настройке пользовательского опыта и реализации конкретных функций, из которых состоит ваш локальный экземпляр. Toolkit берёт на себя всю сложность за кулисами, обеспечивая упрощённое развертывание вашего экземпляра Overleaf.

{% hint style="info" %}
По историческим причинам основной контейнер Overleaf называется `sharelatex`, и основан на `sharelatex/sharelatex` образе Docker. Это связано с тем, что технология основана на кодовой базе ShareLaTeX, которая была объединена с Overleaf. См. [этот пост в блогеarrow-up-right](https://www.overleaf.com/blog/518-exciting-news-sharelatex-is-joining-overleaf) для получения дополнительных сведений. Когда-нибудь в будущем это будет переименовано, чтобы соответствовать схеме именования Overleaf.
{% endhint %}

#### Архитектура

Внутри контейнера Overleaf программное обеспечение работает как набор микросервисов, управляемых `runit`. Некоторые из наиболее интересных файлов внутри контейнера:

* `/etc/service/`: файлы инициализации микросервисов.
* `/var/log/overleaf/`: журналы каждого микросервиса.
* `/overleaf/services/`: код различных микросервисов.
* `/var/lib/overleaf/`: точка монтирования для постоянных данных (соответствует каталогу, указанному `OVERLEAF_DATA_PATH` на хосте).

#### Контейнеры MongoDB и Redis

Overleaf зависит от двух внешних баз данных: MongoDB и Redis. По умолчанию Toolkit создаст контейнер для каждой из этих баз данных, в дополнение к контейнеру Overleaf, всего три контейнера Docker.

{% hint style="info" %}
Если вы предпочитаете подключиться к существующему экземпляру MongoDB или Redis, это можно сделать, указав соответствующие настройки в [overleaf.rc](https://overleaf-pro.ayaka.space/on-premises/ru/nachalo-raboty/pages/56287e9d274b97bfb81777d199aab409e34d6014#the-overleaf.rc-file) файле конфигурации.
{% endhint %}

#### Процесс редактора и компиляции

В этом разделе даётся общее представление об обработке документов и процессе компиляции.

{% hint style="info" %}
На этой странице описан процесс компиляции с использованием Sandboxed Compiles, доступный только в Overleaf Pro. В Server CE процесс компиляции использует простые подпроцессы — замените элементы, ссылающиеся на **container** на один элемент **запускать компиляцию в подпроцессе**.
{% endhint %}

Компоненты / Участники:

* `пользователь` — Пользователь приложения
* `редактор` — Клиентское приложение, работающее в браузере
* `clsi` — микросервис, используемый для компиляции PDF-файлов
* `document-updater` — микросервис, используемый для обработки обновлений документов
* `filestore` — микросервис, обрабатывающий двоичные файлы
* `real-time` — микросервис, используемый для обработки веб-сокетов
* `web` — (не совсем) микросервис, используемый для обработки API-запросов

**Кэширование Redis**

* **пользователь**: загружает страницу редактора
* **редактор**: открывает веб-сокет
* **редактор**: отправляет запрос на открытие документа через веб-сокет
  * **real-time** -> **document-updater**: документ загружается из MongoDB в Redis
* **редактор**: отправляет обновление документа через веб-сокет
  * **real-time** -> **document-updater**: документ обновляется в Redis
* **редактор**: отправляет дополнительные запросы на компиляцию
  * После того как с момента последней выгрузки прошло 5 минут (для каждого документа):
    * **document-updater**: выгружает документ из Redis в MongoDB
* **редактор**: отправляет дополнительные обновления
  * каждые 100 обновлений (для каждого документа):
    * **document-updater**: выгружает историю документа из Redis в MongoDB
* **пользователь**: выходит из редактора/закрывает вкладку браузера
  * 5 минут спустя
    * **real-time**: проверяет наличие других соавторов, если их нет:
      * **real-time** -> **document-updater**: выгружает документы из Redis в MongoDB

**Чтение из MongoDB в Redis**

* **document-updater** -> **web** -> **docstore**: чтение из MongoDB

**Выгрузка из Redis в MongoDB**

* **document-updater** -> **web** -> **docstore**: запись в MongoDB

**Компиляция — режим синхронизации «полный»**

* **редактор**: отправляет запрос на компиляцию с режимом синхронизации, установленным в «полный»
* **web** -> **document-updater**: все документы выгружаются из Redis в MongoDB
* **web** -> **docstore**: все документы загружаются из MongoDB
* **web** -> **clsi**: запрос на компиляцию отправляется в `clsi`, включая:
  * режим синхронизации
  * хэш дерева файлов -> «состояние проекта»
  * все документы с их содержимым -> с учётом лимита тела запроса 7 МБ
  * URL-адреса двоичных файлов для отдельной загрузки
* **clsi**: проверяет состояние на диске вместе с режимом синхронизации и «состоянием проекта»
  * это полная синхронизация, поэтому предыдущее состояние на диске можно игнорировать
* **clsi**: очищает каталог компиляции
* **clsi**: записывает все документы в каталог компиляции
* **clsi**: записывает все двоичные файлы в каталог компиляции
  * `clsi` копирует файлы из локального кэша для каждого проекта
  * при промахе кэша:
    * **clsi** -> **filestore**: загружает файлы
* **clsi**: записывает «состояние проекта»
* **clsi**: убеждается, что контейнер Docker существует с нужной конфигурацией
  * собирает параметры контейнера, включая версию texlive
  * параметры хэша
  * имя контейнера: `project-<project-id>-<user-id>-<hash>`
* **clsi**: запускает контейнер и передаёт stdout/stderr в память -> лимит 2 МБ
* **clsi**: оставляет остановленный контейнер -> очищается через 24 часа
* **clsi**: записывает stdout/stderr на диск
* **clsi**: копирует выходные файлы в уникальный каталог вывода
  * build-id состоит из 8 случайных байтов плюс временной метки с точностью до миллисекунд
  * удаляет все папки сборки, кроме последних 3 (анонимный) / последней 1 (вошедший в систему пользователь)
* **clsi**: компиляция завершилась с ошибкой/тайм-аутом
  * удаляет кэш компиляции — в нём могут быть частичные файлы/повреждённый кэш
* **редактор**: загружает output.log и output.pdf

**Компиляция — режим синхронизации «инкрементальный»**

* **редактор**: отправляет запрос на компиляцию с режимом синхронизации, установленным в «инкрементальный»
* **web** -> **document-updater**: получает любые документы из Redis
  * хэш «состояния проекта» также хранится в Redis
  * **web** отправляет хэш дерева файлов в `document-updater` и `document-updater` может преобразовать инкрементальную компиляцию в полную при несовпадении
    * см. процесс компиляции, выполняемый, когда редактор запрашивает «полную» компиляцию
* **web** -> **clsi**: запрос на компиляцию отправляется в `clsi`, включая:
  * режим синхронизации
  * хэш дерева файлов -> «состояние проекта»
  * все документы из Redis с их содержимым -> с учётом лимита тела запроса 7 МБ
  * без двоичных файлов
* **clsi**: проверяет состояние на диске вместе с режимом синхронизации и «состоянием проекта»
  * это инкрементальная синхронизация, поэтому «состояние проекта» должно совпадать
  * при несовпадении: ответить 409, позволить вебу повторить попытку с «полной» синхронизацией
    * см. процесс компиляции, выполняемый, когда редактор запрашивает «полную» компиляцию
* **clsi**: записывает обновлённые документы в каталог компиляции
* **clsi**: убеждается, что контейнер Docker существует с нужной конфигурацией
  * собирает параметры контейнера, включая версию texlive
  * параметры хэша
  * имя контейнера: `project-<project-id>-<user-id>-<hash>`
* **clsi**: запускает контейнер и передаёт stdout/stderr в память -> лимит 2 МБ
* **clsi**: оставляет остановленный контейнер -> очищается через 24 часа
* **clsi**: записывает stdout/stderr на диск
* **clsi**: копирует выходные файлы в уникальный каталог вывода
  * build-id состоит из 8 случайных байтов плюс временной метки с точностью до миллисекунд
  * удаляет все папки сборки, кроме последних 3 (анонимный) / последней 1 (вошедший в систему пользователь)
* **clsi**: компиляция завершилась с ошибкой/тайм-аутом
  * удаляет кэш компиляции — в нём могут быть частичные файлы/повреждённый кэш
* **редактор**: загружает output.log и output.pdf

**Компиляция — переключение между режимами**

* **редактор**: наблюдает сбой компиляции, следующая компиляция — «полная» компиляция
* **редактор**: наблюдает успешную компиляцию, следующая компиляция — «инкрементальная» компиляция


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/on-premises/ru/nachalo-raboty/microservices.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
