日が経過しています。情報の鮮度にご注意ください
以前、ある学生からブログの仕組みについて聞かれた時、私は「Github PagesのJekyllを使い、ビルド後のHTMLをホスティングしている」と答えました。しかし、この説明は少し大雑把で、実際には様々なサービスを統合する作業が含まれています。そこで、ここでは詳細を説明するとともに、コードも公開します。
全体の流れ
Markdownファイルの全体的なフローチャート:

ブログ画像の全体的なフローチャート:

画像処理に関する補足説明:
-
ローカル開発時、画像リポジトリはブログリポジトリのサブモジュールです。ブログ記事に新しい画像を追加した場合、まず画像を画像リポジトリにプッシュし、リポジトリのアクションがTencent Cloud COSに同期するのを待ってからブログコードをプッシュする必要があります。そうしないと画像参照リンクが見つかりません。
-
ブログ記事を書く際、画像を参照する時は相対パスを使用します。Jekyllには3つの設定ファイルがあり、それぞれローカル開発用、.comサイト参照用、.cnサイト参照用に使われます。3つのymlファイルの唯一の違いは静的リソースの参照方法です:
-
ローカル設定ファイル:static_url: /static
-
.com設定ファイル:static_url: https://static.xheldon.com
-
.cn設定ファイル:static_url: https://static.xheldon.cn
-
画像リソースを参照する必要がある場合、markdown内での記述方法は:\!\[\]\(https://static.xheldon.cn/img/in-post/qing-zheng-lu-yu/IMG_3789.png) となります(JekyllはまずMarkdownファイルを処理し、中のLiquid変数を置換した後、HTMLにビルドします)。
きっかけ
以前、Notionをデータソースとして使用し、ブログを更新したいと考えていました。そのためにはサーバーが必要だったので、Tencent Cloudの軽量サーバーをNotionデータ取得用のサーバーとして購入しました。効果はこちらで確認できます:
さらに、もう一つの理由は、ブログを書く際には必ず画像を掲載する必要があることです。最初はjsDelivrのGithubリポジトリ加速サービスを使用していました:
jsDelivr - オープンソース向けの無料で高速かつ信頼性の高いCDN
しかし、困ったことにjsDelivrの加速サービスには各リポジトリに対して50MBの制限があり、公共のjs/cssなどを加速するには適していますが、画像には明らかに向いていません。
このため、私がサーバーを所有している状況では、答えは明白でした:もう一つドメインを購入し、CDN加速サービスを有効化すればよいのです。
そしてさらに考えを進めると、すでにドメインを購入しているし、私のブログにアクセスするユーザーのほとんどが中国大陸のIPであるなら、なぜ中国版のブログも作らないのでしょうか?ドメイン名はhttps://xheldon.cnにしましょう。
というわけで、すぐに行動に移しました。以下がその過程のまとめです。
サーバーとドメイン
購入
サーバーはTencent Cloudの軽量サーバーを購入しました。4コア8GBメモリ、4M帯域幅で、大割引(キャンペーンで0.数割の価格)の時に購入したので非常に安く済みました。
ドメインを購入した後、中国大陸では当然ながらICP登録が必要です。登録がないとドメインの解析が許可されず、そのドメインにアクセスすると「このドメインは登録されておらず、解析が停止されています」などのメッセージが表示されます。幸いTencent Cloudは無料でICP登録代行サービスを提供しており、現在はプロセスも大幅に簡素化されています。Tencent Cloudの登録申請フォームに、自宅の住所、連絡先、ウェブサイトの用途、申請理由などの情報を記入するだけで済みます。もし申請理由欄に「早く登録しろ」などと書いてしまうと、通信管理局(ドメイン審査を行う政府機関)に直接提出された時点で却下されるでしょう。記入内容に問題がある場合、Tencent Cloudの担当者から連絡があり、修正を確認した上で提出されます。
設定
設定には以下の手順がありますが、詳細は割愛します:
-
無料のHTTPS証明書を申請し、HTTPSを有効化する。
-
CDN加速ドメインを設定する。
-
画像保存用にCOSを購入する(新規ユーザーには無料で提供されます)。
-
ExpressのNodeサービスを起動し、Nginxリバースプロキシを通じて外部に80ポートを公開します。サーバーはGiteeから静的HTMLリソースをプルし、いくつかのAPIリクエストに応答します。なぜ直接Githubからプルせず、わざわざGiteeから行うのかというと、これらのAPIリクエストには以下のようなものがあるからです:
-
GiteeからのWebhooksに応答し、サーバーに最新のHTMLファイルをGiteeからプルするよう通知します。
-
ブログからのNotionクエリリクエストに応答し、サーバー側でNotionのサーバーにリクエストを送信してクエリを実行します。
いくつか説明が必要な点があります:
-
軽量サーバーとしては、Node + NginxのDockerイメージを選択しました。Javaベースのものやカスタムイメージを選んでも構いません。
-
軽量サーバーにデフォルトでインストールされているNodeとNginxは、lighthouseユーザー権限でインストールされています。パッケージインストール時に権限不足のエラーが頻発したため、手間を省くためにデフォルトのNginxとNodeを削除し、rootユーザーで再インストールしました。
-
サーバーにFTPでファイルをアップロードする必要がある場合があります。前述のSSL証明書などです。FTP関連の設定が必要で、Tencent Cloudには関連ドキュメントがありますので、検索すれば見つかります。ここでは割愛します。
-
登録には少なくとも1週間以上かかります。私の場合は2週間ほど待ちました。
リポジトリ設定
Github Actionsで静的ファイルをビルドする設定
ブログのソースコードファイルを公開したくないこと、またGithub PagesがサポートするJekyllプラグインには制限があり(例えばホームページだけでなくカテゴリページでもページネーションを行いたい場合など)、私の要件を満たせないため、ソースコードをHTMLにビルドすることにしました。
また、Github Pagesの無料版の制限により、プライベートリポジトリでGithub Pagesを有効にすることができないため、別のリポジトリを公開設定にし、ソースコードリポジトリはプライベートに設定しています。コードをプライベートリポジトリにプッシュすると、Github Actionでビルドされた後、その公開リポジトリにプッシュされます。
Github PagesとGithub Actionの使用については、以前私が書いた以下の記事を参照してください:
プライベートリポジトリで無料公開するGitHub Pages - Xheldon Blog
ただし、国内ドメインを追加で取得したため、設定ファイルにもいくつか変更がありました。以下が新しい設定ファイルです:
1 | |
別のリポジトリを設定し、Github Pagesを有効化
この手順については特に説明する必要はありません。Githubリポジトリの設定を有効にするだけです。
Conding Webhooksの設定
Giteeのリポジトリ管理-Webhooksで、あなたのWebHookアドレスを設定します。私の場合はhttps://www.xheldon.cn/hooks_cn_push。です。
サーバー側のWebhooks応答設定
サーバー側ではExpressサービスを起動しています。コードは以下の通りです:
1 | |
画像リポジトリのAction設定
画像を画像リポジトリx_blog-staticにアップロードすると、Github Actionがトリガーされ、Tencent Cloud COSに増分更新されます。コードは以下の通りです:
1 | |
もちろん、COSなどの秘密鍵といった環境変数があります。これらは前述のGithub Actionの記事を参照し、自身のリポジトリで設定してください。
上記ではjsファイルを実行しており、コミットの状況を取得し、今回のコミットで何が追加、削除、変更、リネームされたかを確認した後、一括でアップロードします。リポジトリは公開されており、こちらにあります。
今後の計画
この記事で述べられているように、本記事もCraftのプラグインを使ってGithubリポジトリに同期されています。その利点については既に詳しく説明されているので、ここでは繰り返しません。現在唯一の問題は、Craftから挿入された画像の扱いです。公式ではCORS制限のないfetch API(Macのみ利用可能)が公開されていますが、Craftにアップロードされた画像をTencent Cloudにエレガントに同期する方法についてはまだ検討中です。
現在の計画では、Githubに画像を保存する手順を廃止し、Craft内の画像をextension経由で直接Tencent Cloud COSに送信する予定です。
人生の重要な選択に直面したとき、最善の方法を誰かが教えてくれて、貴重な時間を無駄にせずに済めばと、私はよく願っています。だからこそ、自分の経験を踏まえて頻繁にブログを書き、広大なインターネットのこの小さな片隅に、私にとって一度きりの人生経験を記録し、助けを求める人々の力になれればと思っています。