Add Docker/Lightsail deployment, web search summarization, and fix vite peer dep

- Add backend/frontend Dockerfiles, nginx reverse proxy config, and
  docker-compose.yml to run the app on AWS Lightsail; document the setup
  in docs/deploy-lightsail.md. Fix a .gitignore path anchoring bug that
  left backend/knowledge_base/web_search/ untracked instead of ignored.
- Summarize web search results into structured Markdown via LLM before
  saving them to the local knowledge base, and support regenerating
  existing entries from their source URLs (backend/app/core/memory_kb).
- Downgrade vite to ^6 to match @vitejs/plugin-vue's peer dependency
  range, fixing a failing `npm ci` (found while testing the Docker build).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 02:45:09 +09:00
co-authored by Claude Sonnet 5
parent 347230e3c8
commit 8e01458bb2
18 changed files with 1375 additions and 213 deletions
+141
View File
@@ -0,0 +1,141 @@
# AWS Lightsail へのデプロイ
このアプリを AWS Lightsail の「インスタンス」(Ubuntu VPS)上で、Docker Compose を使って動かす手順。
SQLite・ローカルナレッジベース・Discord Bot・APScheduler がすべて 1 プロセス(バックエンドコンテナ)内で常駐するため、
Lightsail Containers(マネージドコンテナサービス)よりも、状態を持てる通常のインスタンス構成の方が相性が良い。
## 構成
```
Internet
│ :80 / :443
▼
[frontend コンテナ] nginx
├─ 静的ファイル (Vue ビルド成果物) を配信
└─ /chat, /api, /memory, /logs, /health を backend にリバースプロキシ
│
▼
[backend コンテナ] FastAPI (uvicorn)
└─ SQLite (playchat.db) / knowledge_base を Docker Volume に永続化
```
`frontend/src/api/client.ts` はすべて相対パスで API を呼ぶ実装になっているため、
本番でも frontend と backend を同一オリジン(nginx 経由)で配信すれば CORS 設定は事実上不要。
リポジトリには以下を追加済み:
- [backend/Dockerfile](../backend/Dockerfile)
- [frontend/Dockerfile](../frontend/Dockerfile) / [frontend/nginx.conf](../frontend/nginx.conf)
- [docker-compose.yml](../docker-compose.yml)
## 1. Lightsail インスタンスの作成
1. Lightsail コンソール → 「インスタンスの作成」
2. プラットフォーム: **Linux/Unix**、設計図: **OS のみ → Ubuntu 22.04 LTS**
3. プラン: **2GB RAM / 1vCPU($10/月)以上を推奨**
(フロントエンドの `npm run build` (vue-tsc) はビルド時にメモリを食うため、1GB プランだと OOM で失敗することがある)
4. インスタンス名を付けて作成
作成後、インスタンス詳細ページの「ネットワーキング」タブで:
- **静的 IP をアタッチ**(再起動してもIPが変わらないようにする。ドメインを使う場合は必須)
- ファイアウォールで **80 (HTTP)** と、HTTPS を使うなら **443** を許可(22/SSH はデフォルトで開いている)
## 2. SSH 接続 & Docker のインストール
Lightsail コンソールの「接続」タブからブラウザ SSH で入るか、ダウンロードした鍵で接続する。
```bash
sudo apt update && sudo apt upgrade -y
# Docker 公式インストールスクリプト
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
# Docker Compose Plugin の確認(get.docker.com で入る場合が多い)
docker compose version
```
## 3. リポジトリの取得と設定
```bash
git clone <このリポジトリのURL> playchat
cd playchat
cp backend/.env.example backend/.env
nano backend/.env # APIキーやモデル名など本番用の値を設定
```
`backend/.env` で最低限確認する項目:
| 変数 | 本番での指針 |
|---|---|
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` | 使うプロバイダーのキーを設定 |
| `DEFAULT_MODEL` | 使いたいモデル名 |
| `CORS_ORIGINS` | `http://<静的IP>` またはドメイン(nginx が同一オリジンで配信するので基本は素通りするが念のため合わせておく) |
| `DATABASE_URL` | **編集不要**(`docker-compose.yml` が `/app/data/playchat.db` に上書きし、Docker Volume に永続化する) |
| `DISCORD_BOT_TOKEN` 等 | Discord Bot / 通知機能を使うなら設定。不要なら空のままでよい(未設定時は該当機能が無効) |
`backend/.env` はコンテナに `env_file` として渡され、Git 管理対象外(`.gitignore` 済み)なので直接編集してよい。
## 4. ビルド & 起動
```bash
docker compose build
docker compose up -d
docker compose logs -f backend # 起動ログ確認(Ctrl+C で抜ける。プロセスは動き続ける)
```
ブラウザで `http://<静的IP>/` にアクセスして動作確認する。
停止・再起動・更新の運用コマンド:
```bash
docker compose ps # 状態確認
docker compose restart backend # backend だけ再起動
git pull && docker compose up -d --build # コード更新を反映
```
## 5. 永続化されるデータ
`docker-compose.yml` は以下を Named Volume にしている(`docker compose down` してもデータは消えない。`docker compose down -v` は消えるので注意):
- `backend_data` … `playchat.db`(会話履歴・メモリ)
- `backend_knowledge_base` … `knowledge_base/`(Web検索で蓄積したナレッジ含む)
バックアップ例:
```bash
docker compose exec backend sqlite3 /app/data/playchat.db ".backup /app/data/backup.db"
docker cp $(docker compose ps -q backend):/app/data/backup.db ./playchat-backup-$(date +%F).db
```
インスタンスごとのバックアップとしては、Lightsail の「スナップショット」機能(自動スナップショット設定可)も併用すると安心。
## 6. HTTPS 化(ドメインがある場合)
ドメインの A レコードを Lightsail の静的 IP に向けた上で、ホスト側で certbot を使い証明書を取得し、
`frontend` コンテナへ読み取り専用でマウントする。
```bash
sudo apt install -y certbot
docker compose stop frontend # 80番ポートを一時的に空ける
sudo certbot certonly --standalone -d your-domain.example.com
docker compose start frontend
```
`frontend/nginx.conf` に 443 用のサーバーブロックを追記し、`docker-compose.yml` の `frontend` サービスに
`443:443` のポートマッピングと `/etc/letsencrypt` のボリュームマウントを追加する(証明書更新時は `docker compose restart frontend` が必要。
`certbot renew` の `--deploy-hook` に登録しておくと自動化できる)。この構成に変更したい場合は改めて対応する。
## 7. 常駐タスクについて
APScheduler(天気通知など)と Discord Bot は `backend` コンテナ起動時(FastAPI の `lifespan`)に単一プロセス内で動く。
`restart: unless-stopped` を設定しているため、インスタンス再起動やコンテナクラッシュ時も自動的に立ち上がる。
複数インスタンス/複数コンテナへのスケールアウトは想定していない(SQLite・APScheduler・Discord Bot が単一プロセス前提のため)。
## コスト目安
- Lightsail インスタンス 2GB プラン: 約 $10/月(固定IP・80/443 の転送量込み)
- LLM API 利用料(OpenAI / Anthropic / Bedrock)は別途従量課金