セルフホスト可能なRSSリーダーで、見た目も美しく実用的なものが公開されていたので導入してみました。
デモサイトもあるようなので動作を試してみてください。各種AIのAPIキーを登録することで、AI連携でも利用出来ます。

Oksskoltenをdocker composeで導入
下記スクリプトを作成して実行するだけです。
# スクリプトファイルを作成・下記を貼り付け
nano setup-oksskolten.sh
# 作成したスクリプトを実行
sudo bash setup-oksskolten.sh
#!/usr/bin/env bash
# ============================================================
# oksskolten セルフホスト セットアップスクリプト
# インストール先: /opt/docker/oksskolten
# OS: Ubuntu 25.10 / docker compose 導入済み前提
# ============================================================
set -euo pipefail
INSTALL_DIR="/opt/docker/oksskolten"
# ------------------------------------------------------------
echo "==> [1/5] ディレクトリ作成 & リポジトリ取得"
# ------------------------------------------------------------
sudo mkdir -p "$INSTALL_DIR"
sudo chown "$USER":"$USER" "$INSTALL_DIR"
if [ -d "$INSTALL_DIR/.git" ]; then
echo " 既存のリポジトリを更新します..."
git -C "$INSTALL_DIR" pull
else
git clone https://github.com/babarot/oksskolten.git "$INSTALL_DIR"
fi
cd "$INSTALL_DIR"
# ------------------------------------------------------------
echo "==> [2/5] シークレットキーを自動生成して .env を作成"
# ------------------------------------------------------------
gen_secret() { openssl rand -hex 32; }
if [ -f "$INSTALL_DIR/.env" ]; then
echo " .env が既に存在します。上書きをスキップします。"
else
JWT_SECRET="$(gen_secret)"
SESSION_SECRET="$(gen_secret)"
MEILI_MASTER_KEY="$(gen_secret)"
cat > "$INSTALL_DIR/.env" <<EOF
# ----- サーバー設定 -----
NODE_ENV=production
PORT=3000
# データ保存先(コンテナ内 /data にマウント)
DATA_DIR=./data
# ----- セキュリティ(自動生成済み / 変更不要) -----
JWT_SECRET=${JWT_SECRET}
SESSION_SECRET=${SESSION_SECRET}
# ----- Meilisearch -----
MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
MEILI_URL=http://meilisearch:7700
# ----- AI プロバイダー(任意 / 後から Settings UI で設定可) -----
# ANTHROPIC_API_KEY=your_anthropic_key_here
# OPENAI_API_KEY=your_openai_key_here
# GEMINI_API_KEY=your_gemini_key_here
# ----- GitHub OAuth(任意) -----
# GITHUB_CLIENT_ID=
# GITHUB_CLIENT_SECRET=
# ----- Cloudflare Tunnel(任意 / 使わない場合は空のまま) -----
# TUNNEL_TOKEN=
# ----- シードデータ無効化(空の DB で始めたい場合は 1 に) -----
# NO_SEED=1
EOF
echo " .env を作成しました。"
fi
# ------------------------------------------------------------
echo "==> [3/5] データディレクトリ作成 & 権限設定"
# コンテナの app ユーザー (uid=100, gid=101) が書き込めるよう設定
# ------------------------------------------------------------
mkdir -p "$INSTALL_DIR/data"
sudo chown -R 100:101 "$INSTALL_DIR/data"
sudo chmod -R 775 "$INSTALL_DIR/data"
# ------------------------------------------------------------
echo "==> [4/5] ポート公開用オーバーライドファイルを作成"
# compose.prod.yaml はポートを削除してしまうため別ファイルで上書き
# ------------------------------------------------------------
sudo tee "$INSTALL_DIR/compose.port.yaml" > /dev/null <<'EOF'
services:
server:
ports:
- "3000:3000"
EOF
echo " compose.port.yaml を作成しました。"
# ------------------------------------------------------------
echo "==> [5/5] Docker イメージビルド & コンテナ起動"
# ------------------------------------------------------------
docker compose \
--env-file "$INSTALL_DIR/.env" \
-f "$INSTALL_DIR/compose.yaml" \
-f "$INSTALL_DIR/compose.prod.yaml" \
-f "$INSTALL_DIR/compose.port.yaml" \
up --build -d
# ------------------------------------------------------------
# 起動後にDBファイルの権限を再修正
# (初回ビルド時にシードDBが別権限で生成されることがあるため)
# ------------------------------------------------------------
echo " DBファイルの権限を確認・修正します..."
sleep 5
sudo chown -R 100:101 "$INSTALL_DIR/data"
sudo chmod 664 "$INSTALL_DIR/data"/*.db 2>/dev/null || true
sudo chmod 775 "$INSTALL_DIR/data"
echo ""
echo "============================================================"
echo " oksskolten の起動が完了しました!"
echo ""
echo " アクセス URL : http://$(hostname):3000"
echo " インストール先: $INSTALL_DIR"
echo ""
echo " AI API キーは Settings UI から後で設定できます。"
echo ""
echo " ログ確認:"
echo " docker compose -f $INSTALL_DIR/compose.yaml \\"
echo " -f $INSTALL_DIR/compose.prod.yaml \\"
echo " -f $INSTALL_DIR/compose.port.yaml \\"
echo " logs -f server"
echo ""
echo " 停止:"
echo " docker compose -f $INSTALL_DIR/compose.yaml \\"
echo " -f $INSTALL_DIR/compose.prod.yaml \\"
echo " -f $INSTALL_DIR/compose.port.yaml \\"
echo " down"
echo "============================================================"

