概要
コンテンツをObsidianで作成し、自宅NASおよびすべてのデバイスとSyncthingで同期し、自宅サーバーにNASの対象ディレクトリをnfsでマウントして、それをアプリで包んで配信するシステムを作った。
記事の管理
コンテンツはObsidianでmarkdownを書く。書いたものを自宅NAS(QNAP)とSyncthingで同期してすべてのデバイスで閲覧・編集できるようにする。
├── Obsidian
│ ├── Blog
│ │ ├── diary
│ │ │ ├── ....
│ │ │ └── 2021-10-07_XPS9305-review.md
│ │ ├── game
│ │ │ ├── ....
│ │ │ └── 2021-03-12_osu-on-linux.md
│ │ ├── tips
│ │ │ ├── ....
│ │ │ └── 2023-11-11_plasma-dont-open-menu-by-meta-key.md
│ │ ├── update
│ │ │ ├── ...
│ │ │ └── 2024-05-28_renewal.md
│ │ └── meta.toml
│ ├── static
│ │ ├── favicon.png
│ │ └── images
│ │ └── ...
このような形で記事を書く。Obsidian
フォルダをVaultとしてSyncthingで共有する。Dropboxと違い、スマホとも同期できるのが大きな強みだ。
またこれは別の観点にはなるが、systemd-unitとしても登録できるのでリモートホストのデスクトップがない環境とも簡単にファイルを同期できる。Dropboxだとそのホストでデスクトップを立ち上げるなどしないと行けない。デスクトップの無い環境ともデータを同期する手段としても便利である。
この中にBlog
というディレクトリを作り、これ以下のMarkdownファイルを記事として公開する。他のディレクトリは普通にObsidianとして使う。
記事ファイルの作成ルールとして、必ず一つのなどのサブフォルダを挟んだ上で、<Vault>/Blog/diary/2024-01-01_slug.md
という形式とする。これにマッチしないファイルは無視する。日付を入れることで常にソートされた状態で一覧できるようにする。
Obsidianの編集画面。タイトルやタグをfrontmatterで記載できる。
また、Obsidianでは各テキストをfrontmatterで管理できるので、title
やtags
を記事に応じて設定する。正直これが一番使いたかった機能だ。
もともとブログの記事をfrontmatterで管理することで、DB-lessのCMSとして作っていたが、当時はこれに対応するエディタがなかった。Web管理画面なども作っていたが、個人で使うにはValidationやAPIの整備などの労力は割に合わなかった。
記事をパース・配信するAPIバックエンド
Syncthingしているディレクトリを、LAN経由でサーバーにマウントする。サーバーマシンはRyzen 5700Uのmini PCにProxMoxをいれ、そこにVMを作っている。
$ motunt -t nfs 10.16.2.1:/share/Obsidian /mnt/obsidian
これをDocker volumeでアプリに引き渡す。
アプリ内ではvolumeで渡ってきたディレクトリをwatchdogで監視し変更の都度パースしてメモリ上に読み込む。これをFastAPIを使ってREST APIで配信する。
---
title: 個人ブログリニューアル2024
tags:
- Linux
- Python
---
## 概要
コンテンツをObsidianで作成し、自宅NAS内のQSyncで同期し、NAS内のVMに置いたアプリから元のディレクトリをnfsでマウントし、パースしそれを配信するシステムを作った。
このような構造になっているので、---
に挟まれる部分をyamlでパースし、メタデータとする。
このとき、<Vault>/Blog/<dir>/YYYY-MM-DD_slug-slug.md
という形式にあっているので、 <dir>
をカテゴリとして扱う。このままだとラベルや順序を決められないので、それを補うために Obsidian/Blog/meta.toml
というファイルを作る。ここでは、
[[Category]]
slug = "tips"
label = "Tips"
hidden = false
[[Category]]
slug = "diary"
label = "日記"
hidden = false
みたいにして名前を設定できるようにする。その他ファイルベースだけで決定できない設定等はこのファイルを使う。
画像など静的ファイルの扱い
Obsidianではfuzzyにファイルをリンクさせられるので、この仕組みも利用する。
公開するデータは<Vault>/static
以下に画像は集約し、![](/static/favicon.png)
みたいに参照するようにする。Obsidianは余計な/
が頭にあっても無くても、いい感じに画像を見つけてくれるのが嬉しい。
サーバーではこれは普通にnginxで配信するようにするだけである。
フロントエンド
SvelteKitでバックエンドから取得した記事データをルーティング・HTMLへの変換を行う。 デザインは時間がかかるので、とりあえず記事を書いて読めるところまでやってデプロイした。
Markdownのパースにはmarkdown-itを使っている。TOCやカスタムコンテナなどを柔軟に設定できる。ひとまず簡単にハイライトやGithub Alertsなどを入れてみた。
Note
GitHubスタイルのカスタムアノテーション
app = FastAPI()
@app.get('/')
async def root():
return { 'message': 'Hello.'}
SSGもできるが404なリンクや記事の頻繁な更新を考えたらSSRにして、キャッシュはCDNに任せることにした。
デザインはdaisyUIを使い、markdownのコンテンツにはtailwindlabs/tailwindcss-typographyの.prose
を雑に使った。
案外悪くない。
インフラ
VM on NAS
NASのVMにdockerを入れて、nginx-proxy
nginx-proxy-le-companion
を使ってまとめてSSL化している。つまり自宅サーバーである。
コンテナは開発環境でビルドし、VMのdocker compse pull && docker compose up -d
で更新するだけ。
Docker HubのAutomationが使えなくなったので、イメージをDocker Hubに投げっぱなし、ということができなくなってしまった。なので今はサーバーVMに入って、中からpull
とrestart
をかけている。
これについてはちょっと考えないといけない。
Cloudflare tunnel
VMサーバー内にcloudflared
を導入し、endaaman.com
にトンネルしている。詳細は別で書くかも。
コメント
デザインは適当にしたけど案内悪くない感じにまとまった気がする。 大体隙間時間を使って10日くらいでデプロイまでできたので、コスパはいいと思う。 編集環境もObsidianなので非常に快適である。これでもう少しいろいろ書いていけるようになるはずだ。