Docusaurus 現代靜態文件站點
1. 架構全景與目錄結構
一個標準的 Docusaurus 站點包含文件 (docs)、部落格 (blog) 與自訂 React 頁面 (src/pages):
my-website/
├── docs/ <-- Markdown / MDX 技術文件 (側邊欄樹狀結構)
│ ├── intro.md
│ └── tutorial/
├── blog/ <-- 時間軸文章 (Blog 模式,可選關閉)
├── static/ <-- 靜態資源 (圖片、favicon、robots.txt)
├── src/
│ ├── css/custom.css <-- 自訂樣式 (支援覆蓋深色/淺色變數)
│ └── pages/index.js <-- 首頁 (Landing Page)
├── docusaurus.config.js <-- 核心全域設定檔 (站點名稱、路由、外掛)
├── sidebars.js <-- 側邊欄結構定義
└── package.json <-- 依賴管理與啟動腳本
2. 快速初始化與核心指令
2.1 建立專案
建議使用官方推薦的 classic 經典範本:
# 使用 Node.js 18+ 建立專案
npx create-docusaurus@latest my-website classic
cd my-website
2.2 本地開發與編譯
# 啟動本地即時預覽伺服器 (預設 Port: 3000,支援 HMR 熱更新)
npm start
# 編譯靜態產物 (輸出至 build/ 目錄,用於生產環境發布)
npm run build
# 本地預覽編譯後的靜態檔案
npm run serve
3. 核心設定詳解 (docusaurus.config.js)
設定檔負責定義整個站點的基礎 URL、導航列(Navbar)、頁尾(Footer)以及預設外掛:
// @ts-check
const {themes} = require('prism-react-renderer');
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'My HomeLab Wiki',
tagline: '自動化維運與自建服務技術手冊',
favicon: 'img/favicon.ico',
// 生產環境網址設定
url: 'https://wiki.example.com',
baseUrl: '/',
// GitHub Pages 部署時使用 (非 GH Pages 可隨意填寫)
organizationName: 'my-org',
projectName: 'my-wiki',
onBrokenLinks: 'throw', // 偵測到死連結時中斷 build (CI/CD 防呆)
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'zh-Hant', // 預設語言:繁體中文
locales: ['zh-Hant', 'en'],
},
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: './sidebars.js',
routeBasePath: 'docs', // 文件根路徑;若改為 '/' 則整個網站純做文件站
editUrl: undefined, // 關閉「編輯此頁」按鈕 (私有庫適用)
},
blog: false, // 若純作為 Wiki 知識庫,可直接設為 false 關閉部落格
theme: {
customCss: './src/css/custom.css',
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
navbar: {
title: 'HomeLab Wiki',
logo: {
alt: 'Site Logo',
src: 'img/logo.svg',
},
items: [
{
type: 'docSidebar',
sidebarId: 'tutorialSidebar',
position: 'left',
label: '文檔手冊',
},
{
href: 'https://github.com/my-org/my-wiki',
label: 'GitHub',
position: 'right',
},
],
},
colorMode: {
defaultMode: 'dark', // 預設採用暗黑模式
respectPrefersColorScheme: true,
},
prism: {
theme: themes.github,
darkTheme: themes.dracula,
additionalLanguages: ['bash', 'yaml', 'docker', 'nginx', 'json'], // 擴充語法高亮
},
}),
};
module.exports = config;
4. 文件結構與側邊欄管理 (sidebars.js)
側邊欄分為「自動生成 (Auto-generated)」與「手動宣告 (Manual)」兩種模式。對於文件量龐大的 Wiki,強烈建議採用自動生成模式,並由目錄結構與 Markdown Frontmatter 控制排序。
4.1 自動生成側邊欄 (sidebars.js)
// @ts-check
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
tutorialSidebar: [
{
type: 'autogenerated',
dirName: '.', // 自動遞迴 docs/ 目錄下的所有資料夾與檔案
},
],
};
module.exports = sidebars;
4.2 文件 Frontmatter 核心標頭控制
在每篇 Markdown 的最上方加入 YAML 元數據,可精確控制其在側邊欄中的名稱與權重:
---
id: uptime-kuma-guide
title: Uptime Kuma 監控手冊
sidebar_label: Uptime Kuma 監控 # 側邊欄顯示的短名稱
sidebar_position: 1 # 排序權重 (數字越小排越上面)
description: 跨主機容器守護與狀態頁建置
tags:
- Docker
- Monitoring
---
# Uptime Kuma 監控手冊正文...
4.3 目錄分組命名控制 (_category_.json)
若要為 docs/ 內的子資料夾設定側邊欄顯示名稱,在該資料夾內放入 _category_.json:
{
"label": "影音串流套件",
"position": 2,
"link": {
"type": "generated-index",
"description": "涵蓋 Navidrome、Emby 與 Lidarr 的整合指南。"
}
}
5. MDX 擴充語法實戰
Docusaurus 支援在 Markdown 中直接使用特殊提示框(Admonitions)與 React UI 組件:
5.1 提示告警塊 (Admonitions)
:::tip[實用技巧]
使用 NFS 掛載音樂庫時,加上 `_netdev` 參數可避免開機卡死。
:::
:::warning[注意事項]
請勿將 SQLite 資料庫放在 CIFS/SMB 網路硬碟上。
:::
:::danger[嚴重警告]
執行資料清除前,請務必先執行快照備份!
:::
5.2 程式碼區塊 Tab 切換 (Code Tabs)
適合展示不同作業系統或不同工具的對照指令:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="photon" label="Photon OS" default>
```bash
tdnf -y install cifs-utils
```
</TabItem>
<TabItem value="debian" label="Debian / Ubuntu">
```bash
apt-get update && apt-get install -y cifs-utils
```
</TabItem>
</Tabs>
6. 本地全文搜尋引擎整合 (免外部依賴)
Docusaurus 官方預設推薦 Algolia,但若建置的是內部私有知識庫,外部爬蟲無法存取。社群最成熟的離線解決方案是 @easyops-cn/docusaurus-search-local。
步驟 1:安裝離線搜尋外掛
npm install @easyops-cn/docusaurus-search-local
步驟 2:在 docusaurus.config.js 註冊外掛
// 在 config 物件中加入 themes 區塊:
themes: [
[
require.resolve('@easyops-cn/docusaurus-search-local'),
/** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */
({
hashed: true,
language: ['zh', 'en'], // 支援中英文分詞搜尋
indexDocs: true,
indexBlog: false,
docsRouteBasePath: '/docs',
}),
],
],
設定完成後,執行 npm run build 時會自動在本地建立索引檔案,網站頂部將直接出現離線搜尋欄。
7. 生產環境部署方案
Docusaurus 編譯後純為靜態檔案(位於 build/ 目錄),常見的自建託管模式為 Docker Nginx 容器 或搭配 Traefik v3。
7.1 Dockerfile 多階段建置 (Multi-stage Build)
建立 Dockerfile,利用 Node 容器編譯,並由 Alpine Nginx 託管,體積僅約 20MB:
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Serve
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
配套的 nginx.conf:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# 啟用靜態資源 Gzip 壓縮
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
}
7.2 Docker Compose + Traefik v3 整合範本
services:
wiki:
build: .
container_name: docusaurus-wiki
restart: unless-stopped
networks:
- proxy-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wiki.rule=Host(`wiki.example.com`)"
- "traefik.http.routers.wiki.entrypoints=websecure"
- "traefik.http.routers.wiki.tls=true"
- "traefik.http.routers.wiki.tls.certresolver=myresolver"
- "traefik.http.services.wiki.loadbalancer.server.port=80"
networks:
proxy-network:
external: true
8. 常見疑難排解 (Troubleshooting)
| 異常現象 | 根本原因 | 排除處置 |
|---|---|---|
npm run build 拋出 Docusaurus found broken links! | 內文中的跨頁超連結路徑錯誤,或引用的錨點(Anchor)不存在。 | 依據日誌印出的檔案行號修正路徑,或暫時在 docusaurus.config.js 將 onBrokenLinks 改為 'warn'。 |
| Markdown 包含特殊字元導致編譯失敗 | MDX 解析器將 < 或 { 誤判為 JSX 標籤或程式碼變數。 | 使用反引號包裹行內代碼(如 `<Your_IP>`),或使用 HTML 實體編碼替換。 |
| 中文字串搜尋不到 | 搜尋外掛未包含中文分詞庫。 | 確認 @easyops-cn/docusaurus-search-local 設定中包含 language: ["zh", "en"]。 |
| 深色模式下自訂樣式跑版 | CSS 直接寫死色碼,未覆蓋全域 CSS 變數。 | 編輯 src/css/custom.css,在 [data-theme='dark'] 選擇器內覆蓋 --ifm-color-primary 等主題變數。 |