ponshu-room-lite/docs/ARCHITECTURE_DECISION_RECOR...

536 lines
17 KiB
Markdown
Raw Normal View History

# インフラ構成の意思決定記録ADR: Architecture Decision Record
**作成日**: 2026-01-18
**対象プロジェクト**: Ponshu Room Lite日本酒アプリ+ 将来のPosimai Platform
**検討メンバー**: 開発者 + Claude (Anthropic) + Gemini (Google)
---
## 📋 目次
1. [現状の環境と課題](#現状の環境と課題)
2. [検討した構成案](#検討した構成案)
3. [最終推奨アーキテクチャ](#最終推奨アーキテクチャ)
4. [Antigravity向けサマリー](#antigravity向けサマリー)
---
## 現状の環境と課題
### ✅ **既存環境**
- **Synology NAS**: メモリ16GB高スペック
- **Container Manager**: 導入済み
- **Gitea**: 導入済みGit管理
- **Tailscale**: 導入済み・稼働中VPNアクセス可能
- **現状のアクセス**: TailscaleのIP100.x.x.xで外部からアクセス可能
### ❌ **過去の失敗Synology経由AI解析**
**時期**: 2025年頃
**問題点**:
1. **自宅の壁**: ローカルIP192.168.x.xで外出先から接続不可
2. **セキュリティの壁**: HTTP通信がモバイルOSでブロック
3. **レイテンシ**: 自宅回線の上り速度ボトルネック
**結果**: Direct CloudGemini API直接アクセスに戻した
### 🎯 **現在の目標**
1. **Geminiトークン消費削減**: 無料枠1日1,500回を超えないように
2. **データ所有権**: クラウドに依存せず、Synology内で完結
3. **外出先アクセス**: 安全かつ高速なHTTPSアクセス
4. **ずぼら対応**: 自動化・メンテナンスフリー
5. **お香アプリ展開**: 同じインフラで複数アプリ展開
---
## 検討した構成案
### 案1: **Cloudflare Tunnel方式**Claude提案
#### アーキテクチャ
```
スマホ → Cloudflare Tunnel (HTTPS) → Synology NAS
posimai.yourname.com
```
#### メリット
- ✅ ポート開放不要
- ✅ 自動HTTPS化証明書管理不要
- ✅ カスタムドメイン使用可能
- ✅ DDoS防御機能あり
- ✅ 無料
#### デメリット
- ⚠️ Cloudflareへの依存
- ⚠️ トンネル設定の初期学習コスト
- ⚠️ すでにTailscaleがあるのに二重導入
---
### 案2: **Tailscale Funnel方式**Gemini提案
#### アーキテクチャ
```
スマホ → Tailscale Funnel (HTTPS) → Synology NAS
nas-name.tailnet-name.ts.net
```
#### メリット
-**既存のTailscaleを活用**(追加インストール不要)
- ✅ ポート開放不要
- ✅ 自動HTTPS化
- ✅ Tailscaleの既存知見を活かせる
- ✅ 無料(個人利用)
#### デメリット
- ⚠️ カスタムドメインは別途設定必要
- ⚠️ Cloudflareほど多機能ではないWAF等
---
### 案3: **Synology QuickConnect方式**
#### アーキテクチャ
```
スマホ → Synology Relay Server → Synology NAS
QuickConnect.to/yourID
```
#### メリット
- ✅ Synology公式・設定最簡単
- ✅ ポート開放不要
- ✅ 追加ソフト不要
#### デメリット
-**速度が遅い**(中継経由のため)
- ❌ カスタムドメイン不可
- ❌ API開発には不向き
---
### 案4: **Tailscale MagicDNS + HTTPS方式**(推奨)
#### アーキテクチャ
```
スマホ (Tailscale VPN) → MagicDNS → Synology NAS
https://nas-name.ts.net
```
#### メリット
-**既存環境を最大活用**
- ✅ 正式なHTTPS証明書Let's Encrypt
- ✅ IPアドレス不要・名前でアクセス
- ✅ モバイルアプリのセキュリティ要件クリア
- ✅ 追加コストゼロ
#### デメリット
- ⚠️ 一般公開には不向きTailscaleインストール必須
- → 開発・テスト段階では問題なし
---
## 最終推奨アーキテクチャ
### **段階的アプローチ3ステージ**
#### **Stage 1: 開発・テスト段階(今すぐ)**
**採用案**: Tailscale MagicDNS + HTTPS
```
┌─────────────────────────────────────┐
│ 開発環境(現在〜数ヶ月) │
├─────────────────────────────────────┤
│ │
│ スマホ (Tailscale VPN) │
│ ↓ │
│ https://posimai-nas.ts.net │
│ ↓ │
│ ┌──────────────────────────────┐ │
│ │ Synology NAS (16GB) │ │
│ │ │ │
│ │ - Immich (写真 + AI検索) │ │
│ │ - PostgreSQL (データ) │ │
│ │ - Ollama (夜間AI解析) │ │
│ │ - Gitea (コード管理) │ │
│ └──────────────────────────────┘ │
│ ↓ │
│ Gemini API (リアルタイム解析) │
└─────────────────────────────────────┘
```
**理由**:
- ✅ 既存Tailscale活用で最速立ち上げ
- ✅ HTTPS対応でFlutterアプリ開発可能
- ✅ 外出先テスト可能(自分のデバイスのみ)
- ✅ 追加コストゼロ
**設定手順**:
1. Tailscale管理画面でMagicDNS有効化
2. HTTPS証明書の自動発行設定
3. FlutterアプリのAPI接続先を `https://posimai-nas.ts.net` に設定
---
#### **Stage 2: 限定公開段階(β版リリース)**
**追加導入**: Tailscale Funnel
```
┌─────────────────────────────────────┐
│ β版・限定公開(数ヶ月後) │
├─────────────────────────────────────┤
│ │
│ 一般ユーザーTailscaleなし
│ ↓ │
│ https://posimai.tailnet.ts.net │
│ ↓ │
│ Tailscale Funnel (公開エンドポイント)│
│ ↓ │
│ Synology NAS (同構成) │
└─────────────────────────────────────┘
```
**理由**:
- ✅ Tailscaleの延長線上で公開可能
- ✅ 学習コスト最小
- ✅ β版フィードバック収集に最適
---
#### **Stage 3: 本番運用(正式リリース)**
**選択肢A**: Cloudflare Tunnel導入カスタムドメイン重視
**選択肢B**: Tailscale継続コスト・シンプルさ重視
```
┌─────────────────────────────────────┐
│ 本番環境1年後〜
├─────────────────────────────────────┤
│ │
│ 【選択肢A: Cloudflare Tunnel】 │
│ 一般ユーザー │
│ ↓ │
│ https://api.posimai.com │
│ ↓ │
│ Cloudflare Tunnel │
│ ↓ │
│ Synology NAS │
│ │
│ 【選択肢B: Tailscale Funnel継続】 │
│ 一般ユーザー │
│ ↓ │
│ https://api.posimai.ts.net │
│ ↓ │
│ Tailscale Funnel │
│ ↓ │
│ Synology NAS │
└─────────────────────────────────────┘
```
**判断基準**:
- ユーザー数が1万人超 → Cloudflare推奨DDoS対策
- ユーザー数が数百人規模 → Tailscale継続で十分
---
### **詳細構成docker-compose.yml**
```yaml
version: '3.8'
services:
# 1. 写真管理 + AI検索CLIP内蔵
immich-server:
image: ghcr.io/immich-app/immich-server:latest
container_name: immich_server
environment:
DB_HOSTNAME: postgres
DB_USERNAME: postgres
DB_PASSWORD: ${DB_PASSWORD}
DB_DATABASE_NAME: immich
REDIS_HOSTNAME: redis
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
depends_on:
- redis
- postgres
restart: always
networks:
- posimai-net
# 2. データベース
postgres:
image: tensorchord/pgvecto-rs:pg16-v0.2.0
container_name: immich_postgres
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: postgres
POSTGRES_DB: immich
volumes:
- /volume1/docker/posimai/pgdata:/var/lib/postgresql/data
restart: always
networks:
- posimai-net
# 3. キャッシュ
redis:
image: redis:7.2-alpine
container_name: immich_redis
restart: always
networks:
- posimai-net
# 4. ローカルAI夜間バッチ用
ollama:
image: ollama/ollama:latest
container_name: ollama
volumes:
- /volume1/docker/posimai/ollama:/root/.ollama
restart: always
networks:
- posimai-net
deploy:
resources:
limits:
memory: 8G
# 5. 自動化ハブ(ノーコード自動化)
activepieces:
image: activepieces/activepieces:latest
container_name: activepieces
environment:
AP_ENGINE_EXECUTABLE_PATH: dist/packages/engine/main.js
AP_POSTGRES_DATABASE: activepieces
AP_POSTGRES_HOST: postgres
AP_POSTGRES_PASSWORD: ${DB_PASSWORD}
AP_POSTGRES_PORT: 5432
AP_POSTGRES_USERNAME: postgres
restart: always
networks:
- posimai-net
# 6. コンテナ管理UI
dockhand:
image: felixboet/dockhand:latest
container_name: dockhand
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: always
networks:
- posimai-net
networks:
posimai-net:
driver: bridge
```
---
### **AI解析フロー詳細**
#### リアルタイム解析(昼間)
```
┌──────────────┐
│ スマホで撮影 │
└──────┬───────┘
┌──────────────────────┐
│ Flutter App │
│ 1. 画像圧縮 (1024px) │
│ 2. OCR前処理 │
└──────┬───────────────┘
│ HTTPS
┌──────────────────────┐
│ Synology (Immich) │
│ 1. 画像保存 │
│ 2. ハッシュ計算 │
│ 3. キャッシュ確認 │
└──────┬───────────────┘
├─ キャッシュHIT → DB取得即座
└─ キャッシュMISS ↓
┌──────────────┐
│ Gemini API │
│ Vision解析 │
│ (1-3秒) │
└──────┬───────┘
┌──────────────┐
│ 結果をDB保存 │
│ + キャッシュ │
└──────────────┘
```
#### 夜間バッチ解析
```
┌──────────────────────┐
│ cron: 毎晩0時実行 │
└──────┬───────────────┘
┌──────────────────────┐
│ 今日の登録写真を取得 │
└──────┬───────────────┘
┌──────────────────────┐
│ Ollama (NAS内AI) │
│ - Llama 3.2 Vision │
│ - 時間: 10-30秒/枚 │
│ │
│ 処理内容: │
│ 1. ペアリング提案 │
│ 2. 詳細解説生成 │
│ 3. 類似銘柄検索 │
└──────┬───────────────┘
┌──────────────────────┐
│ PostgreSQLに保存 │
│ - pairing_suggestion │
│ - detailed_notes │
│ - similar_items[] │
└──────────────────────┘
```
---
## Antigravity向けサマリー
### 🎯 **検討の核心ポイント**
#### 1. **なぜURLが重要なのか**
- **モバイルアプリの要件**: HTTPS必須HTTPはブロックされる
- **IPアドレスの限界**: SSL証明書が発行できない
- **AI連携**: Webhook外部からの通知受信に固定URLが必要
- **開発効率**: AIエージェントClaude/Cursorへの指示がしやすい
#### 2. **Cloudflare vs Tailscale 比較**
| 観点 | Cloudflare Tunnel | Tailscale Funnel/MagicDNS |
|------|-------------------|---------------------------|
| **既存環境活用** | ❌ 新規導入 | ✅ **既存Tailscale活用** |
| **設定の簡単さ** | ⚠️ 学習コストあり | ✅ **既存知見を活かせる** |
| **HTTPS対応** | ✅ 自動 | ✅ 自動Let's Encrypt |
| **カスタムドメイン** | ✅ 簡単 | ⚠️ DNS設定必要 |
| **一般公開** | ✅ 最適 | ✅ Funnelで可能 |
| **DDoS対策** | ✅ 強力 | ⚠️ 基本的な保護のみ |
| **コスト** | 無料 | 無料(個人利用) |
| **推奨段階** | Stage 3本番 | **Stage 1-2開発〜β版** |
#### 3. **最終推奨方針**
**即座に着手**: Tailscale MagicDNS + HTTPS設定
- 理由: 既存環境を最大活用、最速で開発開始可能
- 所要時間: 30分-1時間
- リスク: ほぼゼロ
**中期検討**: Tailscale Funnel導入β版公開時
- 理由: 一般ユーザーへの公開が可能になる
- 所要時間: 1-2時間
- リスク: 低
**長期検討**: Cloudflare Tunnel移行判断正式版リリース時
- 判断基準: ユーザー数・トラフィック・セキュリティ要件
- 移行コスト: 中(新規学習必要)
---
### 📊 **技術スタック詳細**
#### ライセンス・商用利用まとめ
| ツール | ライセンス | 商用利用 | 注意点 |
|--------|-----------|---------|--------|
| **Immich** | AGPL-3.0 | ⚠️ API経由のみOK | 本体改造時は公開義務 |
| **Ollama** | MIT | ✅ 完全OK | 制限なし |
| **Activepieces** | MIT | ✅ 完全OK | Community版 |
| **Dockhand** | MIT | ✅ 完全OK | 制限なし |
| **Gitea** | MIT | ✅ 完全OK | 制限なし |
#### メモリ配分16GB環境
| サービス | 推奨メモリ | 役割 |
|---------|-----------|------|
| Ollama | 4-8GB | ローカルAI夜間バッチ |
| Immich | 2-4GB | 写真管理 + CLIP検索 |
| PostgreSQL | 2GB | データベース |
| Activepieces | 1-2GB | 自動化ハブ |
| その他 | 2-4GB | Redis, Dockhand等 |
---
### 🚀 **次のアクション(優先順)**
#### Step 1: Tailscale HTTPS化今週
```bash
# Tailscale管理画面で実行
1. MagicDNS有効化
2. HTTPS証明書設定
3. DNS名確認: posimai-nas.ts.net
```
#### Step 2: Immich導入来週
```bash
# Synology Container Managerで実行
1. docker-compose.yml配置
2. docker-compose up -d
3. https://posimai-nas.ts.net:2283 でアクセス確認
```
#### Step 3: Flutter接続テスト再来週
```dart
// lib/config/api_config.dart
class ApiConfig {
static const String baseUrl = 'https://posimai-nas.ts.net';
static const String immichEndpoint = '$baseUrl:2283/api';
}
```
---
### 💡 **開発者(非エンジニア)へのアドバイス**
#### 「ずぼら」を活かす運用設計
1. **Dockhand自動更新**: コンテナの更新を深夜自動実行
2. **Activepieces自動化**: 写真→解析→DB保存→通知を完全自動化
3. **AIログ生成**: Giteaへのコミットを自動でLINE/Discord通知
#### クレジット表記例
```dart
// アプリの「このアプリについて」画面
const String credits = '''
使用技術:
- Photo Management: Immich (AGPL-3.0)
- Local AI: Ollama (MIT)
- Automation: Activepieces (MIT)
- Infrastructure: Synology NAS + Tailscale
''';
```
---
## 参考資料
### 関連ドキュメント
- [expansion_and_infrastructure_plan.md](../expansion_and_infrastructure_plan.md)
- [technical_spec_incense_v1.md](../technical_spec_incense_v1.md)
- [DARK_MODE_GUIDELINES.md](./DARK_MODE_GUIDELINES.md)
### 外部リンク
- [Tailscale MagicDNS](https://tailscale.com/kb/1081/magicdns/)
- [Tailscale Funnel](https://tailscale.com/kb/1223/tailscale-funnel/)
- [Immich Documentation](https://immich.app/docs/overview/introduction)
- [Ollama Model Library](https://ollama.com/library)
---
**更新履歴**:
- 2026-01-18: 初版作成Claude + Gemini検討内容統合