#Docker構成(DBのみ)
AIコンポーネント(Ollama・FastAPI・Frontend)はホストで直接起動する。 DockerはDBの管理・永続化にのみ使用する。
#環境別docker-compose対応表
| ファイル | 用途 | DBポート | ChromaDBポート | ボリューム |
|---|---|---|---|---|
docker-compose.yml | 開発環境 | 5432 | 8001 | named volume(永続化) |
docker-compose.test.yml | テスト環境 | 5433 | 8002 | tmpfs(使い捨て・高速) |
docker-compose.prod.yml | 本番環境 | 5432 | 8001 | named volume(永続化) |
# docker-compose.yml(PostgreSQL・ChromaDBのみ・開発環境)
#
# ホスト環境: Mac Studio M4 Max 16コアCPU / 40コアGPU / 48GB / 1TB
# Docker Desktop メモリ割り当て推奨: 6〜8GB(DBのみ起動のため)
# AI コンポーネント(Ollama / FastAPI / Frontend)はホスト直接起動
# → Metal GPU(gemma3:27b: 30〜40 tok/s)・Metal MPS(Embedding / Reranker)を使用
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
# Mac Studio 48GB 環境向け PostgreSQL チューニング
command: >
postgres
-c shared_buffers=512MB
-c effective_cache_size=2GB
-c work_mem=16MB
-c max_connections=20
volumes:
- postgres_data:/var/lib/postgresql/data # named volume 必須(bind mountはI/O 10〜30倍遅化)
shm_size: '256m' # shared_buffers に必要な共有メモリ領域
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
chromadb:
image: chromadb/chroma:latest
volumes:
- chromadb_data:/chroma/data # named volume 必須
ports:
- "8001:8001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8001/api/v1/heartbeat"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
postgres_data: # ホストのDocker named volumeに保存(NASには置かない)
chromadb_data:# docker-compose.test.yml(テスト用・開発環境と別ポート・tmpfsで使い捨て)
services:
postgres-test:
image: postgres:16-alpine
environment:
POSTGRES_DB: company_rag_test
POSTGRES_USER: raguser
POSTGRES_PASSWORD: test_password # テスト専用・固定値でよい
ports:
- "5433:5432" # 開発環境の5432と衝突しない
tmpfs:
- /var/lib/postgresql/data # tmpfs使用(永続化不要・高速・テスト後消える)
healthcheck:
test: ["CMD-SHELL", "pg_isready -U raguser"]
interval: 5s
timeout: 3s
retries: 5
chromadb-test:
image: chromadb/chroma:latest
ports:
- "8002:8001" # 開発環境の8001と衝突しない
tmpfs:
- /chroma/data # tmpfs使用(永続化不要)
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8001/api/v1/heartbeat"]
# コンテナ内部ポートは8001(ホスト側は8002にマッピング・ヘルスチェックは内部から実行のため8001を使用)
interval: 5s
timeout: 3s
retries: 5
# volumesブロックなし(tmpfsを使用するため named volume 不要)#ホスト起動スクリプト(scripts/start-dev.sh)
#!/bin/bash
set -e
# 1. DockerでDB起動
docker-compose up -d
# 2. Ollamaをホスト起動(すでに起動中の場合はスキップ)
if ! pgrep -x "ollama" > /dev/null; then
ollama serve &
echo "Ollama started"
else
echo "Ollama already running"
fi
# 3. FastAPIをホスト起動(仮想環境アクティベート後)
cd backend
source .venv/bin/activate # or: source venv/bin/activate
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 &
# 4. Frontend起動の案内(別ターミナル推奨)
echo ""
echo "=== 別ターミナルで以下を実行してください ==="
echo "cd frontend && npm run dev"#テスト起動スクリプト(scripts/start-test.sh)
#!/bin/bash
set -e
# 1. テスト用DBを起動(開発DBとは別ポート・tmpfsで使い捨て)
docker-compose -f docker-compose.test.yml up -d
# 2. DBのヘルスチェックが通るまで待機
echo "Waiting for test DB to be ready..."
until docker-compose -f docker-compose.test.yml exec -T postgres-test pg_isready -U raguser; do
sleep 1
done
# 3. テスト用DBにAlembicマイグレーションを適用
cd backend
source .venv/bin/activate
DATABASE_URL=postgresql://raguser:test_password@localhost:5433/company_rag_test \
alembic upgrade head
# 4. pytestを実行(.env.testを使用)
pytest tests/ -v --cov=app --cov-report=term-missing
# 5. テスト用DBを停止・削除(tmpfsなので自動的にデータは消える)
cd ..
docker-compose -f docker-compose.test.yml down本番用 (docker-compose.prod.yml) の追加事項:
- Frontend: Nginx で静的ビルドを配信 + セキュリティヘッダー設定(
docker-compose.prod.yml内の Nginx サービスとして Docker 管理を推奨。docker-compose up一発起動と整合するため。ホスト直接起動も可だが管理が煩雑になる) - Backend: Gunicorn + Uvicorn workers(2〜4 workers推奨、ホスト直接起動)
- 全Dockerサービスにヘルスチェック設定
restart: unless-stopped全Dockerサービスに設定- バックアップ用コンテナ(定期的にpg_dump + ChromaDBデータをローカルボリュームへ)
Nginxセキュリティヘッダー(本番必須):
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;※ Mermaid.jsがSVGをインライン生成するため、CSPの
script-srcとstyle-srcは実装確認後に調整が必要
#環境変数一覧
#環境別ファイル対応
| ファイル | Git管理 | 用途 |
|---|---|---|
.env.example | ○(雛形) | 全変数の説明・空値の雛形 |
.env.test | ○(秘匿情報なし) | テスト環境のデフォルト値(テスト用DB接続先・固定SECRET_KEY) |
.env | ✗(.gitignore) | 開発環境の実際の値 |
.env.production | ✗(.gitignore) | 本番環境の値 |
#.env(開発環境)
# 環境識別(development 環境では CORS_ALLOWED_ORIGINS に "http://localhost:3000" またはワイルドカード "*" を設定可能)
ENVIRONMENT=development
# Database(ホスト直接起動のためlocalhost)
POSTGRES_DB=company_rag
POSTGRES_USER=raguser
POSTGRES_PASSWORD= # 必須・空白禁止(起動時チェックあり)
DATABASE_URL=postgresql://raguser:@localhost:5432/company_rag
# Auth
SECRET_KEY= # 必須・32文字以上・起動時に強度チェックあり
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60
REFRESH_TOKEN_EXPIRE_DAYS=7
# CORS(本番は実際のドメインを指定・"*"は開発環境のみ)
CORS_ALLOWED_ORIGINS=http://localhost:3000
# Ollama(ホスト直接起動)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=gemma3:27b
OLLAMA_TIMEOUT_SECONDS=120
# Embedding(バージョン固定でベクトル空間の変動を防ぐ)
EMBEDDING_MODEL=intfloat/multilingual-e5-large
EMBEDDING_MODEL_REVISION=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 固定コミットハッシュ
# ChromaDB(ホスト直接起動のためlocalhost)
CHROMA_HOST=localhost
CHROMA_PORT=8001
CHROMA_COLLECTION=company_documents
# File Storage(ホスト直接起動のため絶対パス or 相対パス)
UPLOAD_DIR=./uploads
MAX_UPLOAD_SIZE_MB=50
ALLOWED_EXTENSIONS=.pdf,.docx,.xlsx,.txt
# Hugging Face キャッシュ(ホストの ~/.cache/huggingface を使用)
HF_HOME=~/.cache/huggingface
# PyTorch MPS(Metal Performance Shaders)設定
# MPS非対応演算をCPUにフォールバックさせる(macOS必須)
PYTORCH_ENABLE_MPS_FALLBACK=1
# Rate Limiting(POST /chat)
CHAT_RATE_LIMIT_PER_MINUTE=10
# Frontend
VITE_API_BASE_URL=http://localhost:8000#.env.test(テスト環境・git管理可)
# テスト環境識別
ENVIRONMENT=test
# テスト用DB(docker-compose.test.ymlと対応・開発DBとは別)
POSTGRES_DB=company_rag_test
POSTGRES_USER=raguser
POSTGRES_PASSWORD=test_password
DATABASE_URL=postgresql://raguser:test_password@localhost:5433/company_rag_test
# Auth(テスト用固定値・強度チェックはskip)
SECRET_KEY=test-secret-key-for-testing-only-do-not-use-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60
REFRESH_TOKEN_EXPIRE_DAYS=7
# CORS(テスト時はテストクライアントのみ)
CORS_ALLOWED_ORIGINS=http://localhost:3000
# Ollama(テストではモックするため実際には使用しない)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=gemma3:27b
OLLAMA_TIMEOUT_SECONDS=10
# Embedding(テストではモックするため実際には使用しない)
EMBEDDING_MODEL=intfloat/multilingual-e5-large
EMBEDDING_MODEL_REVISION=
# ChromaDB(テスト用・docker-compose.test.ymlの8002ポートと対応)
CHROMA_HOST=localhost
CHROMA_PORT=8002
CHROMA_COLLECTION=company_documents_test
# File Storage(テスト用一時ディレクトリ)
UPLOAD_DIR=./test_uploads
MAX_UPLOAD_SIZE_MB=50
ALLOWED_EXTENSIONS=.pdf,.docx,.xlsx,.txt
# Rate Limiting(テストでは緩く設定)
CHAT_RATE_LIMIT_PER_MINUTE=1000
# Frontend
VITE_API_BASE_URL=http://localhost:8000起動時バリデーション(config.py):
SECRET_KEYが空・32文字未満・your-super-secretを含む場合は起動を拒否- 例外:
ENVIRONMENT=testの場合はこのチェックをスキップ(テスト用固定キーを許容)
- 例外:
POSTGRES_PASSWORDが空の場合は起動を拒否- 例外:
ENVIRONMENT=testの場合はスキップ
- 例外:
CORS_ALLOWED_ORIGINSが*かつENVIRONMENT=productionの場合は起動を拒否