17 KiB
17 KiB
インフラ構成の意思決定記録(ADR: Architecture Decision Record)
作成日: 2026-01-18 対象プロジェクト: Ponshu Room Lite(日本酒アプリ)+ 将来のPosimai Platform 検討メンバー: 開発者 + Claude (Anthropic) + Gemini (Google)
📋 目次
現状の環境と課題
✅ 既存環境
- Synology NAS: メモリ16GB(高スペック)
- Container Manager: 導入済み
- Gitea: 導入済み(Git管理)
- Tailscale: 導入済み・稼働中(VPNアクセス可能)
- 現状のアクセス: TailscaleのIP(100.x.x.x)で外部からアクセス可能
❌ 過去の失敗(Synology経由AI解析)
時期: 2025年頃 問題点:
- 自宅の壁: ローカルIP(192.168.x.x)で外出先から接続不可
- セキュリティの壁: HTTP通信がモバイルOSでブロック
- レイテンシ: 自宅回線の上り速度ボトルネック
結果: Direct Cloud(Gemini API直接アクセス)に戻した
🎯 現在の目標
- Geminiトークン消費削減: 無料枠(1日1,500回)を超えないように
- データ所有権: クラウドに依存せず、Synology内で完結
- 外出先アクセス: 安全かつ高速なHTTPSアクセス
- ずぼら対応: 自動化・メンテナンスフリー
- お香アプリ展開: 同じインフラで複数アプリ展開
検討した構成案
案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アプリ開発可能
- ✅ 外出先テスト可能(自分のデバイスのみ)
- ✅ 追加コストゼロ
設定手順:
- Tailscale管理画面でMagicDNS有効化
- HTTPS証明書の自動発行設定
- 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)
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化(今週)
# Tailscale管理画面で実行
1. MagicDNS有効化
2. HTTPS証明書設定
3. DNS名確認: posimai-nas.ts.net
Step 2: Immich導入(来週)
# Synology Container Managerで実行
1. docker-compose.yml配置
2. docker-compose up -d
3. https://posimai-nas.ts.net:2283 でアクセス確認
Step 3: Flutter接続テスト(再来週)
// lib/config/api_config.dart
class ApiConfig {
static const String baseUrl = 'https://posimai-nas.ts.net';
static const String immichEndpoint = '$baseUrl:2283/api';
}
💡 開発者(非エンジニア)へのアドバイス
「ずぼら」を活かす運用設計
- Dockhand自動更新: コンテナの更新を深夜自動実行
- Activepieces自動化: 写真→解析→DB保存→通知を完全自動化
- AIログ生成: Giteaへのコミットを自動でLINE/Discord通知
クレジット表記例
// アプリの「このアプリについて」画面
const String credits = '''
使用技術:
- Photo Management: Immich (AGPL-3.0)
- Local AI: Ollama (MIT)
- Automation: Activepieces (MIT)
- Infrastructure: Synology NAS + Tailscale
''';
参考資料
関連ドキュメント
外部リンク
更新履歴:
- 2026-01-18: 初版作成(Claude + Gemini検討内容統合)