WebFont Sidecar 部署與維運
本文件說明 OdfKit.WebFonts.Sidecar.Host 的適用範圍、System.Web 設定、Windows
生命週期管理,以及非 Windows Server 環境的替代路徑。Sidecar 的唯一主要用途,是讓
ASP.NET Web Forms/.NET Framework 4.8 在要求階段產生 WOFF2。ASP.NET Core 在支援的
.NET Runtime 上直接使用 managed 引擎,不需要 Sidecar。
平台決策
| 網站平台 | 作業系統 | 建議路徑 |
|---|---|---|
| ASP.NET Web Forms/.NET Framework 4.8 | Windows Server | 使用 NativeAOT Sidecar;正式環境由受管程序監督器管理 |
| ASP.NET Web Forms/IIS Express | Windows 10/11 開發機 | 使用 sidecar.autoStart: true |
| ASP.NET Core | Windows Server、Windows 10/11 | 直接使用 managed 引擎,不部署 Sidecar |
| ASP.NET Core | Linux/macOS | 直接使用 managed 引擎,不部署 Sidecar |
| System.Web | Linux/macOS | 不支援;System.Web 與目前 Sidecar 發布產物均為 Windows 路徑 |
不要在 Linux/macOS 以 Wine、Mono 或相容層執行 Windows Sidecar。這些組合未進入支援矩陣, 也沒有具名 pipe、字型解析、檔案鎖定及瀏覽器端到端證據。
取得與驗證 Host
OdfKit.WebFonts.Sidecar NuGet 只包含 client library,不包含 Host。從相同版本的 GitHub
Release 取得符合目標架構的 ZIP:
win-x64:一般 x64 Windows Server 或 Windows 10/11。win-arm64:Windows ARM64;目前只有交叉發布證據,正式採用前仍須在目標機器驗收。
解壓縮前核對 Release 隨附的 OdfKit.WebFonts.Sidecar.Host-SHA256SUMS,並保留版本、RID、
SHA-256、下載來源及部署日期。Host 是 self-contained NativeAOT 執行檔,目標機器不需要安裝
.NET 10 Runtime。
可先確認執行檔與 WOFF2 Runtime 能力:
.\OdfKit.WebFonts.Sidecar.Host.exe --probe
成功輸出包含協定版本、woff2=True 及 Runtime Identifier。--probe 只驗證執行檔本身,
不會確認正式 Host 已啟動、pipe 可連線或權杖一致。
System.Web 設定
將完整字型、資產及 Host 分開放置,並限制 IIS 應用程式集區與 Sidecar 服務帳號的 ACL:
C:\OdfKitWebFonts\
Host\OdfKit.WebFonts.Sidecar.Host.exe
Fonts\TW-Sung-Plus-98_1.ttf
Fonts\TW-Kai-Plus-98_1.ttf
Assets\
Cache\
App_Data/webfonts.dynamic.json 使用固定 pipe、相同資產根目錄及明確 allowlist:
{
"schemaVersion": 1,
"assetRootPath": "C:\\OdfKitWebFonts\\Assets",
"allowManagedFallback": false,
"sidecar": {
"pipeName": "odfkit-webfonts-production",
"tokenEnvironmentVariable": "ODFKIT_WEBFONT_SIDECAR_TOKEN",
"tokenAppSettingName": "OdfKit.WebFonts.SidecarToken",
"tokenFilePath": "C:\\OdfKitWebFonts\\Secrets\\sidecar.token",
"connectTimeoutSeconds": 5,
"requestTimeoutSeconds": 180,
"maxMessageBytes": 4194304,
"autoStart": false,
"startupTimeoutSeconds": 15,
"stopWithApplicationProcess": false
},
"allowedFormats": [ "Woff2", "Woff", "TrueType" ]
}
正式環境應維持 autoStart: false。只要 JSON 具有有效 sidecar 區段,Handler 就會自動使用
Sidecar;前端不需要,也不應提供正式環境的啟用開關。allowManagedFallback 是受信任診斷
功能,不是 Sidecar 故障時的靜默遞補。
Host 與 System.Web 必須使用相同:
- pipe 名稱;
- 資產根目錄;
- 至少 32 UTF-8 bytes 的高熵 Sidecar token;
- 字型來源 ID;
- 套件/協定版本。
Host 命令列
正式 Host 的最小命令列如下:
$env:ODFKIT_WEBFONT_SIDECAR_TOKEN = '<secret-store-value>'
.\OdfKit.WebFonts.Sidecar.Host.exe `
--service-name OdfKitWebFontsSidecar `
--pipe odfkit-webfonts-production `
--asset-root C:\OdfKitWebFonts\Assets `
--cache-root C:\OdfKitWebFonts\Cache `
--token-file C:\OdfKitWebFonts\Secrets\sidecar.token `
--font-source cns-sung-plus=C:\OdfKitWebFonts\Fonts\TW-Sung-Plus-98_1.ttf `
--font-source cns-kai-plus=C:\OdfKitWebFonts\Fonts\TW-Kai-Plus-98_1.ttf
| 參數 | 預設值/範圍 | 說明 |
|---|---|---|
--pipe |
必填,最長 128 字元 | 不得包含 / 或 \ |
--asset-root |
必填 | 必須與 System.Web 資產根目錄相同 |
--cache-root |
未設定 | 選用的 durable cache |
--token-environment-variable |
ODFKIT_WEBFONT_SIDECAR_TOKEN |
只指定變數名稱,不傳送 secret 值 |
--token-file |
未設定 | 環境變數沒有值時讀取的 ACL 保護 token 檔案 |
--service-name |
OdfKit WebFonts Sidecar |
必須與 SCM 服務名稱一致 |
--font-source |
至少一個,可重複 | 格式為 id=絕對路徑 |
--max-message-bytes |
4 MiB;4 KiB~16 MiB | 單一 pipe frame 上限 |
--max-connections |
8;1~64 | 同時 pipe 連線上限 |
--max-concurrency |
1;1~32 | 同時產字工作上限 |
--queue-capacity |
32;1~4,096 | 有界工作佇列容量 |
--max-unicode-scalars |
65,536;1~65,536 | 單一 Host 工作字元上限;HTTP 層通常應更小 |
--max-asset-bytes |
64 MiB;1 byte~256 MiB | 輸出及快取資產上限 |
--job-timeout-seconds |
180;1~1,800 | 單一工作與連線逾時基準 |
--parent-process-id |
未設定 | 僅供受控自動啟動;父程序結束後停止 |
--allow-cross-user |
關閉 | 允許不同 Windows 使用者連線;仍須另外設定 ACL |
HTTP Handler 的 maxUnicodeScalarCount、maxAssetBytes、request body、並行數及 allowlist
仍是外層安全邊界。不要只放寬 Host 上限。
Windows Server 生命週期
Host 使用 Microsoft Generic Host 與 AddWindowsService,可以同一個 NativeAOT 執行檔接受
SCM 啟動、停止與系統關機通知,也保留主控台及 IIS Express 自動啟動模式。正式部署不需要
WinSW、NSSM 或其它 wrapper。
Release ZIP 內的 Manage-WebFontSidecarService.ps1 會建立虛擬服務帳號、延遲自動啟動、
service SID、ACL、Event Log source 與有退避的復原設定。請在系統管理員 PowerShell 執行:
.\Manage-WebFontSidecarService.ps1 `
-Action Install `
-ServiceName OdfKitWebFontsSidecar `
-DisplayName "OdfKit WebFonts Sidecar" `
-HostExecutablePath C:\OdfKitWebFonts\Host\OdfKit.WebFonts.Sidecar.Host.exe `
-PipeName odfkit-webfonts-production `
-AssetRootPath C:\OdfKitWebFonts\Assets `
-CacheRootPath C:\OdfKitWebFonts\Cache `
-TokenFilePath C:\OdfKitWebFonts\Secrets\sidecar.token `
-FontSource "cns-sung-plus=C:\OdfKitWebFonts\Fonts\TW-Sung-Plus-98_1.ttf" `
-FontSource "cns-kai-plus=C:\OdfKitWebFonts\Fonts\TW-Kai-Plus-98_1.ttf" `
-IisAppPoolName OdfKit `
-StartService
Token 檔案不存在時,腳本會產生 48-byte 隨機值,移除繼承 ACL,只授予 Administrators、
SYSTEM、服務帳號及指定 IIS application pool 讀取權。token 值不會出現在 SCM binPath。
若組織已有 secret store,可自行佈署 token,或繼續使用
ODFKIT_WEBFONT_SIDECAR_TOKEN;環境變數優先於 token 檔案。
查詢、更新及解除安裝:
.\Manage-WebFontSidecarService.ps1 -Action Status -ServiceName OdfKitWebFontsSidecar
.\Manage-WebFontSidecarService.ps1 `
-Action Update `
-ServiceName OdfKitWebFontsSidecar `
-HostExecutablePath C:\OdfKitWebFonts\Host\OdfKit.WebFonts.Sidecar.Host.exe `
-AssetRootPath C:\OdfKitWebFonts\Assets `
-CacheRootPath C:\OdfKitWebFonts\Cache `
-TokenFilePath C:\OdfKitWebFonts\Secrets\sidecar.token `
-FontSource "cns-sung-plus=C:\OdfKitWebFonts\Fonts\TW-Sung-Plus-98_1.ttf" `
-IisAppPoolName OdfKit `
-StartService
.\Manage-WebFontSidecarService.ps1 `
-Action Uninstall `
-ServiceName OdfKitWebFontsSidecar
解除安裝只刪除 SCM 服務及 Event Log source,不刪除 Host、字型、資產、cache 或 token。
服務帳號預設為 NT SERVICE\<ServiceName> 虛擬帳號;多節點部署可明確傳入 gMSA。服務與
IIS application pool 通常是不同身分,所以安裝腳本會啟用跨使用者 pipe,並以 token 與檔案
ACL 保護。這不能取代服務帳號、服務管理權限及組織 secret store。
使用 gMSA 時,先由網域管理員完成帳號建立、主機授權及安裝,再傳入結尾含 $ 的帳號:
.\Manage-WebFontSidecarService.ps1 `
-Action Install `
-ServiceName OdfKitWebFontsSidecar `
-ServiceAccount 'CONTOSO\OdfKitWebFonts$' `
-HostExecutablePath C:\OdfKitWebFonts\Host\OdfKit.WebFonts.Sidecar.Host.exe `
-PipeName odfkit-webfonts-production `
-AssetRootPath C:\OdfKitWebFonts\Assets `
-CacheRootPath C:\OdfKitWebFonts\Cache `
-TokenFilePath C:\OdfKitWebFonts\Secrets\sidecar.token `
-FontSource "cns-sung-plus=C:\OdfKitWebFonts\Fonts\TW-Sung-Plus-98_1.ttf" `
-IisAppPoolName OdfKit `
-StartService
腳本不接受需要在命令列傳遞密碼的一般網域或本機帳號;只接受 Windows 內建帳號、服務虛擬 帳號或 gMSA,避免密碼進入命令歷程、程序參數或部署記錄。
Windows 10/11 與 IIS Express
本機開發可由 System.Web Handler 自動啟動:
{
"sidecar": {
"pipeName": "odfkit-webfonts-development",
"tokenAppSettingName": "OdfKit.WebFonts.SidecarToken",
"autoStart": true,
"hostExecutablePath": "Sidecar/OdfKit.WebFonts.Sidecar.Host.exe",
"startupTimeoutSeconds": 15,
"stopWithApplicationProcess": true
}
}
Handler 會先探測既有 pipe,只有服務不存在時才以隱藏子程序啟動 Host。這個模式只適用單一 使用者的開發機或單 worker 受控測試,不適用 web garden、多站台共用 Host 或正式機關環境。
一般 Windows 10/11 MIS 單機若不使用 IIS Express,也可以安裝前節的原生 Windows Service; 不要讓使用者登入後手動開啟 Host 視窗。
Linux、macOS 與非 System.Web 伺服器
ASP.NET Core 在 Windows、Linux 與 macOS 均應直接註冊
ManagedOpenTypeWebFontSubsetEngine。現代 .NET Runtime 提供 OdfKit WOFF2 路徑所需的
Brotli API,因此不需要用 Windows Sidecar 繞行:
builder.Services.AddOdfWebFontGeneration(
_ => new ManagedOpenTypeWebFontSubsetEngine(engineOptions),
generationOptions =>
{
// 設定 face、Profile、format allowlist 與有界 Worker。
});
部署為 systemd、launchd、Kubernetes 或 Linux container 時,管理的是 ASP.NET Core 網站 程序本身,不是 Sidecar。不得把 Windows Sidecar ZIP 複製到 Linux container,也不要公開 具名 pipe 為 TCP 服務。
健康檢查與故障語意
正式監控至少包含:
- Host 程序存在且沒有快速重啟。
- 受信任後端能以正確 token 連線至 pipe。
- 固定的宋體/楷體小型 canary 能產生 manifest。
- manifest 中的內容定址 WOFF2 可以 GET,SHA-256 與 ETag 正確。
- 瀏覽器 canary 能以像素驗證指定 PUA,不只呼叫
document.fonts.check()。
| 現象 | 意義 | 優先檢查 |
|---|---|---|
| HTTP 204 | 指定來源沒有可產生 glyph | 字型版本、cmap、Profile、PUA 對照 |
| HTTP 401/403 | 動態產字 API 授權失敗 | API key 與 BFF |
| HTTP 429 | HTTP 限流或 Sidecar queue 已滿 | 並行數、queue、Retry-After、負載 |
| HTTP 503 | Sidecar 不可連線、啟動失敗、token/協定錯誤或逾時 | Host、pipe、帳號、ACL、token、版本 |
| 一般字正常但 PUA 是豆腐字 | manifest 沒有該字,或 WebFont 未實際畫出 | 來源 cmap、資產 GET、CSP、像素驗證 |
不要在 Sidecar 失敗時把所有文字強制改成 CNS Plus。系統已有的文字仍應由系統字型顯示; 既有預產生難字資產可繼續使用,尚未產生的難字則應回報可觀察的暫時失敗。
升級與回復
Sidecar client、Host、System.Web Hosting 套件與 pipe 協定視為同一版部署單元:
- 在隔離目錄放置新 Host,核對 SHA-256。
- 使用新 pipe 名稱啟動新 Host,完成
--probe、pipe、產字、資產 GET 與瀏覽器 canary。 - 更新網站設定及套件,讓新 worker 指向新 pipe。
- 觀察 429、503、產字延遲及 cache 命中。
- 確認沒有舊 worker 後停止舊 Host。
- 保留舊 Host、設定與字型版本至回復窗口結束。
目前 Sidecar token 是單值契約,沒有同一 pipe 的雙 token overlap。需要輪替時,使用新 pipe 與新 Host 做藍綠切換,避免把 secret 同時寫入多個不受控位置。