💬

mkdocsでTechサイトを作ろう

2021/07/04に公開2

時系列などに関係なく、調べたことをまとめるためのmkdocs製のページが
概ね自分の納得いくLvまで構築できたので
参考になるかわかりませんが、記事をなくしてシンプルにしたリポジトリを用意しました。
https://github.com/fereria/mkdocs_sample
公開ページは
https://fereria.github.io/mkdocs_sample
こちらになります。

こちらのリポジトリをベースにして、
mkdocs.ymlを自分用に書き換えて、markdownの記事を書けば
私のカスタマイズした環境とほぼ同じmkdocsのページができあがります。

お手軽手順

詳細を書く前に、かんたんな記事更新の段取りなど。

準備

  1. リポジトリをForkするか中身を自分のリポジトリ以下にコピー
  2. mkdocs.ymlのサイト情報などを書き換える
  3. GithubAction用の設定を追加

    GithubのリポジトリのSettingsから

    Secrets を選ぶ。

    右上の、New Repository Secret を選んで

    GithubのMailとアカウント名を入れる。
  4. ローカルでmkdocsのページをプレビューしたい場合はDockerをインストール

以上で、初回の準備は完了です。

記事の更新

  1. docs以下にmdファイルを追加
  2. 追加したらmdファイルをGithubにPush

以上で、サイトの設定は完了です。
Commitするときのコメントが、サイトの更新履歴に表示される
コメントになるので(1行目タイトル、2行目以降が説明)コメントはちゃんと
書くようにします。

ローカル環境でのプレビューをしたい場合
GithubにPushする前に、自分のローカル環境で記事の内容をチェックしたい場合は
Dockerをインストールして、リポジトリのRootフォルダ以下で
以下のコマンドを実行します。

docker-compose -f "docker\docker-compose.yml" up -d --build

リポジトリ以下でコマンドを実行すると、Dockerのコンテナを起動します。

docker exec mkdocs mkdocs serve --dev-addr=0.0.0.0:8888

サーバーを起動して、 http://localhost:8888 にアクセスします。
markdownを編集すると、↑のページも更新されます。

色々構造を変えたり、マクロを更新したりした場合は、サーバーを起動し直さないと
正しく表示されなかったりするので
その時は、サーバーを再起動すればOKです。

カスタマイズしたこと

以下は、自分用に色々カスタマイズした内容です。
(サンプルのリポジトリはすでに設定済)

細かい説明などは別途書いてあることが多いのでそちらを見ていただければ。

mkdocsのビルド~デプロイ用にやったこと

mkdocsは、 mkdocs gh-deploy を実行すると
markdownファイルをビルドして、GithubPagesにデプロイします。
ですが、デフォルトだと手動でやらなければいけないことが多すぎて非常にめんどくさいです。
ので、 mkdocs gh-deploy する前にいくつかの処理を自動で実行するようにしました。

.pagesの自動生成

markdownで記事を書く場合は、docs以下に md ファイルを追加します。
docs直下のフォルダ・markdownファイルは、タブ扱いになり

このような階層になっていると、

このようになります。
サブフォルダを作ってその下にmarkdownを作れば
サイト左のページ一覧は自動で階層化されます。

mkdocsは、フォルダ階層がURLと同じになります。
そのため、フォルダに日本語を使ってしまうと大変なことになります。
あとは、並び順はアルファベット順になるので、順番変更がやりにくいです。

かといって、毎回 .pages を使って名前を指定するのはとてもめんどくさいので
https://github.com/fereria/mkdocs_sample/blob/main/create_mkdocs_pages.py
mkdocsビルド前にこのスクリプトを実行して、
自動で.pagesを作ります。

replace_foldername:
  - JupyterNotebook: のーとぶっく
  - SubDir: サブディレクトリ

上のスクリプトでは、ここで指定した名前でフォルダ名を変換+数字_を削除します。

Tagページの自動生成

階層構造とは別に、Tab指定もやりたくなります。
https://github.com/srymh/MkdocsTagPlugin#egg=mdoctag
Tabはプラグインですでに公開されているので、こちらを使用しました。

しかし、このプラグインを使用した場合、タブのページは手動で作らなければいけません。
それはとてもめんどくさいので、
https://github.com/fereria/mkdocs_sample/blob/main/create_tag_pages.py
docs以下にあるmarkdownをすべてパースして
タグの一覧を取得して、tags以下に必要なmarkdwonを自動生成します。
(パワープレイ)

---
title: SamplePage
tags:
    - sample
description: Tagsのページに表示される説明文書
---

あとは、記事のmarkdownに、tags と、必要なら description を入れれば

https://fereria.github.io/mkdocs_sample/tags/sample/

このようなTagの記事一覧ページができあがります。

Notebook公開

私は、主にPythonのコマンドテスト用にNotebookを使用しています。
そのNotebookのうち、主にUSD関連のコマンドの動作を
記事にする前にテストしたりしたものを
後で見直すために見やすく公開したい...という気持ちがあったので
自動でmarkdownとして公開できるようにしました。

https://github.com/fereria/mkdocs_sample/blob/main/create_jupyter_markdown.py

notebooks以下にあるipynbを、nbconvertを使用してmarkdownに変換します。
変換したものは、docs/60_JupyterNotebook 以下にフォルダ階層を維持した状態で出力します。
実際のmarkdownの名前と表示の名前は、どうしたら簡単にできるか考えた結果
ipynbのファイル名を filename__日本語で名前をつける.ipynb のようにしました。
__がない場合は、そのままの名前になります。

公開する(GithubActions)

以上の処理用にスクリプトを用意しましたが、
毎回これを実行してから gh-deploy しなければ行けないのはとてもめんどくさいです。
さらに、ローカルで実行すると .pagesがリポジトリ以下にできてしまうし
公開した後に元になったmarkdownなどを別途GithubにPushしなければいけないのも
非常にめんどくさいです。

めんどくさいので、 mkdocs gh-deploy はローカルで実行するのではなく
GithubActionsを使用して、GitにPushした後に自動で実行するようにします。

https://github.com/fereria/mkdocs_sample/blob/main/.github/workflows/python-app.yml

GithubActionsの環境はDockerを使用します。
dockerフォルダ以下の docker-compose.yml Dockerfile requirements.txt
をPushしていれば、GithubActions上でも全て自動で構築してくれます。

      - name: nbConvert
        run: docker exec mkdocs python create_jupyter_markdown.py

      - name: Create TagPages
        run: docker exec mkdocs python create_tag_pages.py

      - name: Create Mkdoc .Pages
        run: docker exec mkdocs python create_mkdocs_pages.py

      - name: Mkdocs
        env:
          TZ: Asia/Tokyo
        run: docker exec mkdocs mkdocs gh-deploy

構築ができたら、あとは Notebookページを作り、Tag用のページを作り、.pagesを作り、最後にデプロイします。

初回のみそこそこ時間はかかりますが(3分半)、2回目以降はキャッシュが効くので
1分ほどでビルド・デプロイが完了します。

Slackに通知を出す

Mkdocsのビルドが正しく終わったかどうか分かるようにSlackに通知を出すようにします。

      - name: Send Slack Finish(Success)
        if: ${{ success() }}
        env:
          HOOK_URL: ${{ secrets.SlackURL }}
        run: |
          curl -X POST --data-urlencode "payload={\"channel\": \"#github_actions\", \"username\": \"github_aciton_bot\", \"text\": \"GithubPagesの更新が完了しました!!\"}" ${HOOK_URL}
      - name: Send Slack Finish(Failure)
        if: ${{ failure() }}
        env:
          HOOK_URL: ${{ secrets.SlackURL }}
        run: |
          curl -X POST --data-urlencode "payload={\"channel\": \"#github_actions\", \"username\": \"github_aciton_bot\", \"text\": \"GithubPagesの更新に失敗しました...\"}" ${HOOK_URL}

通知を出すには、 .github/workflows/python-app.yml の最後に上の項目を追加します。

https://api.slack.com/apps?new_app=1
自分のSlackのチャンネルでログインして、

Appを作成します。

Incoming Webhooks を作成して、Activate Incoming WebhooksをONにします。

次にAdd New Webhook to Workspaceをクリックして

投稿先のチャンネルを指定して、許可をするを押します。

許可すると、投稿用のURLが作成できるので、

追加したら、 Settings -> Secrets から New repository secret を選んで、
SLACKURL を追加して、上で作成したWebhookのURLを指定します。

指定すると、ビルドが完了したらSlackの指定チャンネルに結果が投稿されます。

便利なマクロたち

mkdocsには macros-mkdocs という、Pythonで書いたスクリプトの結果を記事に埋め込む事ができるプラグインがあります。
これを使うと、プラグインを作らなくても
いろんなことができるようになります。

このマクロを使用して、あると便利なものを色々追加しました。

更新履歴表示(macros)

docs以下に md ファイルを置いて、記事を書いて、Push することで
記事の更新ができるのは良いのですが
いつ何を更新したかの更新履歴が無いと、色々不便でした。
ので、Githubのコミットログを使用して
自動で履歴ページを作れるようにしました。

ページはこちら。
https://fereria.github.io/mkdocs_sample/update/

例えばこの部分は、Githubの
https://github.com/fereria/mkdocs_sample/commit/8c9b88ca5715df804ced4857a1e818a9b968a7c5
このコミットを表示したものです。

Notebook埋め込み(macros)

Gistなどを埋め込むのでも良いですが、
Notebookで検証した結果をそのままページに埋め込みたいこともあったので
マクロを利用して、プロジェクト以下の指定のipynbの指定セルを

こんな感じで表示できるようにしました。

VSCode環境、その他エディット環境関連

私は記事を書くときにはVSCodeを使用しています。
ので、その環境でより楽に記事を書くための設定やサービスを紹介します。

Addon

使用しているのはほぼメジャーどころですがこんなかんじです。

Preview Enhanced があると、今書いている記事をそのままプレビューできるので
わざわざmkdocsのサーバーを建てなくても気軽に記事を書くことができます。
DrawIOは、記事の中で作図をしたい場合 .drawioファイルをそのまま埋め込める
ようになっているので、そのファイルをVSCodeで編集するために
入れています。
ProjectManagerを入れておけば、指定のリポジトリをかんたんに開けるので
複数のプロジェクトを使っている場合はおすすめです。
最後に、書いた記事をGithubにPushしたりするのに
GitLensを入れておきます。

Snippets

VSCodeでよく使う文字を、スニペットに登録+ショートカットを入れることで
色々便利になります。
https://gist.github.com/fereria/d0e4fe59fba83e9e6a2f485d42e3c2cb
現状の私のスニペットはこんな感じで、登録してあって

    {
        "key": "ctrl+c ctrl+i",
        "command": "editor.action.insertSnippet",
        "args": {
            "langId": "markdown",
            "name": "img"
        }
    },
    {
        "key": "ctrl+m",
        "command": "editor.action.insertSnippet",
        "args": {
            "langId": "markdown",
            "name": "br_line"
        }
    },

さらに、よく使う改行(末尾に を入れる)と画像挿入はショートカットに登録してます。

画像(Gyazo)

最後に画像。
プロジェクト以下に画像を保存するようにしてもよいのですが
GithubPagesには容量制限があるのと、毎回画像のパスを指定するのがめんどくさい
のと、サイトを移行するのがらくになるようにするために
ページに貼り付けている画像はGyazoというサービスを使用しています。
このサービスを使用すると、スクリーンショット、あるいは動画をそのまますぐWebにアップロード
することができる上に、画像のかんたんな編集をすることができます。

なので、これを使用して 範囲選択してスクショ→ショートカットで画像タグを入れる→URLコピペ
をすることで、画像をかんたんに貼り付けることができます。

まとめ

以上が私のmkdocsのサイトカスタマイズと記事の更新環境まとめでした。
ここまで環境を作れば、markdownをPushすれば更新できるだけでサイトの
更新ができるので、非常に楽になりました。
これからTechページを作ろうかな?とか
ナレッジサイト作りたいな?という方がおりましたら
ぜひとも参考にしてください。

GitHubで編集を提案

Discussion

shigezoshigezo

この記事を参考に以前作成した MkDocs の環境をアップデートしました!!
特にタグに関しては一番実現したかったことであり助かりました。
マクロに関しても python を学ぶと色々とやれることがありそうで夢が広がります。

いくつかハマりどころがあったのでフィードバックしておきます。

  1. Docker の Image がビルドできない

私の環境では ビルドできませんでした。
これは元々自分で Dockerfile を作ろうと思っていたのでそれで回避。

  1. create_mkdocs_pages.py が動作しない

おそらく main.py のミスなんだと思います。
こちら から頂きました。

  1. description が設定されていないと Tag ページに表示がされない

description は必須として考えていたと思うのですが、私はすべてに記載するのは面倒なので少し手を入れました。
tech の方でも同様だったので参考までにおすそ分けで PR を投げておきました。

あんどうめぐみ@れみりああんどうめぐみ@れみりあ

参考になったならよかったです!

本体のMkdocsのサイトを掃除しながらサンプル作っていたので、いろいろ不整合おきておりました...
わざわざPRありがとうございました!!