> 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/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 컨테이너 외에 이들 데이터베이스 각각에 대한 컨테이너를 프로비저닝하여, 총 세 개의 Docker 컨테이너를 만듭니다.

{% hint style="info" %}
기존 MongoDB 또는 Redis 인스턴스에 연결하려면, [overleaf.rc](https://overleaf-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" 동기화 모드**

* **편집기**: sync-mode를 "full"로 설정해 컴파일 요청을 보냄
* **web** -> **document-updater**: Redis의 모든 문서가 MongoDB로 플러시됨
* **web** -> **docstore**: 모든 문서가 MongoDB에서 다운로드됨
* **web** -> **clsi**: 컴파일 요청이 다음으로 전송됨 `clsi`, 다음을 포함하여:
  * sync-mode
  * 파일 트리의 해시 -> "프로젝트 상태"
  * 내용이 포함된 모든 문서 -> 7MB 요청 본문 제한 적용
  * 별도로 다운로드하기 위한 바이너리 파일 URL
* **clsi**: on-disk 상태를 sync-mode 및 "프로젝트 상태"와 확인
  * 이것은 전체 동기화이므로 이전 on-disk 상태는 무시할 수 있습니다
* **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**: 출력 파일을 고유한 출력 디렉터리로 복사
  * 8개의 임의 바이트와 밀리초 정밀도 타임스탬프로 구성된 build-id
  * 마지막 3개(비로그인 사용자) / 마지막 1개(로그인한 사용자) 빌드 폴더만 제외하고 모두 삭제
* **clsi**: 컴파일 실패/타임아웃
  * 컴파일 캐시를 삭제 — 부분 파일/손상된 캐시가 있을 수 있음
* **편집기**: output.log와 output.pdf를 다운로드함

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

* **편집기**: sync-mode를 "incremental"로 설정해 컴파일 요청을 보냄
* **web** -> **document-updater**: Redis에서 모든 문서를 가져옴
  * "프로젝트 상태" 해시도 Redis에 저장됨
  * **web** 파일 트리의 해시를 다음에 보냄 `document-updater` 그리고 `document-updater` 불일치 시 증분 컴파일을 전체 컴파일로 전환할 수 있음
    * 편집기가 "full" 컴파일을 요청했을 때 수행되는 컴파일 프로세스를 참조
* **web** -> **clsi**: 컴파일 요청이 다음으로 전송됨 `clsi`, 다음을 포함하여:
  * sync-mode
  * 파일 트리의 해시 -> "프로젝트 상태"
  * 내용이 포함된 Redis의 모든 문서 -> 7MB 요청 본문 제한 적용
  * 바이너리 파일 없음
* **clsi**: on-disk 상태를 sync-mode 및 "프로젝트 상태"와 확인
  * 이것은 증분 동기화이므로 "프로젝트 상태"가 일치해야 합니다
  * 불일치 시: 409로 응답하고, 웹이 "full" 동기화로 다시 시도하도록 둠
    * 편집기가 "full" 컴파일을 요청했을 때 수행되는 컴파일 프로세스를 참조
* **clsi**: 업데이트된 문서를 컴파일 디렉터리에 씀
* **clsi**: 원하는 구성으로 Docker 컨테이너가 존재하는지 확인
  * 컨테이너 옵션을 빌드하며, texlive 버전을 포함함
  * 해시 옵션
  * 컨테이너 이름: `project-<project-id>-<user-id>-<hash>`
* **clsi**: 컨테이너를 시작하고 stdout/stderr를 메모리로 스트리밍 -> 2MB 제한
* **clsi**: 중지된 컨테이너를 남겨 둠 -> 24시간 후 정리됨
* **clsi**: stdout/stderr를 디스크에 씀
* **clsi**: 출력 파일을 고유한 출력 디렉터리로 복사
  * 8개의 임의 바이트와 밀리초 정밀도 타임스탬프로 구성된 build-id
  * 마지막 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://overleaf-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.
