> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Biên dịch trong sandbox

Ayakaleaf Pro đi kèm tùy chọn chạy biên dịch trong môi trường sandbox an toàn nhằm đáp ứng yêu cầu bảo mật của doanh nghiệp. Điều này được thực hiện bằng cách chạy mỗi dự án trong môi trường docker an toàn riêng của nó.

### Cải thiện bảo mật

Biên dịch trong sandbox (Sandboxed Compiles) là cách tiếp cận được khuyến nghị cho Ayakaleaf Pro, vì nhiều tài liệu LaTeX yêu cầu/có khả năng thực thi các lệnh shell tùy ý trong quá trình biên dịch PDF. Nếu bạn sử dụng Sandboxed Compiles, mỗi lần biên dịch sẽ chạy trong một Docker container riêng biệt với các quyền hạn chế, không 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 của máy chủ host.

<Warning>
  Nếu bạn chạy Ayakaleaf Pro **không có** Sandboxed Compiles, quá trình biên dịch sẽ chạy song song với các lần biên dịch đồng thời khác bên trong Docker container chính, và người dùng có toàn quyền đọc và ghi vào tài nguyên của container `sharelatex` (hệ thống tệp, mạng và biến môi trường) khi chạy biên dịch LaTeX.
</Warning>

### 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 nghị bật Sandboxed Compiles. Đây là một thiết lập có thể cấu hình trong Server Pro, cho phép người dùng của bạn truy cập cùng môi trường TeX Live như trên overleaf.com nhưng nằm trong bản cài đặt on-premise của riêng bạn. Các TeX Live image được Sandboxed Compiles sử dụng chứa những 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 on-premise.

Bật Sandboxed Compiles cho phép bạn cấu hình những phiên bản TeX Live mà người dùng có thể chọn trong dự án của họ, đồng thời thiết lập phiên bản TeX Live image mặc định cho các dự án mới.

<Info>
  Nếu bạn chạy Ayakaleaf Pro mà không có Sandboxed Compiles, phiên bản của bạn sẽ mặc định sử dụng một phiên bản TeX Live với scheme cơ bản để biên dịch. Phiên bản cơ bản này nhẹ và chỉ chứa một tập con rất hạn chế các gói LaTeX, điều này rất có thể sẽ dẫn đến lỗi thiếu gói cho người dùng, đặc biệt nếu họ dùng các mẫu dựng sẵn.
</Info>

Vì Ayakaleaf 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 của overleaf.com vào bản cài đặt on-premise của bạn; tuy nhiên, có thể thực hiện việc này thủ công cho từng mẫu. Để biết thêm thông tin về cách thực hiện, vui lòng xem hướng dẫn chuyển mẫu từ overleaf.com của chúng tôi: [#transferring-templates-from-overleaf.com](/vi/on-premises/configuration/overleaf-toolkit/templates#transferring-templates-from-overleaf.com "mention").

<Info>
  Sandboxed Compiles yêu cầu container `sharelatex` có quyền truy cập vào Docker socket trên máy chủ host (thông qua bind mount) để có thể quản lý các container biên dịch anh em (sibling) này.
</Info>

## Cách hoạt động

Khi Sandboxed Compiles được bật, Docker socket sẽ được mount từ máy chủ host vào container `sharelatex`, để dịch vụ biên dịch trong container có thể tạo các Docker container mới trên host. Sau đó, với 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 các bước sau:

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

### Bật Sandboxed Compiles

#### 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`:

```dotenv title="config/overleaf.rc" theme={null}
SERVER_PRO=true
SIBLING_CONTAINERS_ENABLED=true
```

#### Dành cho người dùng Docker Compose

<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_*` thành `OVERLEAF_*`.
</Danger>

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

```yml theme={null}
version: '2'
services:
    sharelatex:
        #...
        volumes:
            - /data/overleaf_data:/var/lib/overleaf
            - /var/run/docker.sock:/var/run/docker.sock
        environment:
            #...
            DOCKER_RUNNER: "true"
            SANDBOXED_COMPILES: "true"
            SANDBOXED_COMPILES_HOST_DIR: "/data/overleaf_data/data/compiles"
            #...
        #...
```

### Thiết lập TexLive Image

<Info>
  Đối với người dùng tại Trung Quốc đại lục, bạn có thể thay `ghcr.io` bằng `ghcr.nju.edu.cn` để tăng tốc độ tải xuống. Nhưng **KHÔNG** sử dụng trực tiếp `ghcr.nju.edu.cn` trong các thiết lập biến môi trường của toolkit. Bạn nên giữ `ghcr.io` là lựa chọn duy nhất.
</Info>

Ayakaleaf Pro sử dụng ba biến môi trường để xác định các TeX Live image được dùng cho Sandboxed Compiles:

* `TEX_LIVE_DOCKER_IMAGE` <strong>(bắt buộc),</strong> TeX Live image mặc định dùng để biên dịch các dự án mới. Image này phải nằm trong `ALL_TEX_LIVE_DOCKER_IMAGES`.
* `ALL_TEX_LIVE_DOCKER_IMAGE_NAMES` <strong>(bắt buộc),</strong> Danh sách tên thân thiện của các image, phân tách bằng dấu phẩy, được dùng cho các tùy chọn ở frontend.
* `ALL_TEX_LIVE_DOCKER_IMAGES` <strong>(bắt buộc),</strong> Danh sách các TeX Live image sẽ sử dụng, phân tách bằng dấu phẩy. Nếu Overleaf Toolkit được dùng để triển khai, các image 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 Ayakaleaf Pro bằng lệnh `bin/up`, Toolkit sẽ tự động pull tất cả các image được liệt kê trong `ALL_TEX_LIVE_DOCKER_IMAGES`.

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

<Tabs>
  <Tab title="Cài đặt tối thiểu">
    Cấu hình sau cài đặt tất cả các TeX Live Docker image đầy đủ từ 2025 đến 2026. Chúng tôi khuyến nghị có ít nhất **64 GB** dung lượng lưu trữ trống trước khi sử dụng cấu hình này.

    ```dotenv title="config/variables.env" wrap theme={null}
    ALL_TEX_LIVE_DOCKER_IMAGES=ghcr.io/ayaka-notes/texlive-full:2026.1, ghcr.io/ayaka-notes/texlive-full:2025.1
    ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=Texlive 2026, Texlive 2025
    TEX_LIVE_DOCKER_IMAGE=ghcr.io/ayaka-notes/texlive-full:2026.1
    ```
  </Tab>

  <Tab title="Cài đặt đầy đủ">
    Cấu hình sau cài đặt tất cả các TeX Live Docker image đầy đủ từ 2020 đến 2026. Chúng tôi khuyến nghị có ít nhất **150 GB** dung lượng lưu trữ trống trước khi sử dụng cấu hình này.

    ```dotenv title="config/variables.env" wrap theme={null}
    ALL_TEX_LIVE_DOCKER_IMAGES=ghcr.io/ayaka-notes/texlive-full:2026.1,ghcr.io/ayaka-notes/texlive-full:2025.1,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
    ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=Texlive 2026,Texlive 2025,Texlive 2024,Texlive 2023,Texlive 2022,Texlive 2021,Texlive 2020
    TEX_LIVE_DOCKER_IMAGE=ghcr.io/ayaka-notes/texlive-full:2026.1
    ```
  </Tab>
</Tabs>

<Danger>
  Chúng tôi đặc biệt khuyến nghị thiết lập **ít nhất 2 image texlive-full**. Để biết lý do chi tiết, xem [#known-issues](/vi/on-premises/configuration/overleaf-toolkit/sandboxed-compiles#known-issues "mention")
</Danger>

### Các TeX Live image có sẵn

Đây là một loạt TeX Live image đượ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`:

* `ghcr.io/ayaka-notes/texlive-full:2026.1` (cũng là tag `latest`)
* `ghcr.io/ayaka-notes/texlive-full:2025.1`
* `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`

<Warning>
  Có một quy tắc nghiêm ngặt về cách image **bắt buộc** phải được gắn tag (áp dụng regex `^[0-9]+.[0-9]+`, trong đó số đầu tiên xác định năm của TeX Live và số thứ hai là phiên bản bản vá).
</Warning>

### Tôi có thể sử dụng Image Registry khác không

> Một số người có thể thắc mắc liệu có thể thay `ghcr.io` bằng một trang mirror khác, hoặc chuyển texlive sang image khác từ docker hub không?

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

Tuy nhiên, nếu bạn thực sự muốn sử dụng Image Registry của riêng mình, hãy thêm:

```dotenv title="config/variables.env" wrap theme={null}
IMAGE_ROOT=hub.your.com/your-repo
```

Sau đó, bạn cần đảm bảo tất cả các image texlive đều nằm trong `your-repo`, ví dụ

* `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 dưới đây để hiểu cách chúng tôi phân tích biến môi trường của bạn:

```mjs title="sandboxed-compiles/index.mjs" wrap expandable theme={null}
if (process.env.SANDBOXED_COMPILES === 'true') {
  // Set default image root if not provided
  let imageRootPath = process.env.IMAGE_ROOT || "ghcr.io/ayaka-notes";
  // Export imageRoot to Settings
  Settings.imageRoot = imageRootPath

  // allowedImageNames should be:
  // [
  //  { 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],
    }))
  
  // In the end, imageName will be put together with imageRoot to form the full image path
  // The full name will be like: ghcr.io/ayaka-notes/texlive-2023:latest

  // Set default image name if not provided
  if(!process.env.TEX_LIVE_DOCKER_IMAGE) {
    process.env.TEX_LIVE_DOCKER_IMAGE = imageRootPath + "/" + Settings.allowedImageNames[0].imageName
  }

  // Export currentImageName to Settings
  // This is the new created projects' image name
  Settings.currentImageName = process.env.TEX_LIVE_DOCKER_IMAGE
}
```

### Tự động đồng bộ TeX Live Image

Để tránh phải cập nhật thủ công phiên bản của bạn bằng `bin/up` mỗi lần, bạn có thể tự động hóa việc cập nhật TeX Live image. Xem [updating-tex-live-full-images-automatically.md](/vi/on-premises/maintenance/updating-tex-live-full-images-automatically "mention").

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

Đây là một trường hợp thực tế từ cộng đồng Overleaf:

> Khi dùng `6.0.1-ext-v3.3`, tôi có các thiết lập sau trong `variables.env`:
>
> ```dotenv theme={null}
> TEX_LIVE_DOCKER_IMAGE=texlive/texlive:latest-full
> ALL_TEX_LIVE_DOCKER_IMAGES=texlive/texlive:latest-full
> ```
>
> Cấu hình này hoạt động tốt với `texlive/texlive:latest-full`. Tuy nhiên, tôi đã pull một texlive image khác là `danteev/texlive:2025-10-15` và đổi cả hai biến này sang tên image mới nhưng nó không hoạt động:
>
> ```dotenv theme={null}
> TEX_LIVE_DOCKER_IMAGE=danteev/texlive:2025-10-15
> ALL_TEX_LIVE_DOCKER_IMAGES=danteev/texlive:2025-10-15
> ```
>
> Trong log, tôi thấy như sau:
>
> ```text wrap theme={null}
> {"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 ... 
> ```
>
> 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 image `texlive/texlive:latest-full`, chứ không phải image mới.
>
> Tôi đã thử khởi động lại, xóa các container và chạy lại, nhưng vẫn gặp vấn đề tương tự.
>
> 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 Docker TeXLive image duy nhất, chẳng hạn như `texlive-fullA:latest`

```text theme={null}
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 đổi TeXLive image thành `texlive-fullB:latest`. Khi đó, bạn sẽ thấy người dùng của mình không thể biên dịch bất kỳ dự án nào.

```text theme={null}
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 của TeXLive-Full image (dùng cho biên dịch trong sandbox) của mỗi 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 image mới được thay đổi trong cơ sở dữ liệu*.

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

Nếu bạn chỉ cung cấp một Docker image, người dùng sẽ không thể thay đổi image 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** TeXLive image cho tất cả các dự án của người dùng trong mongoDB.

### Gỡ lỗi và báo cáo

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

```bash wrap theme={null}
bin/logs clsi
```

Nếu bạn gặp bất kỳ vấn đề nào khi biên dịch với các TeX Live image, vui lòng gửi issue tại đây:

[https://github.com/ayaka-notes/texlive-full/issues/new?template=texlive-image-bug.yml](https://github.com/ayaka-notes/texlive-full/issues/new?template=texlive-image-bug.yml)

Để giúp chúng tôi tái hiện và khắc phục sự cố, bạn có thể được yêu cầu tải dự án của mình lên Overleaf. Sau đó, chúng tôi sẽ pull dự án và chạy thử nghiệm biên dịch bằng GitHub Action.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.