- 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>
142 lines
6.5 KiB
Markdown
142 lines
6.5 KiB
Markdown
# 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)は別途従量課金
|