> For the complete documentation index, see [llms.txt](https://ayakaleaf-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://ayakaleaf-pro.ayaka.space/on-premises/ko/getting-started/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 컨테이너에 더해 이 데이터베이스 각각에 대한 컨테이너를 프로비저닝하며, 총 3개의 Docker 컨테이너가 생성됩니다.

{% hint style="info" %}
기존 MongoDB 또는 Redis 인스턴스에 연결하고 싶다면, [overleaf.rc](https://ayakaleaf-pro.ayaka.space/on-premises/ko/getting-started/pages/e8fd72e52967a61b5950c2388c4f767c6f61266e#the-overleaf.rc-file) 구성 파일에서 적절한 설정을 지정하여 그렇게 할 수 있습니다.
{% endhint %}

#### 편집기 및 컴파일 과정

이 섹션에서는 문서 처리와 컴파일 과정에 대한 개괄적인 개요를 제공합니다.

{% hint style="info" %}
이 페이지는 Overleaf Pro에서만 제공되는 Sandboxed Compiles를 사용한 컴파일 과정을 설명합니다. Server CE에서는 컴파일 과정이 단순한 하위 프로세스를 사용합니다 — a를 참조하는 항목을 다음으로 바꾸세요 **컨테이너** 를 단일 항목 **하위 프로세스에서 컴파일 실행**.
{% 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에 쓰기

**컴파일 — "full" 동기화 모드**

* **편집기**: 동기화 모드를 "full"로 설정한 컴파일 요청을 보냄
* **web** -> **document-updater**: Redis의 문서가 MongoDB로 플러시됨
* **web** -> **docstore**: 모든 문서가 MongoDB에서 다운로드됨
* **web** -> **clsi**: 컴파일 요청이 다음으로 전송됨 `clsi`다음을 포함하여,
  * 동기화 모드
  * 파일 트리의 해시 -> "프로젝트 상태"
  * 내용이 포함된 모든 문서 -> 7MB 요청 본문 제한 적용
  * 별도 다운로드를 위한 바이너리 파일 URL
* **clsi**: 동기화 모드와 "프로젝트 상태"를 사용해 디스크의 상태를 확인
  * 이는 전체 동기화이므로 이전 디스크 상태는 무시할 수 있음
* **clsi**: 컴파일 디렉터리 정리
* **clsi**: 모든 문서를 컴파일 디렉터리에 기록
* **clsi**: 모든 바이너리 파일을 컴파일 디렉터리에 기록
  * `clsi` 프로젝트별 로컬 캐시에서 파일을 복사함
  * 캐시 미스 시:
    * **clsi** -> **filestore**: 파일 다운로드
* **clsi**: "프로젝트 상태"를 기록
* **clsi**: 원하는 구성으로 Docker 컨테이너가 존재하는지 확인
  * texlive 버전을 포함한 컨테이너 옵션 빌드
  * 옵션 해시
  * 컨테이너 이름: `project-<project-id>-<user-id>-<hash>`
* **clsi**: 컨테이너를 시작하고 stdout/stderr를 메모리로 스트리밍 -> 2MB 제한
* **clsi**: 중지된 컨테이너를 남겨둠 -> 24시간 후 정리됨
* **clsi**: stdout/stderr를 디스크에 기록
* **clsi**: 출력 파일을 고유한 출력 디렉터리로 복사
  * build-id는 8개의 랜덤 바이트와 밀리초 정밀도의 타임스탬프로 구성됨
  * 마지막 3개(익명 사용자) / 마지막 1개(로그인한 사용자) 빌드 폴더를 제외한 모든 항목 삭제
* **clsi**: 컴파일 실패/시간 초과
  * 컴파일 캐시 삭제 — 부분 파일/손상된 캐시가 있을 수 있음
* **편집기**: output.log와 output.pdf를 다운로드

**컴파일 — "incremental" 동기화 모드**

* **편집기**: 동기화 모드를 "incremental"로 설정한 컴파일 요청을 보냄
* **web** -> **document-updater**: Redis에서 문서 가져오기
  * "프로젝트 상태" 해시도 Redis에 저장됨
  * **web** 파일 트리의 해시를 다음으로 보냄 `document-updater` 및 `document-updater` 불일치 시 증분 컴파일을 전체 컴파일로 전환할 수 있음
    * 편집기가 "full" 컴파일을 요청했을 때 수행되는 컴파일 과정을 참조하세요
* **web** -> **clsi**: 컴파일 요청이 다음으로 전송됨 `clsi`다음을 포함하여,
  * 동기화 모드
  * 파일 트리의 해시 -> "프로젝트 상태"
  * 내용이 포함된 Redis의 모든 문서 -> 7MB 요청 본문 제한 적용
  * 바이너리 파일 없음
* **clsi**: 동기화 모드와 "프로젝트 상태"를 사용해 디스크의 상태를 확인
  * 이는 증분 동기화이므로 "프로젝트 상태"가 일치해야 함
  * 불일치 시: 409로 응답하고, 웹이 "full" 동기화로 재시도하도록 함
    * 편집기가 "full" 컴파일을 요청했을 때 수행되는 컴파일 과정을 참조하세요
* **clsi**: 업데이트된 문서를 컴파일 디렉터리에 기록
* **clsi**: 원하는 구성으로 Docker 컨테이너가 존재하는지 확인
  * texlive 버전을 포함한 컨테이너 옵션 빌드
  * 옵션 해시
  * 컨테이너 이름: `project-<project-id>-<user-id>-<hash>`
* **clsi**: 컨테이너를 시작하고 stdout/stderr를 메모리로 스트리밍 -> 2MB 제한
* **clsi**: 중지된 컨테이너를 남겨둠 -> 24시간 후 정리됨
* **clsi**: stdout/stderr를 디스크에 기록
* **clsi**: 출력 파일을 고유한 출력 디렉터리로 복사
  * build-id는 8개의 랜덤 바이트와 밀리초 정밀도의 타임스탬프로 구성됨
  * 마지막 3개(익명 사용자) / 마지막 1개(로그인한 사용자) 빌드 폴더를 제외한 모든 항목 삭제
* **clsi**: 컴파일 실패/시간 초과
  * 컴파일 캐시 삭제 — 부분 파일/손상된 캐시가 있을 수 있음
* **편집기**: output.log와 output.pdf를 다운로드

**컴파일 — 모드 전환**

* **편집기**: 컴파일 실패를 감지하면, 다음 컴파일은 "full" 컴파일임
* **편집기**: 컴파일 성공을 감지하면, 다음 컴파일은 "incremental" 컴파일임


---

# 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://ayakaleaf-pro.ayaka.space/on-premises/ko/getting-started/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.
