# インフラ設計書

## 概要

本ドキュメントは、Chatwoot（オープンソースカスタマーサポートプラットフォーム）のインフラストラクチャ構成を記載する。Chatwootは、Ruby on Rails 7.1ベースのWebアプリケーションであり、PostgreSQL、Redis、Sidekiqを中心としたマイクロサービス的なアーキテクチャを採用している。

## システム構成

### 全体構成

Chatwootは以下のコンポーネントで構成される:

1. **Railsアプリケーションサーバー**: メインのWebアプリケーション（Puma）
2. **Sidekiqワーカー**: バックグラウンドジョブ処理
3. **PostgreSQL**: メインデータベース（pgvector拡張によるベクトル検索対応）
4. **Redis**: キャッシュ、セッション、ActionCable（WebSocket）、Sidekiqジョブキュー
5. **Vite**: フロントエンドアセットビルド（開発環境）
6. **Nginx**: リバースプロキシ/ロードバランサー（本番環境）

### サーバー構成

| サーバー種別 | 役割 | スペック（推奨） | 台数 |
| --- | --- | --- | --- |
| Webサーバー（Rails） | HTTPリクエスト処理、WebSocket接続 | 2 vCPU / 4GB RAM以上 | 1台以上（水平スケール可能） |
| Workerサーバー（Sidekiq） | バックグラウンドジョブ処理 | 2 vCPU / 4GB RAM以上、メモリ上限1.2GB | 1台以上 |
| DBサーバー（PostgreSQL） | データ永続化 | 4 vCPU / 8GB RAM以上 | 1台（レプリカ構成可能） |
| Redisサーバー | キャッシュ、キュー、PubSub | 2 vCPU / 2GB RAM以上 | 1台（Sentinel構成可能） |
| Nginxサーバー | リバースプロキシ、SSL終端 | 1 vCPU / 1GB RAM | 1台以上 |

### ネットワーク構成

```
[Internet]
    |
    | HTTPS (443)
    v
[Nginx / Load Balancer]
    |
    +-- HTTP (3000) --> [Rails Web Server]
    |                        |
    |                        +-- TCP (5432) --> [PostgreSQL]
    |                        |
    |                        +-- TCP (6379) --> [Redis]
    |
    +-- [Sidekiq Worker]
             |
             +-- TCP (5432) --> [PostgreSQL]
             |
             +-- TCP (6379) --> [Redis]
```

#### ポート構成

| ポート | プロトコル | 用途 |
| --- | --- | --- |
| 80 | HTTP | HTTPSへのリダイレクト |
| 443 | HTTPS | Webアプリケーション（SSL終端） |
| 3000 | HTTP | Railsアプリケーション（内部） |
| 3036 | HTTP | Vite開発サーバー（開発環境のみ） |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
| 1025/8025 | TCP | Mailhog（開発環境のみ） |

## ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Ruby | 3.4.4 | アプリケーション言語 |
| Rails | 7.1.x | Webフレームワーク |
| Node.js | 24.13.0 | フロントエンドビルド |
| pnpm | 10.2.0 | パッケージマネージャー |
| PostgreSQL | 16（pgvector） | メインデータベース |
| Redis | Alpine版（最新） | キャッシュ/キュー |
| Nginx | 1.x | リバースプロキシ |
| Puma | 最新 | アプリケーションサーバー |
| Sidekiq | 7.3.1以上 | バックグラウンドジョブ |
| Sidekiq-cron | 1.12.0以上 | 定期ジョブスケジューラー |
| Vite | 最新 | フロントエンドビルドツール |

## 外部サービス連携

| サービス名 | 用途 | 接続方式 |
| --- | --- | --- |
| Amazon S3 | ファイルストレージ | AWS SDK (HTTPS) |
| Google Cloud Storage | ファイルストレージ（代替） | GCS SDK (HTTPS) |
| Azure Blob Storage | ファイルストレージ（代替） | Azure SDK (HTTPS) |
| S3互換ストレージ | ファイルストレージ（DigitalOcean Spaces, Minio等） | S3 API (HTTPS) |
| OpenSearch/Elasticsearch | 全文検索（Searchkick） | REST API (HTTPS) |
| Facebook Messenger API | チャネル連携 | Webhook/REST API |
| Twitter API | チャネル連携 | OAuth/REST API |
| Twilio | SMS/電話連携 | REST API |
| LINE Bot API | チャネル連携 | Webhook/REST API |
| Slack API | チャネル連携 | OAuth/REST API |
| Google Dialogflow | AIチャットボット | gRPC |
| Google Translate | 翻訳機能 | REST API |
| OpenAI API | AI機能 | REST API |
| Stripe | 決済処理 | REST API/Webhook |
| SMTP サーバー | メール送信 | SMTP |
| Sentry | エラー監視 | SDK (HTTPS) |
| New Relic | APM | エージェント |
| Datadog | APM/監視 | エージェント |
| Elastic APM | APM | エージェント |
| Scout APM | APM | エージェント |
| FCM (Firebase Cloud Messaging) | プッシュ通知 | REST API |
| VAPID (Web Push) | Webプッシュ通知 | Web Push Protocol |

## スケーリング設計

### 水平スケーリング

| コンポーネント | スケーリング方式 | 備考 |
| --- | --- | --- |
| Rails Web | 水平スケール可能 | ロードバランサー経由でリクエスト分散 |
| Sidekiq Worker | 水平スケール可能 | 複数プロセス/コンテナで並列処理 |
| PostgreSQL | 読み取りレプリカ追加可能 | マスター1台、レプリカn台構成 |
| Redis | Sentinel構成可能 | 高可用性構成対応 |

### 垂直スケーリング

- **Sidekiq同時実行数**: `SIDEKIQ_CONCURRENCY` 環境変数で設定（デフォルト: 10）
- **Railsスレッド数**: `RAILS_MAX_THREADS` 環境変数で設定（デフォルト: 5）
- **DBコネクションプール**: Sidekiqサーバーは `SIDEKIQ_CONCURRENCY`、Webサーバーは `RAILS_MAX_THREADS` に基づく

### Sidekiqキュー設計

優先度順のキュー構成:

1. `critical` - 最優先ジョブ
2. `high` - 高優先度ジョブ
3. `medium` - 中優先度ジョブ
4. `default` - 標準ジョブ
5. `mailers` - メール送信
6. `action_mailbox_routing` - 受信メール処理
7. `low` - 低優先度ジョブ
8. `scheduled_jobs` - 定期実行ジョブ
9. `deferred` - 遅延ジョブ
10. `purgable` - 削除可能ジョブ
11. `housekeeping` - メンテナンスジョブ
12. `async_database_migration` - 非同期DBマイグレーション
13. `bulk_reindex_low` - 大量インデックス再構築
14. `active_storage_analysis` - ファイル解析
15. `active_storage_purge` - ファイル削除
16. `action_mailbox_incineration` - メール削除

## 可用性設計

### Redis高可用性（Sentinel構成）

```
環境変数:
- REDIS_SENTINELS: host1:port1,host2:port2
- REDIS_SENTINEL_MASTER_NAME: mymaster（デフォルト）
- REDIS_SENTINEL_PASSWORD: (オプション)
```

### アプリケーション再起動設計

- Systemdによるプロセス管理（`Restart=always`）
- Dockerコンテナの`restart: always`ポリシー
- Sidekiqワーカーのメモリ上限: 1.2GB（OOMPolicy: stop）

### タイムアウト設計

- PostgreSQL Statement Timeout: 14秒（`POSTGRES_STATEMENT_TIMEOUT`で変更可能）
- Redis Timeout: 1秒
- Nginx Proxy Read Timeout: 36000秒（WebSocket対応）
- Rack Timeout: 本番環境のみ有効

## バックアップ設計

| 対象 | 方式 | 頻度 | 保持期間 |
| --- | --- | --- | --- |
| PostgreSQL | pg_dump / 継続的アーカイブ | 日次以上推奨 | 運用ポリシーによる |
| Redis | RDB/AOF永続化 | 設定による | 運用ポリシーによる |
| ファイルストレージ | S3/GCS/Azureの冗長化機能 | リアルタイム | 運用ポリシーによる |
| アプリケーションログ | ログローテーション | 日次 | 500行（LOG_SIZE環境変数） |

### ボリュームマウント（Docker構成）

| ボリューム名 | 用途 |
| --- | --- |
| postgres_data / postgres | PostgreSQLデータ |
| redis_data / redis | Redisデータ |
| storage_data | ActiveStorageファイル（ローカルストレージ時） |

## 監視設計

### APM・エラー監視（選択式）

| サービス | 環境変数 |
| --- | --- |
| Sentry | `SENTRY_DSN` |
| New Relic | `NEW_RELIC_LICENSE_KEY` |
| Datadog | `DD_TRACE_AGENT_URL` |
| Elastic APM | `ELASTIC_APM_SERVER_URL`, `ELASTIC_APM_SECRET_TOKEN` |
| Scout APM | `SCOUT_KEY`, `SCOUT_NAME`, `SCOUT_MONITOR` |

### ログ設計

```
環境変数:
- RAILS_LOG_TO_STDOUT: true（標準出力へ出力）
- LOG_LEVEL: info（デフォルト）
- LOG_SIZE: 500（ログサイズ上限）
- LOGRAGE_ENABLED: true（構造化ログ有効化）
```

Sidekiq本番環境ではJSON形式のログを出力。

### レート制限（Rack Attack）

```
環境変数:
- ENABLE_RACK_ATTACK: true（本番環境デフォルト）
- RACK_ATTACK_LIMIT: 3000（1分あたりのリクエスト上限）
- RACK_ATTACK_ALLOWED_IPS: 信頼済みIPリスト
```

主なレート制限:
- 全リクエスト: 3000/分
- ログイン試行: 5回/5分（IP）、10回/15分（メール）
- パスワードリセット: 5回/30分（IP）、5回/1時間（メール）
- MFA認証: 5回/分（IP）
- ウィジェットAPI: 6回/12時間（会話作成）

### 定期ジョブ（Sidekiq-cron）

| ジョブ名 | 実行間隔 | 用途 |
| --- | --- | --- |
| internal_check_new_versions_job | 毎日12:00 | 新バージョンチェック |
| trigger_scheduled_items_job | 5分毎 | スケジュール済みアイテム処理 |
| trigger_imap_email_inboxes_job | 1分毎 | IMAPメール取得 |
| remove_stale_contact_inboxes_job | 毎日22:30 | 古いコンタクト受信トレイ削除 |
| remove_stale_redis_keys_job | 毎日22:30 | 古いRedisキー削除 |
| process_stale_contacts_job | 毎日04:30 | 古いコンタクト処理 |
| delete_accounts_job | 毎日01:00 | 削除予定アカウント処理 |
| bulk_auto_assignment_job | 15分毎 | 自動割り当て処理 |
| periodic_assignment_job | 30分毎 | 定期割り当て処理 |
| remove_old_notification_job | 毎日22:30 | 古い通知削除（1ヶ月以上、300件/ユーザー上限） |
| remove_orphan_conversations_job | 12時間毎 | 孤立会話削除 |

### ヘルスチェック

- `/health` エンドポイント: Rack Attackスロットリングから除外
- Sidekiq Alive: Sidekiqプロセスのヘルスチェック

## セキュリティ設計

### SSL/TLS

- Let's Encrypt証明書使用（Nginx設定）
- TLSv1.2/TLSv1.3対応
- HSTS有効（max-age: 31536000）
- `FORCE_SSL`環境変数でSSL強制可能

### 認証・認可

- Devise + DeviseTokenAuth: ユーザー認証
- Devise Two-Factor: 二要素認証（MFA）
- JWT: API認証トークン
- Pundit: 権限管理

### シークレット管理

- `SECRET_KEY_BASE`: Cookieセキュリティ
- Active Record Encryption Keys: MFA/2FAデータ暗号化

## デプロイメント構成

### Docker構成（推奨）

#### 本番環境（docker-compose.production.yaml）

```yaml
services:
  rails:      # Webアプリケーション（ポート3000、localhost限定）
  sidekiq:    # バックグラウンドワーカー
  postgres:   # データベース（pgvector/pgvector:pg16）
  redis:      # キャッシュ/キュー
```

#### 開発環境（docker-compose.yaml）

```yaml
services:
  rails:      # Webアプリケーション
  sidekiq:    # バックグラウンドワーカー
  vite:       # フロントエンド開発サーバー
  postgres:   # データベース
  redis:      # キャッシュ/キュー
  mailhog:    # メールテスト
```

### Systemd構成（ベアメタル/VM）

- `chatwoot-web.1.service`: Railsサーバー
- `chatwoot-worker.1.service`: Sidekiqワーカー
- `chatwoot.target`: サービスグループ

### Heroku構成（Procfile）

```
release: bundle exec rails db:chatwoot_prepare
web: bundle exec rails server
worker: bundle exec sidekiq
```

## 備考

### 環境変数一覧（主要）

| 変数名 | 説明 | デフォルト |
| --- | --- | --- |
| SECRET_KEY_BASE | アプリケーションシークレット | （必須） |
| FRONTEND_URL | フロントエンドURL | http://0.0.0.0:3000 |
| REDIS_URL | Redis接続URL | redis://127.0.0.1:6379 |
| REDIS_PASSWORD | Redisパスワード | （空） |
| POSTGRES_HOST | PostgreSQLホスト | localhost |
| POSTGRES_USERNAME | PostgreSQLユーザー | postgres |
| POSTGRES_PASSWORD | PostgreSQLパスワード | （空） |
| POSTGRES_DATABASE | データベース名 | chatwoot_production |
| RAILS_ENV | Rails環境 | development |
| RAILS_MAX_THREADS | Railsスレッド数 | 5 |
| SIDEKIQ_CONCURRENCY | Sidekiq同時実行数 | 10 |
| ACTIVE_STORAGE_SERVICE | ストレージサービス | local |

### Enterprise版について

- `enterprise/`ディレクトリにEnterprise専用機能が配置
- OSS版の機能を`prepend_mod_with`等で拡張
- 本設計書はOSS版の構成を記載

### 参考資料

- Chatwoot公式ドキュメント: https://www.chatwoot.com/docs/
- Docker Hub: chatwoot/chatwoot
- GitHub Container Registry: ghcr.io/chatwoot/chatwoot_codespace
