跳轉到

Docker 設定

Gotenberg 是一個 Docker 原生的服務,官方提供多種映像變體。本頁說明如何設定 Gotenberg 服務以配合 nextpdf/gotenberg 套件使用,包含字型安裝、API 認證與生產環境強化。

PHP Compatibility

This example uses PHP 8.5 syntax. If your environment runs PHP 8.1 or 7.4, use NextPDF Backport for a backward-compatible build.

快速啟動(開發環境)

# 啟動 Gotenberg(Chromium + LibreOffice)
docker run --rm \
    --name gotenberg \
    -p 3000:3000 \
    gotenberg/gotenberg:8

確認服務正常運作:

curl http://localhost:3000/health
# 預期回傳:{"status":"up","details":{...}}

docker-compose 設定

# docker-compose.yml
services:
  app:
    build: .
    environment:
      GOTENBERG_URL: http://gotenberg:3000
      GOTENBERG_API_KEY: ${GOTENBERG_API_KEY}
    depends_on:
      gotenberg:
        condition: service_healthy

  gotenberg:
    image: gotenberg/gotenberg:8
    ports:
      - "3000:3000"
    environment:
      # API 金鑰認證(強烈建議在生產環境啟用)
      GOTENBERG_API_BASIC_AUTH_USERNAME: nextpdf
      GOTENBERG_API_BASIC_AUTH_PASSWORD: ${GOTENBERG_API_KEY}

      # Chromium 設定
      GOTENBERG_CHROMIUM_ALLOW_LIST: "https?://.*"
      GOTENBERG_CHROMIUM_DENY_LIST: ""
      GOTENBERG_CHROMIUM_DISABLE_JAVASCRIPT: "false"

      # LibreOffice 設定
      GOTENBERG_LIBREOFFICE_RESTART_AFTER: "10"  # 每 10 次轉換後重啟 LibreOffice(記憶體洩漏緩解)

      # 逾時設定
      GOTENBERG_TIMEOUT: "30s"

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s

    deploy:
      resources:
        limits:
          memory: 2G    # LibreOffice + Chromium 記憶體需求較高
          cpus: '2.0'

自訂字型安裝

Office 文件轉換品質高度依賴字型可用性。建立自訂映像以安裝必要字型:

# Dockerfile.gotenberg
FROM gotenberg/gotenberg:8

# 切換至 root 安裝字型
USER root

# 安裝微軟字型(需同意授權條款)
RUN apt-get update && \
    echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | \
    debconf-set-selections && \
    apt-get install -y --no-install-recommends \
        ttf-mscorefonts-installer \
        fonts-noto-cjk \          # 中日韓字體(重要:處理 CJK 文件)
        fonts-noto-cjk-extra \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# 複製自訂商業字型(需持有合法授權)
COPY --chown=root:root ./custom-fonts/*.ttf /usr/local/share/fonts/
COPY --chown=root:root ./custom-fonts/*.otf /usr/local/share/fonts/

# 更新字型快取
RUN fc-cache -fv

# 切換回非 root 使用者
USER gotenberg
# 建置自訂映像
docker build -f Dockerfile.gotenberg -t my-gotenberg:latest .

授權須知:微軟 TrueType 核心字型(Arial、Times New Roman、Calibri 等)的使用受 Microsoft 授權條款約束。商業部署前請確認授權合規。

安全強化

API 認證

# docker-compose.production.yml
services:
  gotenberg:
    image: my-gotenberg:latest
    environment:
      GOTENBERG_API_BASIC_AUTH_USERNAME: nextpdf-prod
      GOTENBERG_API_BASIC_AUTH_PASSWORD: "${GOTENBERG_SECRET}" # 從 Vault 或 Secrets 讀取
    # 不暴露 port 至主機——只允許同網段 app 容器存取
    expose:
      - "3000"
    networks:
      - internal
    # 唯讀根目錄(減少攻擊面)
    read_only: true
    tmpfs:
      - /tmp
      - /home/gotenberg

在 PHP 中設定 Basic Auth:

use NextPDF\Gotenberg\Config\GotenbergConfig;
use NextPDF\Gotenberg\Config\AuthConfig;

$config = GotenbergConfig::create(
    baseUrl: 'http://gotenberg:3000',
    auth: AuthConfig::basicAuth(
        username: $_ENV['GOTENBERG_AUTH_USERNAME'],
        password: $_ENV['GOTENBERG_AUTH_PASSWORD'],
    ),
);

防止 SSRF

environment:
  # 只允許存取內部網段,阻擋外部 URL
  GOTENBERG_CHROMIUM_ALLOW_LIST: "https?://app\\.internal\\..*"
  GOTENBERG_CHROMIUM_DENY_LIST: "https?://.*\\.example\\.com"

  # 禁止存取本機 IP(防止 SSRF 攻擊內部服務)
  GOTENBERG_CHROMIUM_DISABLE_ROUTES: "true"

Kubernetes 部署

# k8s/gotenberg-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gotenberg
  labels:
    app: gotenberg
spec:
  replicas: 2
  selector:
    matchLabels:
      app: gotenberg
  template:
    metadata:
      labels:
        app: gotenberg
    spec:
      containers:
        - name: gotenberg
          image: my-gotenberg:latest
          ports:
            - containerPort: 3000
          env:
            - name: GOTENBERG_API_BASIC_AUTH_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: gotenberg-secret
                  key: api-password
          resources:
            requests:
              memory: "512Mi"
              cpu: "500m"
            limits:
              memory: "2Gi"
              cpu: "2000m"
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 15
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: gotenberg
spec:
  selector:
    app: gotenberg
  ports:
    - port: 3000
      targetPort: 3000
  type: ClusterIP  # 不對外暴露

效能調校

設定 建議值(生產) 說明
GOTENBERG_TIMEOUT 60s 複雜文件的轉換時間上限
GOTENBERG_LIBREOFFICE_RESTART_AFTER 10-50 每 N 次轉換後重啟 LibreOffice
容器記憶體限制 2Gi+ LibreOffice 記憶體需求高
副本數 2+ 高可用性 + 負載分散

參見