前書き#
「2024 年、私のブログはどのように変わったか」という記事で、私は Serverless プラットフォームといくつかのオープンソースプロジェクトを使用して構築したブログシステムについて紹介し、このシリーズのチュートリアルを開始して、構築とデプロイの全過程を記録しています。
この記事はコメントシステムの解決策についてです。
コメントシステムの進化#
私は、コメントは読者と著者の間のコミュニケーションの一部であるだけでなく、その内容自体も記事の一部であると常に感じています。時には、コメントの考察や意見の議論が記事自体よりも価値があることが多いので、コメントシステムには常に重視しており、いくつかの第三者のホスティングサービスを信頼したくありません。検閲がないことを望み、スタイルはできるだけシンプルで、自分のブログのスタイルに合致することを望んでいます。
ブログの発展過程で、コメントシステムの解決策も何度か進化してきました。コメントシステムの種類と選択について、私が好きな開発者 reorx が「ブログコメントシステムの変更」で詳しく紹介しているので、私はそれ以上の説明はしません。この記事は、個人的な体験と詳細な構築プロセスに重点を置いています。
Disqus#
私が最初に使用したブログコメントシステムは、悪名高い Disqus で、重くてユーザーのプライバシーを収集する有名なコメントシステムです。読み込みが遅く、無料版にはしばしば広告が付いてくるため、耐え難いものでした。また、当時はほとんどコメントがなかったため、移行の負担もなく、しばらく使用した後に直接廃止しました。
Utterances#
それで、GitHub の issues に基づくコメントシステムである Utterances に切り替えました。これは各記事に対して issue を生成し、ユーザーは GitHub にログインして issue にコメントを投稿します。この方法の利点は、管理のために utterances-bot を認可するだけで済み、自分でサービスをデプロイしたり、データベースを維持したりする必要がないことです。しかし、しばらく使用した後、いくつかの欠点を感じました:
- GitHub API に基づいてコメント管理を行うため、後にインターフェースが変更されたり、このような issue を利用したコメント方式に制限がかかると、不安定になる可能性があります。
- 読者は GitHub にログインする必要があり、非技術者やモバイル端末で読む読者には非常に不便です。
- GitHub リポジトリの Issues 記録が汚染され、他のシステムへの移行も不便です。
Cusdis + Supabase + Vercel#
Cusdis はRandyが作成したデータプライバシーに重点を置いたオープンソースのコメントシステムで、非常に軽量です。gzipped 後は約 5kb しかありません。その名前からも、耐え難い Disqus の代替版を自分で作ったことがわかります。そのため、Disqus の過去のデータのインポートもサポートしています。
2021 年の中頃から使用を開始し、現在でちょうど 3 年が経ちました。最初の頃は Heroku や Railway が相次いで料金を請求したため、デプロイプラットフォームに少し手間取ったことを除けば、ずっと安定して運用されています。ただし、使用中にいくつかの問題に直面しました:
- おそらく WeChat 内蔵ブラウザがいくつかの魔改造を行ったため、WeChat のチャット / 対話からブログを開くとコメントコンポーネントが表示されません。
- メールアドレスを入力できますが、コメント返信の購読はサポートされていません。
- 管理者が手動でコメントを承認する必要がありますが、コメント通知の TG Bot が時々無効になり、コメントを見逃すことがあります。
しかし、全体的には今日に至るまで非常に推奨できる解決策であり、軽量で自分でデプロイが簡単で、スタイルもシンプルで美しいです。構築チュートリアルは「軽量オープンソース無料ブログコメントシステムの解決策(Cusdis + Railway)」を参照してください。
Railway が昨年 8 月から Free Plan を廃止したため、完全に無料で使用したい場合は、Vercel/Netlify/Zeabur を使用してメインプロジェクトを無料でデプロイし、Supabaseに無料の PostgreSQL データベースインスタンスをデプロイし、リンクを環境変数として Cusdis サービスに渡すだけで済みます。他のプロセスはほぼ同じです。
また、コア機能が長い間更新されていないため、他の成熟したコメントシステムと比べてやや簡素に見えますが、私は「十分に使える」という原則を貫いているため、移行や更新の考えはずっとありませんでした。唯一、前端を学んでいた時期に Cusdis V2 バージョンの開発に参加しましたが、長くは続きませんでした。
4 月に Vercel のデプロイがアップグレード中に失敗し、数週間コメントを受け取れなかったため、確かにいくつかの機能要件が出てきたので、移行を決意し、新しい解決策を探求しました。
Remark42 + fly.io#
調査の結果、reorxが「ブログコメントシステムの変更」で最終的に選定したRemark42を選びました。
単純に設定オプションだけを見ても、Cusdis に比べてかなり豊富です。現在、一般的なソーシャルアカウントのログイン(GitHub、Twitter、Telegram、メール)を設定し、匿名コメントを許可し、メールの返信通知をサポートし、TG ボット通知も設定しました。また、fly.ioにデプロイされており、Go の単一バイナリ + データベースの単一ファイルという非常に快適な解決策です。Remark42 の詳細な紹介と利点については、上記の記事を参照してください。
Remark42 は移行ソリューションをいくつか提供していますが、私が使用している Cusdis をサポートしていません。しかし、幸いにもそれは Golang で書かれているため、私は移行ロジックを追加し、これまでに蓄積された 438 件のコメントデータをシームレスに移行しました。
Remark42 + fly.io デプロイガイド#
Remark42 + fly.io の解決策は、単一のサービスに関わるもので、データベースは boltdb をボリュームにマウントしていますが、すべての操作は fly.io の Free Plan 内で行われます。
以下では、ゼロからこの無料コメントシステムを構築する方法を紹介します。
Remark42 自体のコードはオープンソースであり、GitHub - umputun/remark42で入手可能で、公式にメンテナンスされたイメージを提供しており、ドキュメントは明確で読みやすく、実際のニーズに応じて設定できます。
flyctl
コマンドラインツールのインストール#
fly.ioは、私が以前使用していた Railway や Zeabur などと大きく異なる点は、ほとんどの操作がコマンドラインと設定ファイルに基づいて行われることであり、ウェブ管理パネルで操作するのではありません。したがって、まずはドキュメントに従ってflyctl
コマンドラインツールをインストールする必要があります。
macOS を例に、私はbrew
を使用してインストールしました:
brew install flyctl
認証ログイン#
ターミナルツールを開き、以下のコマンドを使用して認証ログインを行います:
flyctl auth login
Web 上でアカウントにログインするか、新しいアカウントを作成し、完了後にContinue as xxx
をクリックすると、flyctl
コマンドラインの認証ログインが完了します。
アプリケーションディレクトリの作成#
私は通常、公式のテンプレートを使用せずに手動で設定管理を行うため、remark42-on-fly
のようなディレクトリを新しく作成し、すべての設定ファイル、環境変数などをこのパスに配置します。
そして、VS Code を使用して編集します(vim や他のエディタ / IDE を使用することもできます)。
設定ファイル#
fly.io は主に.toml
形式の設定ファイルを使用してサービス管理を行います。以下は私がデプロイしたサービスに対応する設定ファイルです:
app = 'yu-remark42-01'
primary_region = 'hkg'
[build]
image = 'umputun/remark42:latest'
[[mounts]]
source = 'remark42_data_01'
destination = '/srv/var'
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = false
auto_start_machines = true
min_machines_running = 1
processes = ['app']
[env]
REMARK_URL = 'https://yu-remark42-01.fly.dev/'
SECRET = 'remark42-secret'
SITE= 'remark42-demo'
ADMIN_SHARED_ID= ''
[[vm]]
cpu_kind = 'shared'
cpus = 1
memory_mb = 256
これは詳細な設定説明です:
app
:アプリケーション名、ここではyu-remark42-01
を使用しています。実際の状況に応じて変更できます。primary_region
:デプロイ地域、こちらのリストから自分がデプロイしたい地域を選択できます。私は香港を選びました。[build]
:この部分は主にサービスイメージに関する設定です。image
:サービスイメージ、公式提供のumputun/remark42:latest
を使用しています。必要に応じてタグバージョンを指定できます。
[[mounts]]
:この部分はデータボリュームのマウント設定です。Remark42 は boltdb データベースを使用しているため、永続的なストレージが必要です。source
:データボリューム名、ここではremark42_data_01
を使用しています。destination
:マウントディレクトリ、ここでは/srv/var
にマウントしています。このディレクトリは Remark42 のデフォルトのデータストレージディレクトリです。
[http_service]
:この部分は主にサービスに関する設定です。internal_port
:サービス内部ポート、8080 を使用しています。force_https
:HTTPS を強制的に使用します。auto_stop_machines
:false
に設定します。auto_start_machines
:true
に設定し、自動起動します。min_machines_running
:最小稼働マシン数、1 に設定します。processes
:サービスプロセス、app
に設定します。
[env]
:環境変数の設定です。REMARK_URL
:Remark42 サービスの URL、ここではhttps://yu-remark42-demo.fly.dev/
を使用しています。これは fly.io が自動生成したもので、後にカスタムドメインができた場合は変更する必要があります。SITE
:サイト名、ここではremark42-demo
を使用しています。SECRET
:カスタム JWT トークン、ここではremark42-secret
を使用しています。ADMIN_SHARED_ID
:管理者 ID、ここでは空文字列を使用しており、管理者がいない状態です。後で追加できます。
[[vm]]
:この部分は主にマシンに関する設定です。cpu_kind
:CPU タイプ、shared
に設定します。cpus
:CPU 数、1 に設定します。memory_mb
:メモリ、256MB に設定します。
サービスの作成#
設定が完了し、確認したら、以下のコマンドを実行してサービスを作成します:
flyctl launch
環境変数の設定#
現在はサービスをデプロイしただけで、環境変数が設定されていないため、サービスの起動に問題があります。次に、環境変数を設定し、prod.env
ファイルに保存します:
AUTH_GITHUB_CID=<your_github_cid>
AUTH_GITHUB_CSEC=<your_github_csec>
AUTH_TWITTER_CID=<your_twitter_cid>
AUTH_TWITTER_CSEC=<your_twitter_csec>
AUTH_ANON=true
AUTH_TELEGRAM=true
TELEGRAM_TOKEN=<your_telegram_token>
NOTIFY_ADMINS=telegram
NOTIFY_TELEGRAM_CHAN=<your_telegram_group>
NOTIFY_USERS=email
AUTH_EMAIL_ENABLE=true
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_TLS=true
[email protected]
SMTP_PASSWORD=<your_password>
[email protected]
[email protected]
環境変数の部分は比較的複雑で、具体的なパラメータについてはドキュメントを参照してください。
ログイン / 認証設定#
私は匿名コメント、GitHub、Twitter、Telegram のいくつかの方法を設定しました。他のログイン方法を設定することもできます。
- 匿名ログイン
AUTH_ANON
:匿名コメントを許可するかどうか、私は許可することにしました。つまり、ユーザーはログインせずにコメントできます。
- GitHub ログイン
AUTH_GITHUB_CID
とAUTH_GITHUB_CSEC
:GitHub OAuth アプリのクライアント ID とクライアントシークレット。
- Twitter ログイン
AUTH_TWITTER_CID
とAUTH_TWITTER_CSEC
:Twitter OAuth アプリのクライアント ID とクライアントシークレット。
- Telegram ログイン
AUTH_TELEGRAM
:Telegram ログインを許可するかどうか。TELEGRAM_TOKEN
:Telegram ボットトークン、botfather
を通じて作成。
- メールログイン
AUTH_EMAIL_ENABLE
:メールログインを許可するかどうか。AUTH_EMAIL_FROM
:メールログインの送信メールアドレス。
通知設定#
- Telegram で管理者に通知、この部分のドキュメントを参照して Telegram ボットの作成と設定を行います。
NOTIFY_ADMINS
:管理者に通知する方法、telegram を選択。NOTIFY_TELEGRAM_CHAN
:Telegram で管理者に通知する場合、対応するチャンネル ID を設定する必要があります。t.me/xxx
の後の ID 部分を記入するだけで済みます。例:pseudoyuchat
。
- Email でユーザーに通知、この部分のドキュメントを参照してメール SMTP などの設定を行います。
NOTIFY_USERS
:ユーザーに通知する方法、私は email を選択しました。つまり、メール通知を行うため、下記の SMTP を設定する必要があります。NOTIFY_EMAIL_FROM
:メール通知の送信元アドレス。
メール SMTP 設定#
上記のメールログインとメール通知は SMTP サーバーの設定が必要です。この部分も自分のメールサービスプロバイダーに基づいてドキュメントを参照して設定できます。
SMTP_HOST
:SMTP サーバーのアドレス。SMTP_PORT
:SMTP サーバーのポート。SMTP_TLS
:TLS を有効にするかどうか。SMTP_USERNAME
:SMTP ユーザー名。SMTP_PASSWORD
:SMTP パスワード。
環境変数をサービスにインポート#
上記の説明に従って環境変数の設定が完了したら、設定ファイルと環境変数ファイルがあるディレクトリで以下のコマンドを実行して環境変数をインポートします:
fly secrets import < prod.env
実行が完了したら、fly.io コンソールでサービスの状態を確認します。Deployed
の状態であれば、デプロイが成功したことを示します。
カスタムドメインの設定(オプション)#
fly.io が提供するデフォルトのドメインを使用したくない場合は、カスタムドメインを設定できます。
fly.io コンソールに入り、先ほどデプロイしたyu-remark42-01
サービスを選択し、左側のCertificates
オプションをクリックして、右上のAdd a Certificate
をクリックし、指示に従ってカスタムドメインを追加します。
Create Certificate
をクリックすると、必要な DNS レコードを追加するためのページが表示されます。指示に従って追加してください。
例えば、私のドメインは Cloudflare にホスティングされており、指示に従って 2 つの DNS レコードを追加しました。ページに戻った後、Check again
をクリックするか、しばらく待ってからリフレッシュすると、すべて緑色で表示されれば設定成功です。
この時点で、fly.toml
内のREMARK_URL
をカスタムドメインに変更し、以下のコマンドを実行してサービスを再デプロイします。以降、設定ファイルに対する変更はこのコマンドを使用して更新できます:
fly deploy
ブログに Remark42 を設定#
上記で Remark42 サービスのデプロイが完了しましたので、次は私の使用している Hugo ブログに Remark42 コメントコンポーネントを追加する必要があります。
Hugo テーマの Comments コンポーネントを定義#
私は Hugo ブログのlayouts/partials
ディレクトリにcomments.html
という新しいファイルを作成し、Remark42 コメントコンポーネントを定義しました:
<div class="comments">
<div class="title">
<span>コメント</span>
<span class="counter"><span class="remark42__counter" data-url="{{ .Permalink }}"></span></span>
</div>
<div id="remark42">
</div>
</div>
<script>
var remark_config = {
host: 'https://comments.pseudoyu.com',
site_id: 'pseudoyu.com',
components: ['embed', 'counter'],
max_shown_comments: 20,
simple_view: true,
theme: 'light',
}
</script>
<script>
(function () {
// remark42を初期化またはリセット
const remark42 = window.REMARK42
if (remark42) {
remark42.destroy()
remark42.createInstance(remark_config)
} else {
for (const component of remark_config.components) {
var d = document, s = d.createElement('script');
s.src = `${remark_config.host}/web/${component}.mjs`;
s.type = 'module';
s.defer = true;
// InstantClickによる<script>の重複読み込みを防ぐ
s.setAttribute('data-no-instant', '')
d.head.appendChild(s);
}
}
})();
</script>
remark_config
内のhost
とsite_id
は実際の設定に応じて変更する必要があります。他の部分の設定はそのままでも、またはドキュメントに従って調整できます。
comments
コンポーネントの設定が完了したら、layouts/posts/single.html
の文章の底部に以下を追加します:
{{ partial "comments.html" . }}
大体の位置は図のようになります。他のテーマやブログシステムを使用している場合は、自分の文章に対応するテンプレートファイルを見つけて修正する必要があります。
ローカルプレビュー / ウェブサイトのデプロイ#
この時点で、ローカルでプレビューまたはウェブサイトをデプロイしてコメントシステムが正常に表示されるか確認できます。これでサービスのデプロイが完了しました。
ユーザー ID を取得し、管理者を設定#
認証が完了し、コメントをテストした後、Remark42 でアバターをクリックして管理ページを開き、ダブルクリックしてCMD/Ctrl+C
を押すと、github_
や他のプラットフォームで始まるユーザー ID を取得できます。これをADMIN_SHARED_ID
に設定できます(fly.toml
設定ファイルを変更し、fly deploy
を実行して再デプロイすれば、管理者になり、他のユーザーのコメントを削除するなどの管理操作が可能になります)。
その他#
私は以前の Cusdis のコメントデータを一定の条件に従って json 形式でエクスポートし、go プログラムを通じてフォーマット変換と移行を行ったため、以前のすべてのコメントを保持しました。
Cusdis 自体はエクスポート機能を提供しておらず、移行のニーズが非常にニッチであるため、上流にコードを直接貢献することはありませんでした。また、完璧なスクリプトを書くこともありませんでした。同様のニーズがある方は、この PR を参考にして処理を行うことができます —— 「feat: add cusdis to remark42 migrator support by pseudoyu · Pull Request #1 · pseudoyu/remark42」。
まとめ#
以上が私のブログコメントシステムの構築プロセスです。コメントシステムの構築と設定は比較的複雑であり、この記事の設定方法は時間とともに古くなる可能性があります。問題が発生した場合は、公式ドキュメントを参照してください。
これは私のブログ構築デプロイシリーズチュートリアルの一部であり、データ統計システムやブログ内検索などの構築に興味がある方は、引き続きご注目ください。皆さんの参考になれば幸いです。