> 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/vi/cau-hinh/overleaf-toolkit/bien-dich-trong-moi-truong-sandbox.md).

# Biên dịch trong môi trường sandbox

Overleaf Pro đi kèm tùy chọn chạy quá trình biên dịch trong môi trường sandbox an toàn cho bảo mật doanh nghiệp. Nó làm điều này bằng cách chạy mọi dự án trong môi trường docker được bảo vệ riêng của nó.

### Bảo mật được cải thiện

Biên dịch trong sandbox là cách được khuyến nghị cho Server Pro vì nhiều tài liệu LaTeX cần/có khả năng thực thi các lệnh shell tùy ý như một phần của quá trình biên dịch PDF. Nếu bạn dùng Biên dịch trong sandbox, mỗi lần biên dịch sẽ chạy trong một container Docker riêng với các khả năng hạn chế, không được chia sẻ với bất kỳ người dùng hay dự án nào khác và không có quyền truy cập vào các tài nguyên bên ngoài như mạng máy chủ.

{% hint style="warning" %}
Nếu bạn cố chạy Overleaf Pro **mà không có** Biên dịch trong sandbox, quá trình biên dịch sẽ chạy cùng với các lần biên dịch đồng thời khác bên trong container Docker chính và người dùng có toàn quyền đọc và ghi đối với `sharelatex` các tài nguyên của container (hệ thống tệp, mạng và biến môi trường) khi chạy biên dịch LaTeX.
{% endhint %}

### Quản lý gói dễ dàng hơn

Để tránh phải cài đặt gói thủ công, chúng tôi khuyên bạn bật Biên dịch trong sandbox. Đây là một thiết lập có thể cấu hình trong Server Pro, cung cấp cho người dùng của bạn quyền truy cập vào cùng một môi trường TeX Live như trên overleaf.com nhưng trong chính bản cài đặt tại chỗ của bạn. Các ảnh TeX Live được dùng bởi Biên dịch trong sandbox chứa các gói và phông chữ phổ biến nhất đã được kiểm thử với các mẫu trong thư viện của chúng tôi, đảm bảo khả năng tương thích tối đa với các dự án tại chỗ.

Việc bật Biên dịch trong sandbox cho phép bạn cấu hình người dùng có thể chọn những phiên bản TeX Live nào trong dự án của họ, đồng thời đặt một phiên bản ảnh TeX Live mặc định cho các dự án mới.

{% hint style="info" %}
Nếu bạn cố chạy Overleaf Pro mà không có Biên dịch trong sandbox, phiên bản của bạn sẽ mặc định dùng một phiên bản lược đồ cơ bản của TeX Live cho các lần biên dịch. Phiên bản cơ bản này nhẹ và chỉ chứa một tập hợp rất hạn chế các gói LaTeX, nên rất có thể sẽ dẫn đến lỗi thiếu gói cho người dùng của bạn, đặc biệt nếu họ cố dùng các mẫu dựng sẵn.
{% endhint %}

Vì Overleaf Pro được thiết kế để hoạt động ngoại tuyến, không có cách tự động nào để tích hợp các mẫu trong thư viện overleaf.com vào bản cài đặt tại chỗ của bạn; tuy nhiên, có thể làm điều này thủ công theo từng mẫu. Để biết thêm thông tin về cách hoạt động, vui lòng xem hướng dẫn chuyển mẫu từ overleaf.com của chúng tôi: [/pages/8b9ba7d0925f6bd687383d61bc8206e570931bb0#transferring-templates-from-overleaf.com](https://overleaf-pro.ayaka.space/on-premises/vi/cau-hinh/overleaf-toolkit/pages/8b9ba7d0925f6bd687383d61bc8206e570931bb0#transferring-templates-from-overleaf.com "mention").

{% hint style="info" %}
Biên dịch trong sandbox yêu cầu `sharelatex` container có quyền truy cập vào Docker socket trên máy chủ (thông qua bind mount) để nó có thể quản lý các container biên dịch anh em này.
{% endhint %}

## Cách thức hoạt động

Khi Biên dịch trong sandbox được bật, Docker socket sẽ được gắn từ máy chủ vào `sharelatex` container, để dịch vụ biên dịch trong container có thể tạo các container Docker mới trên máy chủ. Sau đó, cho mỗi lần chạy trình biên dịch trong mỗi dự án, dịch vụ biên dịch LaTeX (CLSI) sẽ thực hiện như sau:

* Ghi các tệp dự án ra một vị trí bên trong `OVERLEAF_DATA_PATH`.
* Sử dụng Docker socket đã gắn để tạo một `texlive` container cho lần biên dịch.
* Để `texlive` container đọc dữ liệu dự án từ vị trí bên dưới `OVERLEAF_DATA_PATH`.
* Biên dịch dự án bên trong `texlive` container.

### Bật Biên dịch trong sandbox&#xD;

#### Dành cho người dùng Toolkit

Để bật biên dịch trong sandbox (còn gọi là Sibling containers), hãy đặt các tùy chọn cấu hình sau trong `overleaf-toolkit/config/overleaf.rc`:

{% code title="config/overleaf.rc" %}

```dotenv
SERVER_PRO=true
SIBLING_CONTAINERS_ENABLED=true
```

{% endcode %}

#### Dành cho người dùng Docker Compose <a href="#docker-compose-example" id="docker-compose-example"></a>

{% hint style="danger" %}
Bắt đầu từ Overleaf CE/Server Pro `5.0.3` các biến môi trường đã được đổi tên từ `SHARELATEX_*` đến `OVERLEAF_*`.
{% endhint %}

Nếu bạn đang dùng một `4.x` phiên bản (hoặc sớm hơn), hãy đảm bảo các biến được thêm tiền tố tương ứng (ví dụ: `SHARELATEX_MONGO_URL` thay vì `OVERLEAF_MONGO_URL`).

<pre class="language-yml"><code class="lang-yml">version: '2'
services:
    sharelatex:
        #...
        volumes:
            - /data/overleaf_data:/var/lib/overleaf
<strong>            - /var/run/docker.sock:/var/run/docker.sock
</strong>        environment:
            #...
<strong>            DOCKER_RUNNER: "true"
</strong><strong>            SANDBOXED_COMPILES: "true"
</strong><strong>            SANDBOXED_COMPILES_HOST_DIR: "/data/overleaf_data/data/compiles"
</strong>            #...
        #...
</code></pre>

### Thay đổi ảnh TexLive

{% hint style="info" %}
Đối với người dùng ở Trung Quốc đại lục, bạn có thể dùng `ghcr.nju.edu.cn` để tăng tốc tải xuống.&#x20;
{% endhint %}

Overleaf Pro sử dụng ba biến môi trường để xác định những ảnh TeX Live nào được dùng cho Biên dịch trong sandbox:

* `TEX_LIVE_DOCKER_IMAGE` **(bắt buộc),** Ảnh TeX Live mặc định được dùng để biên dịch các dự án mới. Ảnh này phải được đưa vào `ALL_TEX_LIVE_DOCKER_IMAGES`.
* `ALL_TEX_LIVE_DOCKER_IMAGE_NAMES` **(bắt buộc),** Danh sách tên thân thiện, phân tách bằng dấu phẩy, cho các ảnh, dùng cho các tùy chọn ở giao diện người dùng.
* `ALL_TEX_LIVE_DOCKER_IMAGES` **(bắt buộc),** Danh sách các ảnh TeX Live, phân tách bằng dấu phẩy, để sử dụng. Nếu dùng Overleaf Toolkit để triển khai, các ảnh này sẽ được tải xuống hoặc cập nhật. Để bỏ qua việc tải xuống, hãy đặt `SIBLING_CONTAINERS_PULL=false` trong `config/overleaf.rc`.

Khi khởi động phiên bản Overleaf Pro của bạn bằng `bin/up` lệnh, Toolkit sẽ tự động kéo tất cả các ảnh được liệt kê trong `ALL_TEX_LIVE_DOCKER_IMAGES`.

Đây là một ví dụ trong đó chúng tôi mặc định dùng TeX Live 2025 cho các dự án mới, và giữ 2024 cho các dự án hiện có.

{% code title="config/variables.env" overflow="wrap" %}

```dotenv
ALL_TEX_LIVE_DOCKER_IMAGES=ghcr.io/ayaka-notes/texlive-full:2025.1, ghcr.io/ayaka-notes/texlive-full:2024.1
ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=Texlive 2025, Texlive 2024
TEX_LIVE_DOCKER_IMAGE=ghcr.io/ayaka-notes/texlive-full:2025.1
```

{% endcode %}

{% hint style="danger" %}
Rất khuyến nghị đặt **ít nhất 2 ảnh texlive-full**. Để biết lý do chi tiết, xem [#known-issues](#known-issues "mention")
{% endhint %}

### Các ảnh TeX Live khả dụng

Đây là một loạt ảnh TeX Live được tối ưu hóa đặc biệt cho Overleaf, cũng có thể được thêm vào `TEX_LIVE_DOCKER_IMAGE` và `ALL_TEX_LIVE_DOCKER_IMAGES`:&#x20;

* `ghcr.io/ayaka-notes/texlive-full:2025.1` (Cũng là `latest` thẻ)
* `ghcr.io/ayaka-notes/texlive-full:2024.1`
* `ghcr.io/ayaka-notes/texlive-full:2023.1`
* `ghcr.io/ayaka-notes/texlive-full:2022.1`
* `ghcr.io/ayaka-notes/texlive-full:2021.1`
* `ghcr.io/ayaka-notes/texlive-full:2020.1`

{% hint style="warning" %}
Có một lược đồ nghiêm ngặt về cách các ảnh **phải** được gắn thẻ (áp dụng biểu thức chính quy sau `^[0-9]+.[0-9]+` , trong đó số đầu tiên xác định năm TeX Live và số thứ hai xác định phiên bản bản vá).
{% endhint %}

### Tôi có thể dùng registry ảnh khác không

> Một số người có thể thắc mắc liệu tôi có thể thay thế `ghcr.io` bằng một trang gương khác, hoặc chuyển texlive sang ảnh khác từ Docker Hub không?

Không, chúng tôi không khuyến nghị vì cấu hình khá phức tạp. Nếu bạn tải xuống từ một trang gương, bạn có thể đổi tên ảnh của mình thành `ghcr.io/ayaka-notes/texlive-full`.

Nhưng nếu bạn thực sự muốn dùng registry ảnh của riêng mình, vui lòng thêm:

{% code title="config/variables.env" overflow="wrap" %}

```dotenv
IMAGE_ROOT=hub.your.com/your-repo
```

{% endcode %}

Sau đó, bạn cần đảm bảo tất cả các ảnh của texlive đều nằm trong `your-repo`, chẳng hạn như

* `hub.your.com/your-repo/texlive-full:2025.1`
* `hub.your.com/your-repo/texlive-full:2024.1`

Để biết thông tin chi tiết, hãy đọc mã nguồn bên dưới để hiểu cách chúng tôi phân tích biến môi trường của bạn:

{% code title="sandboxed-compiles/index.mjs" overflow="wrap" expandable="true" %}

```mjs
if (process.env.SANDBOXED_COMPILES === 'true') {
  // Đặt thư mục gốc ảnh mặc định nếu chưa được cung cấp
  let imageRootPath = process.env.IMAGE_ROOT || "ghcr.io/ayaka-notes";
  // Xuất imageRoot sang Settings
  Settings.imageRoot = imageRootPath

  // allowedImageNames phải là:
  // [
  //  { imageName: "texlive-2023:latest", imageDesc: "TeX Live 2023" },
  //  { imageName: "texlive-2022:latest", imageDesc: "TeX Live 2022" },
  // ]
  Settings.allowedImageNames = parseTextExtensions(process.env.ALL_TEX_LIVE_DOCKER_IMAGES)
    .map((texImage, index) => ({
      imageName: texImage.split("/")[texImage.split("/").length - 1],
      imageDesc: parseTextExtensions(process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES)[index]
        || texImage.split(':')[1],
    }))
  
  // Cuối cùng, imageName sẽ được ghép với imageRoot để tạo thành đường dẫn ảnh đầy đủ
  // Tên đầy đủ sẽ như: ghcr.io/ayaka-notes/texlive-2023:latest

  // Đặt tên ảnh mặc định nếu chưa được cung cấp
  if(!process.env.TEX_LIVE_DOCKER_IMAGE) {
    process.env.TEX_LIVE_DOCKER_IMAGE = imageRootPath + "/" + Settings.allowedImageNames[0].imageName
  }

  // Xuất currentImageName sang Settings
  // Đây là tên ảnh của các dự án mới được tạo
  Settings.currentImageName = process.env.TEX_LIVE_DOCKER_IMAGE
}
```

{% endcode %}

### Các vấn đề đã biết

> Sử dụng `6.0.1-ext-v3.3`, tôi có các thiết lập sau trong `variables.env`:
>
> ```dotenv
> TEX_LIVE_DOCKER_IMAGE=texlive/texlive:latest-full
> ALL_TEX_LIVE_DOCKER_IMAGES=texlive/texlive:latest-full
> ```
>
> Cái này hoạt động tốt với `texlive/texlive:latest-full`. Tuy nhiên, tôi đã kéo một ảnh texlive khác `danteev/texlive:2025-10-15` và đã thay đổi cả hai biến này thành tên ảnh mới nhưng nó không hoạt động:
>
> ```dotenv
> TEX_LIVE_DOCKER_IMAGE=danteev/texlive:2025-10-15
> ALL_TEX_LIVE_DOCKER_IMAGES=danteev/texlive:2025-10-15
> ```
>
> Trong nhật ký, tôi thấy như sau:
>
> {% code overflow="wrap" %}
>
> ```
> {"name":"clsi","level":50,"err":{"message":"(HTTP code 404) no such container - No such image: texlive/texlive:latest-full ","name":"Error","stack":"Error: (HTTP code 404) no such container - No such image: texlive/texlive:latest-full ... 
> ```
>
> {% endcode %}
>
> Có vẻ như các thiết lập đã cập nhật trong `variables.env` không có hiệu lực. Quá trình biên dịch vẫn cố chạy `texlive/texlive:latest-full` ảnh cũ, không phải ảnh mới.
>
> Tôi đã thử khởi động lại, xóa các container rồi chạy lại, nhưng vẫn cùng một vấn đề.
>
> Có giải pháp nào không?

Do một số hạn chế kỹ thuật, nếu bạn chỉ thiết lập một ảnh Docker TeXLive duy nhất, chẳng hạn như `texlive-fullA:latest`&#x20;

```
ALL_TEX_LIVE_DOCKER_IMAGES=texlive/texliveA:latest-full
ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=TeXLiveA
TEX_LIVE_DOCKER_IMAGE=texlive/texliveA:latest-full
```

Và sau khi chạy phiên bản overleaf của bạn một thời gian, bạn có thể muốn sửa ảnh TeXLive thành `texlive-fullB:latest`. Khi đó, bạn sẽ thấy người dùng của bạn không thể biên dịch tất cả các dự án.

```
ALL_TEX_LIVE_DOCKER_IMAGES=texlive/texliveA:latest-full
ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=TeXLiveA
TEX_LIVE_DOCKER_IMAGE=texlive/texliveA:latest-full
```

Điều này là do tên ảnh TeXLive-Full (dành cho biên dịch sandbox) trong từng dự án được lưu cố định trong cơ sở dữ liệu. *Chỉ khi người dùng chuyển phiên bản TeXLive của dự án, ví dụ từ 2024 sang 2025, thì tên ảnh mới được thay đổi trong cơ sở dữ liệu*.

Khi CLSI biên dịch một dự án, nó dùng tên ảnh container tìm thấy trong cơ sở dữ liệu để trực tiếp biên dịch dự án.

Nếu bạn chỉ cung cấp một ảnh Docker, người dùng sẽ không thể sửa ảnh được dùng để biên dịch dự án. Trong trường hợp này, bạn cần viết một script để **sửa thủ công** ảnh TeXLive cho tất cả các dự án của người dùng trong mongoDB.

### Gỡ lỗi

Chạy lệnh sau để kiểm tra nhật ký clsi từ toolkit:

{% code overflow="wrap" %}

```bash
bin/logs clsi
```

{% endcode %}


---

# 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/vi/cau-hinh/overleaf-toolkit/bien-dich-trong-moi-truong-sandbox.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.
