Skip to content

Docker 設定

在容器化環境中執行 Artisan 需要正確安裝 Chromium,並配置適當的安全與資源參數。本頁提供經過生產環境驗證的 Dockerfile 與 docker-compose 設定。

Dockerfile

以下 Dockerfile 基於 PHP 官方映像,安裝 Chromium 與所需的中文字型:

dockerfile
FROM php:8.5-fpm-alpine

# 安裝 Chromium 與系統依賴
RUN apk add --no-cache \
    chromium \
    nss \
    freetype \
    harfbuzz \
    ca-certificates \
    ttf-freefont

# 安裝中文字型(繁體中文支援)
RUN apk add --no-cache font-noto-cjk

# 設定 Chrome 環境變數
ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/ \
    PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true

# 安裝 PHP 擴充
RUN docker-php-ext-install opcache

# 複製應用程式
COPY . /var/www/html
WORKDIR /var/www/html

RUN composer install --no-dev --optimize-autoloader

docker-compose.yml

yaml
services:
  app:
    build: .
    volumes:
      - ./storage:/var/www/html/storage
    environment:
      - TCPDF_CHROME_PATH=/usr/bin/chromium-browser
    # Chrome 需要的核心能力
    cap_add:
      - SYS_ADMIN
    # 或者使用 --no-sandbox(見下方安全性說明)
    tmpfs:
      - /tmp:size=512M
    deploy:
      resources:
        limits:
          memory: 1G

Chrome 無頭模式啟動參數

在容器中執行 Chrome 時,建議使用以下參數:

php
HtmlRenderer::create(chromePath: '/usr/bin/chromium-browser')
    ->chromeArgs([
        '--headless=new',
        '--no-sandbox',
        '--disable-dev-shm-usage',
        '--disable-gpu',
        '--disable-software-rasterizer',
        '--disable-extensions',
        '--disable-background-networking',
        '--single-process',
        '--font-render-hinting=none',
    ]);

參數說明

參數用途
--headless=new使用新版無頭模式(Chrome 112+)
--no-sandbox容器內無法使用沙箱,需搭配其他安全措施
--disable-dev-shm-usage避免 /dev/shm 空間不足導致崩潰
--disable-gpu容器通常沒有 GPU,停用以減少錯誤
--single-process減少記憶體使用,適合單次渲染
--font-render-hinting=none確保跨平台字型渲染一致性

安全性考量

WARNING

--no-sandbox 會停用 Chrome 的沙箱保護。在生產環境中,請搭配以下措施:

  1. 以非 root 使用者執行 Chrome — 在 Dockerfile 中建立專用使用者:
dockerfile
RUN addgroup -S chrome && adduser -S chrome -G chrome
USER chrome
  1. 使用 SYS_ADMIN 能力代替 --no-sandbox — 如果你的部署環境允許:
yaml
cap_add:
  - SYS_ADMIN
# 此時可移除 --no-sandbox 參數
  1. 限制網路存取 — 如果不需要從外部 URL 載入內容,限制 Chrome 只能存取本地資源。

記憶體管理

Chrome 渲染會消耗大量記憶體,特別是渲染複雜頁面時。建議:

  • 容器記憶體限制: 至少 512MB,建議 1GB 以上。
  • tmpfs 掛載:/tmp 掛載為 tmpfs,提升暫存檔案的讀寫速度。
  • --disable-dev-shm-usage Docker 預設的 /dev/shm 只有 64MB,此參數讓 Chrome 改用 /tmp
yaml
deploy:
  resources:
    limits:
      memory: 1G
    reservations:
      memory: 512M
tmpfs:
  - /tmp:size=512M

字型安裝

PDF 的中文顯示取決於容器中是否安裝了對應的字型:

dockerfile
# Alpine — Noto CJK 字型(涵蓋繁體中文、簡體中文、日文、韓文)
RUN apk add --no-cache font-noto-cjk

# Debian/Ubuntu — 同上
RUN apt-get update && apt-get install -y fonts-noto-cjk && rm -rf /var/lib/apt/lists/*

如果需要使用自訂字型,將字型檔案複製到容器中並更新字型快取:

dockerfile
COPY ./fonts/*.ttf /usr/share/fonts/custom/
RUN fc-cache -f -v

生產環境檢查清單

部署前請確認以下各項:

  • [ ] Chromium 可正常執行 — chromium-browser --version
  • [ ] 中文字型已安裝 — fc-list :lang=zh
  • [ ] 記憶體限制已設定 — 建議至少 1GB
  • [ ] 非 root 使用者執行
  • [ ] tmpfs 已掛載於 /tmp
  • [ ] 健康檢查已設定
  • [ ] 渲染逾時已配置

以 LGPL-3.0-or-later 授權釋出。