Docusaurus でドキュメントサイトを展開してみた

カバー

はじめに

当社の基幹業務システムの設計書や手順書として、静的サイトジェネレーター (Static Site Generator: SSG) を利用してドキュメントサイトを生成しています。現在利用している VuePress では濁点、半濁点を含むリンクが機能しないこともあり、他の SSG に移行を考えていました。デザインを一から作り直すのは時間がかかるため、ドキュメントサイトに特化した SSG を探していたところ Docusaurus を見つけました。今回はこの Docusaurus を利用してドキュメントサイトを生成し、GitLab Pages で公開する手順を紹介します。

静的サイトジェネレーターとは

静的サイトジェネレーターはコンテンツとテンプレートから静的な HTML サイトを生成するツールとなっています。SSG は WordPress のような動的に Web ページを生成するコンテンツ管理システム (Contents Management System: CMS) とは異なり、事前に Web ページを生成しているため、表示が早いことが特徴です。また、コンテンツとテンプレートが分離されているため、別の SSG に移行しやすいこともメリットとしてあげられます。 また、コンテンツとテンプレートをまとめて Git でバージョン管理ができるため、開発コードと同様に修正差分の確認や、バージョン管理も可能で、CI/CD に組み込むことで自動でビルド、デプロイができます。 いくつかの SSG を調査、確認していく中で、VuePress の課題も解決しつつ、デフォルトのテンプレートがドキュメントに適した Docusaurus がよいと思い、選択しました。

Docusaurus とは

Docusaurus は Meta 社が管理する React ベースの SSG です。Markdown や Markdown を拡張した MDX でドキュメントを作成 / 更新し、静的 HTML ファイルを生成、Web サーバでドキュメントサイトを公開することができます。先述のように、デフォルトのテンプレートがドキュメントサイト用のデザインとなっているため、テンプレートの作成に時間をあまりかけずに、コンテンツの更新に時間を割くことができます。 Docusaurus のドキュメントサイト 自体も Docusaurus で作成されているため、どのようなサイトが生成できるか確認することができます。 それでは次章からドキュメントサイトの構築手順を紹介します。

ドキュメントサイトの構築

Docusaurus は Node.js v18 以上を利用するため、Node.js が利用できる環境を用意してください。今回確認した環境は以下となります。(筆者は WSL 内の Docker のコンテナ環境を利用していますが、Linux の環境であれば Docker の環境でなくてもよいです)

## Node.js、npm のバージョン (執筆時点での最新)
$ node --version
v20.11.1
$ npm --version
10.5.0

Docusaurus のサイトをローカル環境で試験的に展開

まず、Docusaurus のテンプレートファイルを取得し、ローカル環境で展開ができるか確認します。npm で配布されている create-docusaurus という、公式の Docusaurus 初期構築用ツールを利用して、ベースとなるファイルを取得します。

## テンプレートファイルの取得
## (公式の classic テンプレートを利用して、sample-site という名前のプロジェクトを作成)
$ npx create-docusaurus@latest sample-site classic
Need to install the following packages:
create-docusaurus@3.1.1
Ok to proceed? (y) y

(省略)

Happy building awesome websites!

## 確認
$ ls ./
sample-site

## 作業ディレクトリーを移動
$ cd ./sample-site/

## ローカル環境で展開
## 展開した環境 (例: WSL の Docker 環境) とアクセス元の環境 (例: ホストの Windows のブラウザー) が異なる端末の場合 --host 0.0.0.0 オプションをつける必要あり
## https://docusaurus.io/docs/cli#docusaurus-start-sitedir
$ npm run start -- --host 0.0.0.0

> sample-site@0.0.0 start
> docusaurus start --host 0.0.0.0

[INFO] Starting the development server...
[SUCCESS] Docusaurus website is running at: http://localhost:3000/

✔ Client
  Compiled successfully in x.xxs

client (webpack 5.90.1) compiled successfully

## ローカルの Windows のブラウザーから http://localhost:3000/ でアクセスする
## ローカルで展開した Docusaurus のサイトが表示される

## (Ctrl + C で終了する)

カスタマイズ

取得したテンプレートファイルを利用して、ドキュメントサイトを作成します。コード管理とサイトの公開を GitLab で行うため、GitLab に新しいプロジェクトを作成します。(GitLab の URL を <GitLab URL> プロジェクト名を test-docs とします)

## 一つ上の階層に戻る
$ cd ../
$ ls ./
sample-site

## GitLab で作成した新規プロジェクト (test-docs) をローカル環境に取得
$ git clone https://<GitLab URL>/test-docs.git

## test-docs が取得できていることを確認
$ ls ./
sample-site  test-docs

次に sample-site から必要なファイルをコピーして、以下となるように test-docs に配置します。

/test-docs/                    : 新しいプロジェクト名
  ├ docs/                     : Markdown ファイル配置先 (中のページ名やディレクトリー名は任意)
  │  └ intro.md -> index.md  : トップページに表示するページ (index.md にリネーム)
  ├ src/                      : ドキュメント以外のファイル配置先
  │  └ css/
  │     └ custom.css        : カスタマイズ CSS ファイル
  ├ static/                   : 静的ディレクトリー
  │  └ img/                  : 画像ファイル配置先
  │     └ favicon.ico       : ファビコン (任意)
  ├ .gitignore                : Git 保管時の除外ファイル
  ├ docsaurus.config.js       : 全体の構成ファイル
  ├ package-lock.json         : (npm パッケージの設定)
  ├ package.json              : (npm パッケージの設定)
  ├ README.md                 : (README ファイル)
  └ sidebars.js               : ドキュメントのサイドバー表示順の指定 (目次)
## サブディレクトリーの作成
$ mkdir -p ./test-docs/{docs,src/css,static/img}

## 上に記載したファイルのコピー
## intro.md のみ index.md にリネームしてコピー
$ cp ./sample-site/docs/intro.md ./test-docs/docs/index.md
$ cp ./sample-site/src/css/custom.css ./test-docs/src/css/
$ cp ./sample-site/static/img/favicon.ico ./test-docs/static/img/
$ cp ./sample-site/{.gitignore,docusaurus.config.js,package-lock.json,package.json,README.md,sidebars.js} ./test-docs/

必要なファイルを test-docs に配置しました。これから作成するドキュメントサイトは、以下のパーツに分類されるため、それぞれカスタマイズします。

全体の設定

まず、Docusaurus 全体の設定から変更します。 参考: Docusaurus - docusaurus.config.js

## 作業ディレクトリーを移動
$ cd ./test-docs/

## 全体の設定を修正
$ vim ./docusaurus.config.js
/** @type {import('@docusaurus/types').Config} */
const config = {
  // タイトル (ブラウザーのタブに表示、等)
  title: 'テストドキュメント',
  // ファビコン、/static/ からのパス
  favicon: 'img/favicon.ico',

  // GitLab Pages の URL
  // (URL が環境により異なるため、この時点で不明の場合は、Pages 展開後に URL を確認してから再修正する)
  url: 'https://<GitLab Pages URL>',
  // ベース URL を指定 (GitLab の場合はプロジェクト名になる)
  baseUrl: '/test-docs/',

  // ドキュメント内のリンク先がない場合の挙動の指定 (docusaurus build 時のみ検出)
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',

  // ローカライズの設定 (日本語のみを指定)
  i18n: {
    defaultLocale: 'ja',
    locales: ['ja'],
  },

  presets: [
    [
      'classic',
      /** @type {import('@docusaurus/preset-classic').Options} */
      ({
        docs: {
          // サイドバー設定のパス (変更不要)
          sidebarPath: './sidebars.js',
          // ブログ機能を使わないため、docs 配下をルートパスとする
          routeBasePath: '/',
        },
        // ドキュメントのみでブログ機能は使わないため、false で無効化しておく
        blog: false,
        // カスタム css ファイルの有効化 (メインカラーの設定や見た目に変更が必要であれば)
        theme: {
          customCss: './src/css/custom.css',
        },
      }),
    ],
  ],
  // 以下、他のパーツの設定のため、次節より説明
};

export default config;

ナビゲーションバーの設定

上部に表示されるナビゲーションバーには、タイトルやロゴ、外部リンク等パーツを配置できます。今回はタイトルとロゴの設定のみ実施します。参考: Docusaurus - Theme configuration - Navbar

## 全体の時と同じ設定ファイルを修正
$ vim ./docusaurus.config.js
/** @type {import('@docusaurus/types').Config} */
const config = {
  // テーマ設定
  themeConfig:
    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
    ({
      // 上部ナビゲーションバーの設定
      navbar: {
        // 左上のタイトル
        title: 'テストドキュメント',
        // ロゴ (試験的にファビコンと同じものを利用 (任意))
        logo: {
          src: 'img/favicon.ico',
        },
        // items は今回設定しないため、コメントアウトまたは削除しておきます
        // items: [
          // (省略)
        // ],
      },

      // 下部フッターの設定
      footer: {
        // (省略)
      },
      // 右部目次の設定
      tableOfContents: {
        // (省略)
      },
      // コードブロックの設定
      prism: {
        // (省略)
      },
    }),
};

export default config;

フッターの設定

下部に表示されるフッターには、コピーライトやロゴ、リンク等パーツを配置できます。今回はコピーライトとテーマカラーの設定を実施します。参考: Docusaurus - Theme configuration - Footer

## 全体の時と同じ設定ファイルを修正
$ vim ./docusaurus.config.js
/** @type {import('@docusaurus/types').Config} */
const config = {
  // テーマ設定
  themeConfig:
    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
    ({
      // 上部ナビゲーションバーの設定
      navbar: {
        // (省略)
      },

      // 下部フッターの設定
      footer: {
        // フッターに表示するコピーライトの内容
        copyright: `© 2024 ALPHA SYSTEMS INC.`,
        // フッターのテーマカラー
        style: 'light',
        // links は今回設定しないため、コメントアウトまたは削除しておきます
        // links: [
          // (省略)
        // ]
      },

      // 右部目次の設定
      tableOfContents: {
        // (省略)
      },
      // コードブロックの設定
      prism: {
        // (省略)
      },
    }),
};

目次の設定

右部に表示される目次欄は、表示する見出しのレベルを設定できます。参考: Docusaurus - Theme configuration - Table of Contents

## 全体の時と同じ設定ファイルを修正
$ vim ./docusaurus.config.js
/** @type {import('@docusaurus/types').Config} */
const config = {
  // テーマ設定
  themeConfig:
    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
    ({
      // 上部ナビゲーションバーの設定
      navbar: {
        // (省略)
      },
      // 下部フッターの設定
      footer: {
        // (省略)
      },

      // 右部目次の設定 (デフォルトで記載はないため、追記します)
      tableOfContents: {
        // 目次に表示される最小見出しレベル (タイトル (見出し 1) を除く 2 がデフォルト)
        minHeadingLevel: 2,
        // 目次に表示される最大見出しレベル (デフォルトは見出し 3、見出し 4 まで表示したいため変更)
        maxHeadingLevel: 4,
      },

      // コードブロックの設定
      prism: {
        // (省略)
      },
    }),
};

コードブロックの設定

コードブロックの設定は、Prism というシンタックスハイライトのプラグインを利用し記載されています。Docusaurus の Prism の初期設定では、利用できるコーディング言語が限られているため、必要に応じてここで追加します。参考: Docusaurus - Theme configuration - CodeBlock

## 全体の時と同じ設定ファイルを修正
$ vim ./docusaurus.config.js
import {themes as prismThemes} from 'prism-react-renderer';

/** @type {import('@docusaurus/types').Config} */
const config = {
  // テーマ設定
  themeConfig:
    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
    ({
      // 上部ナビゲーションバーの設定
      navbar: {
        // (省略)
      },
      // 下部フッターの設定
      footer: {
        // (省略)
      },
      // 右部目次の設定 (デフォルトで記載はないため、追記します)
      tableOfContents: {
        // (省略)
      },

      // コードブロックの設定
      prism: {
        // ライトテーマ時のコードブロックのテーマ
        theme: prismThemes.github,
        // ダークテーマ時のコードブロックのテーマ
        darkTheme: prismThemes.dracula,
        // コードハイライトに追加する言語 (必要に応じて追加する)
        // https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/generate-prism-languages/index.ts#L9-L25
        // 追加できる言語一覧
        // https://prismjs.com/#supported-languages
        additionalLanguages: ['bash', 'yaml'],
      }
    }),
};

ページの作成とサイドバーの設定

次にページの作成とサイドバーを設定します。 トップページは docs/index.md を修正し、以下設定をします。

## トップページの作成
$ vim ./docs/index.md
# トップページ

ここはトップページです。

## 見出し 1

```bash
## ディレクトリーを確認
$ ls ./
sample-site  test-docs

## 作業ディレクトリーを移動
$ cd ./test-docs/

## Docusaurus を展開
$ npm run start -- --host 0.0.0.0
```

::::tip
こんな感じで admonitions も書けます。

:::warning
ネストもできます
:::

::::

### 見出し 1-1

### 見出し 1-2

## 見出し 2

### 見出し 2-1

### 見出し 2-2
## その他ページを作成
$ echo "# テスト 1" > ./docs/test1.md
$ echo "# テスト 2" > ./docs/test2.md
$ mkdir ./docs/subdir/
$ echo "# サブ 1" > ./docs/subdir/sub1.md
$ echo "# サブ 2" > ./docs/subdir/sub2.md
docs 配下の構成

/test-docs/
  └ docs/            : Markdown ファイルの配置先 (中のページ名やディレクトリー名は index.md を除き、任意)
     ├ index.md     : トップページに表示するページ
     ├ test1.md
     ├ test2.md
     └ subdir/      : サブカテゴリー
        ├ sub1.md  : サブカテゴリーのページ
        └ sub2.md

サイドバーの設定は、各ページの Front Matter から自動生成する方法と、自分で目次を管理する方法があり、今回は、後者の自分で目次を管理する方法で実装します。sidebars.js を修正し、以下設定をします。参考: Docusaurus - Docs - Sidebar

## サイドバーの設定
$ vim ./sidebars.js
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
  // 左部サイドバーの設定
  tutorialSidebar: [  // (変数名のため、tutorial という名前が気になる場合は変更も可能)
    {
      // type: doc はドキュメントへのリンク
      type: 'doc',
      // id: は docs/ からの相対パスから .md を取り除いたもの (例: docs/index.md は index)
      id: 'index',
      // label: は表示されるタイトル (省略するとページ内の見出し 1 の名前が表示されるため、今回は省略)
    },
    'test1',  // type: doc の場合は id のみの簡易表記も可能
    'test2',
    {
      // type: category はグループの作成
      type: 'category',
      // label はサイドバーに表示する名前
      label: 'サブカテゴリー',
      // items はカテゴリーに含めるアイテム
      items: [
        'subdir/sub1',
        'subdir/sub2',
      ],
    },
  ],
};

export default sidebars;

実行コマンドの設定

最後に npm scripts の設定をします。Docusaurus の起動オプションに --host 0.0.0.0 を追加し、外部からアクセスをできるよう変更していました。これは、Docker 等リモートからアクセスする場合の環境で起動時のみ必要になるため、新しく npm scripts を追記します。(ついでに npm の設定もいくつか修正します)

## npm 設定の修正
$ vim ./package.json
{
  "name": "test-docs",  // 他のプロジェクトからファイルを移動したため、名前を修正
  "version": "0.1.0",   // このプロジェクトのバージョン (任意)
  "scripts": {
    // Docker でしか起動しない場合は start を直接書き換えてもよい
    "start": "docusaurus start",                    // ローカルのみで確認する場合は今までと同じく npm run start で起動
    "start:vm": "docusaurus start --host 0.0.0.0",  // 別環境からアクセスする場合は npm run start:vm で実行し、外部アクセスを可能にする
    // (以下省略)
  }
}
## node module のインストール (test-docs にファイルを移動してからパッケージのインストールを実行していないため)
$ npm ci

## Docusaurus を展開 (オプションの指定が不要になる)
$ npm run start:vm

> test-docs@0.1.0 start:vm
> docusaurus start --host 0.0.0.0

[INFO] Starting the development server...
[SUCCESS] Docusaurus website is running at: http://localhost:3000/

✔ Client
  Compiled successfully in x.xxs

client (webpack 5.90.1) compiled successfully

## ローカルの Windows のブラウザーから http://localhost:3000/ でアクセスする
## 展開したドキュメントサイトが表示される

## (Ctrl + C で終了する)

以降、新しいページを作成する場合は、

  1. docs 配下に Markdown ファイル (ページ) を追加
  2. sidebars.js を修正してページをサイドバーに表示
  3. npm start でドキュメントサイトをローカルで展開し確認

という流れになります。

GitLab Pages で公開

ローカルで確認ができたため、GitLab Pages で公開します。まず、GitLab Pages で展開するための GitLab CI の設定ファイルを作成します。GitLab Pages は /public/ ディレクトリーのファイルを公開するため、生成ファイルの出力先を /public/ 配下になるよう、あわせて変更します。

## GitLab CI の設定ファイルを作成
$ vim ./.gitlab-ci.yml
# node 20.11.1 の bookworm-slim (Debian) 版を利用
image: node:20.11.1-bookworm-slim
pages:
  script:
    - npm ci  # 必要な node modules をインストール
    - npm run build -- --out-dir ./public/  # 出力先を ./public/ に変更して静的サイトファイルを出力
  artifacts:
    paths:
      - ./public/  # 保管するアーティファクトのディレクトリーを指定
  rules:
    - if: $CI_COMMIT_BRANCH == "main"  # main ブランチのみ CI を実行
## ブランチの確認 (今回は直接 main ブランチにコミット、プッシュします)
$ git branch
* main

## gitlab-ci.yml ファイルを git 管理に追加
$ git add ./.gitlab-ci.yml

## 変更内容をコミット
$ git commit -m "add gitlab-ci.yml"

## リモートにプッシュ
$ git push

main ブランチにプッシュ後、GitLab のパイプラインが動き出し、ビルドしたファイルが GitLab Pages の公開先ディレクトリーに配置されます。ドキュメントサイトは GitLab のプロジェクトの Deploy → Pages の Access pages に表示される URL からアクセスできます。

おわりに

今回は静的サイトジェネレーターの Docusaurus を使ってドキュメントを生成し、GitLab Pages で公開してみました。GitLab を利用するメリットは GitLab Pages で公開できるほか、Docusaurus や SSG の特徴であるコード管理を活かしてマージリクエストでドキュメントの差分をレビューでき、GitLab CI を使うことでドキュメントサイトの公開までを自動で行うことができます。一度、テンプレートになる環境を作成することで、さまざまなドキュメントに利用できます。ぜひ使ってみてはいかかでしょうか。


TOP
アルファロゴ 株式会社アルファシステムズは、ITサービス事業を展開しています。このブログでは、技術的な取り組みを紹介しています。X(旧Twitter)で更新通知をしています。