誰も語らないブックマーク問題
「あとで読む」というフォルダに847件のリンクが入っている。いつの間にか「あとで読む」は「永遠に読まない」と同義になってしまった。心当たりがあるだろうか?
本当の問題はリンクを保存することではなく、後から見つけ出すことだ。PocketもブラウザのブックマークもこのUXを解決できていない。Kubernetesのネットワークに関する記事を保存したのは覚えているが、8ヶ月前に「infra」という曖昧なタグで保存したきり。探し出すのはほぼ不可能だ。
Pocketが無料プランを廃止し、Mozillaによる買収で先行きが不透明になったのを機に、保存問題だけでなく検索・取り出し問題を本当に解決できるセルフホスト型の代替を探した。そこで見つけたのがHoarderだ。AIサマリーと全文検索を内蔵したオープンソースのブックマークマネージャーで、Dockerでクリーンに動作する。
3ヶ月間毎日使い続けた結果、あのフォルダは今では本当に役に立っている。セットアップ方法を紹介しよう。
Hoarderが実際にできること
Hoarderは自ら「AIファースト」と称しており、機能一覧はその名に恥じない:
- 自動コンテンツスクレイピング — ブックマーク時に各ページのスナップショットを保存するため、リンク切れになってもコンテンツは失われない
- AIによる自動要約 — OpenAIまたはローカルのOllamaモデルを使って各保存ページを要約する
- 全文検索 — タイトルやURLだけでなく、スクレイピングしたコンテンツの中身まで検索できる
- 自動タグ付け — AIがコンテンツに基づいてタグを提案する
- ブラウザ拡張機能 — ChromeとFirefoxの拡張機能でワンクリック保存が可能
- モバイル対応UI — ネットワーク内のどのデバイスからでもアクセスできる
内部構成はNext.jsフロントエンド、クロール用バックグラウンドワーカー、全文インデックス用のMeilisearch、そしてオプションのAIレイヤーだ。すべてコンテナ化されている。
始める前の前提条件
必要なもの:
- DockerとDocker Composeがインストール済みのLinuxサーバー(ベアメタルまたはVM)
- 最低2GB RAM — MeilisearchはメモリをよくあそこうするためAIを有効にするなら4GB以上を推奨
- OpenAI APIキー(オプションだがAI機能には推奨)、またはローカルのOllamaセットアップ
- HTTPSが必要な場合はドメインまたはローカルDNS — ローカルIPでも問題なく動作する
Docker ComposeでHoarderをセットアップする
作業ディレクトリとComposeファイルを作成する:
mkdir -p ~/homelab/hoarder && cd ~/homelab/hoarder
nano docker-compose.yml
以下の設定を貼り付ける:
version: "3.8"
services:
web:
image: ghcr.io/hoarder-app/hoarder:release
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- hoarder_data:/data
env_file:
- .env
depends_on:
- meilisearch
- chrome
meilisearch:
image: getmeili/meilisearch:v1.6
restart: unless-stopped
volumes:
- meilisearch_data:/meili_data
environment:
- MEILI_NO_ANALYTICS=true
- MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
chrome:
image: gcr.io/zenika-hub/alpine-chrome:123
restart: unless-stopped
command:
- --no-sandbox
- --disable-gpu
- --disable-dev-shm-usage
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=9222
- --hide-scrollbars
volumes:
hoarder_data:
meilisearch_data:
次に、シークレットを生成して完全な.envファイルを一度に書き出す。これにより重複キーや変数参照の問題を回避できる:
NEXTAUTH_SECRET=$(openssl rand -base64 36)
MEILI_KEY=$(openssl rand -base64 36)
cat > .env << EOF
NEXTAUTH_SECRET=$NEXTAUTH_SECRET
MEILI_MASTER_KEY=$MEILI_KEY
NEXTAUTH_URL=http://YOUR_SERVER_IP:3000
HOARDER_LOG_LEVEL=info
BROWSER_WEB_URL=http://chrome:9222
MEILISEARCH_URL=http://meilisearch:7700
MEILISEARCH_MASTER_KEY=$MEILI_KEY
OPENAI_API_KEY=sk-your-openai-key-here
OPENAI_BASE_URL=https://api.openai.com/v1
# オプション:OpenAIの代わりにローカルのOllamaを使用する
# OLLAMA_BASE_URL=http://YOUR_SERVER_IP:11434
EOF
注意点として、MEILI_MASTER_KEYとMEILISEARCH_MASTER_KEYは必ず同じ値にする必要がある。前者はMeilisearch自体の設定で、後者はHoarderのWebサービスがMeilisearchに認証する方法を指定するものだ。上記のスクリプトではこれを自動的に処理している。
すべてを起動する:
docker compose up -d
docker compose logs -f web
初回起動時は30〜60秒ほど待とう。MeilisearchがインデックスをInitializeするのに少し時間がかかる。ログにServer running on port 3000と表示されたら、ブラウザでhttp://YOUR_SERVER_IP:3000を開く。
初回ログインと初期設定
初回起動時、Hoarderはブラウザ上で直接管理者アカウントを作成できる。特に外部公開を予定している場合は強力なパスワードを使用すること。
ログイン後、設定 → AIに移動してOpenAIキーが認識されていることを確認する。テスト用のブックマークを保存して以下を確認しよう:
- ページコンテンツがスクレイピングされている(ブックマークの「キャッシュ」タブで確認)
- 1〜2分以内に要約が表示される
- タグが自動提案される
要約が表示されない場合はワーカーのログを確認する:
docker compose logs web | grep -i "openai\|summary\|error"
OpenAIの代わりにOllamaを使う
すでにHomeLab上でOllamaを動かしているなら、.envのAI設定を切り替えよう:
# OpenAIをコメントアウト
# OPENAI_API_KEY=...
# Ollamaを追加
OLLAMA_BASE_URL=http://YOUR_OLLAMA_HOST:11434
OLLAMA_MODEL=llama3.2
変更後はスタックを再起動する:
docker compose restart web
Ollamaは要約処理を十分にこなせる。自動タグ付けの精度については、llama3.2やmistralが無難な結果を出す。GPT-4の品質には及ばないが、無料でプライベートな環境としては十分すぎるほどだ。
ブラウザ拡張機能のインストール
ブラウザ拡張機能こそがHoarderを日常的に使えるものにする要素だ。これがなければURLを手動でコピーするしかなく、本末転倒になってしまう。
- Chrome ウェブストアまたはFirefoxアドオンで「Hoarder」を検索する
- インストール後、拡張機能のアイコンをクリック → 設定
- サーバーURLにHoarderのアドレスを設定する:
http://YOUR_SERVER_IP:3000 - Hoarderで APIキーを生成する:設定 → APIキー → 新しいキー
- 拡張機能の設定にAPIキーを貼り付ける
これ以降はワンクリックで保存できる。拡張機能はAIサマリーが生成されるとプレビューも表示してくれる。
毎日使って気づいた実践的なコツ
検索こそが最大の武器
ブックマークリストを眺めるのはやめよう。検索するだけでいい。Hoarderはページの全コンテンツをインデックス化するため、どこに保存したか忘れても読んだ内容のキーワードで見つけられる。記事本文の数単語を入力するだけで、Meilisearchがタイポも補正しながら検索してくれる。
進行中のプロジェクトにはリストを活用する
Hoarderの「リスト」機能は継続的な作業においてフォルダよりも優れている。アクティブなプロジェクトごとにリストを作成し、関連するブックマークを追加して、プロジェクト終了後はリストをアーカイブする。全体のブックマーク数を管理しやすい状態に保てる。
リモートアクセス用にリバースプロキシを設定する
自宅ネットワークの外からHoarderにアクセスしたいなら、Nginx Proxy ManagerやCaddyでHTTPSと合わせて配置しよう。最小限のCaddy設定例:
hoarder.yourdomain.com {
reverse_proxy localhost:3000
}
HTTPSなしで公開してはいけない。そのままでは APIキーもブックマークも平文で通信されてしまう。
データボリュームをバックアップする
スクレイピングされたコンテンツは急速に蓄積される。私の環境では2ヶ月で約2GBに達した。両方のボリュームを定期的にバックアップしよう:
# バックアップスクリプト — cronに追加する
docker run --rm \
-v hoarder_hoarder_data:/source:ro \
-v /backup/hoarder:/backup \
alpine tar czf /backup/hoarder_data_$(date +%Y%m%d).tar.gz -C /source .
docker run --rm \
-v hoarder_meilisearch_data:/source:ro \
-v /backup/hoarder:/backup \
alpine tar czf /backup/meili_data_$(date +%Y%m%d).tar.gz -C /source .
Hoarderをアップデートする
docker compose pull
docker compose up -d
Hoarderは安定版リリースを追跡するreleaseタグを使用している。変更内容を確認したい場合はpullする前にGitHubのリリースページを確認しよう。
まとめ
3ヶ月間毎日使い続けた結果、あの「あとで読む」フォルダは今では本当に役立つツールになった。全文検索とAIサマリーの組み合わせは、保存コンテンツとの向き合い方を根本から変える。ただリンクを溜め込む場所ではなく、実際にクエリを投げられるナレッジベースへと変わるのだ。
セットアップにかかる時間は約20分。私の環境ではAIなしでアイドル時のRAM使用量は約400MB、Ollama起動時は約900MBだ。アップデートとバックアップは他のHomeLab上のサービスと同じパターンに従う — docker compose pull一発と、cronで定期実行するボリュームバックアップだけだ。
まだブラウザのブックマークや先行きの怪しいクラウドサービスに頼っているなら、半日かけてでも試してみる価値は十分にある。

