# Claude Code を Synology NAS の Docker で実行する

> docker-compose.yml: [claude-code/docker-compose.yml](claude-code/docker-compose.yml)

## 概要

Claude Code を Synology NAS 上の Docker コンテナで動かし、
match_12 プロジェクトのソースコードを参照して対話・自動タスクを実行します。

```
[Synology NAS]
├── /volume1/docker/match_12/       ← 既存の match_12 プロジェクト
└── /volume1/docker/claude-code/
    ├── docker-compose.yml
    ├── .env
    ├── tasks/                      ← タスク定義（プロンプト）
    ├── logs/                       ← 実行ログ
    └── scripts/
        └── run-task.sh             ← タスク実行スクリプト

[Claude Code コンテナ]
  └── /workspace/match_12  ← バインドマウント ← /volume1/docker/match_12
```

## 前提条件

- Synology NAS に **Container Manager** がインストール済み
- SSH アクセスが有効
- Anthropic API キー（`sk-ant-...`）
- NAS に十分なメモリ（4GB 以上推奨）
- Git の HTTPS トークン（PR 作成を行う場合）

## 1. ディレクトリ作成

```bash
sudo mkdir -p /volume1/docker/claude-code/{tasks,logs,scripts}
```

## 2. 環境変数の設定

```bash
cat > /volume1/docker/claude-code/.env << 'EOF'
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GH_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EOF

chmod 600 /volume1/docker/claude-code/.env
```

> `GH_TOKEN` は PR 自動作成に使用します。不要なら空で OK。
> GitHub → Settings → Developer settings → Personal access tokens で発行。

## 3. docker-compose.yml

Synology の Container Manager は BuildKit 非対応のため、公式イメージを使用し、
起動時に Claude Code をインストールします。

```bash
cat > /volume1/docker/claude-code/docker-compose.yml << 'COMPOSEOF'
services:
  claude-code:
    image: node:20-slim
    container_name: claude_code
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - GH_TOKEN=${GH_TOKEN}
      - DEVCONTAINER=true
      - NODE_OPTIONS=--max-old-space-size=4096
      - TZ=Asia/Tokyo
    volumes:
      # match_12 プロジェクトをワークスペースとしてマウント
      - /volume1/docker/match_12:/workspace/match_12
      # タスク・ログ・スクリプト
      - ./tasks:/tasks:ro
      - ./logs:/logs
      - ./scripts:/scripts:ro
      # Claude Code の設定を永続化
      - claude_config:/home/node/.claude
    working_dir: /workspace/match_12
    restart: unless-stopped
    # 初回起動時に Claude Code + 必要パッケージをインストールし、常駐
    command: >
      bash -c "
        apt-get update && apt-get install -y git curl jq sudo > /dev/null 2>&1 &&
        curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg
          | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null &&
        echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main'
          | tee /etc/apt/sources.list.d/github-cli.list > /dev/null &&
        apt-get update && apt-get install -y gh > /dev/null 2>&1 &&
        npm install -g @anthropic-ai/claude-code > /dev/null 2>&1 &&
        echo 'node ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers &&
        echo '✅ Claude Code ready' &&
        sleep infinity
      "

volumes:
  claude_config:
COMPOSEOF
```

> **ポイント**: `/volume1/docker/match_12` をコンテナの `/workspace/match_12` にバインドマウントしています。
> Claude Code からソースコードの読み書きが可能です。

## 4. 起動

```bash
cd /volume1/docker/claude-code
sudo docker compose up -d
```

初回起動時はパッケージのインストールに数分かかります。進捗を確認:

```bash
sudo docker compose logs -f claude-code
```

`✅ Claude Code ready` と表示されれば準備完了です。

## 5. 動作確認

### 対話モード

```bash
sudo docker exec -it claude_code bash
cd /workspace/match_12
claude
```

### ヘッドレス実行（単発）

```bash
sudo docker exec claude_code claude -p "match_12プロジェクトの概要を教えて" --dangerously-skip-permissions
```

## 6. タスク定義ファイル

タスクごとにプロンプトを `.md` ファイルで管理します。

### tasks/refactor.md（リファクタリング）

```bash
cat > /volume1/docker/claude-code/tasks/refactor.md << 'EOF'
以下のルールに従ってコードをリファクタリングしてください。

## 対象
- app/Http/Controllers/ 配下のコントローラー
- app/Models/ 配下のモデル

## ルール
- 1メソッド30行以内に分割
- 重複コードをトレイトまたはサービスクラスに抽出
- N+1クエリを修正
- 未使用の use 文を削除

## 制約
- 既存のテストが通ること
- 外部APIの呼び出し方法は変更しない
- データベーススキーマは変更しない

完了したら変更内容を日本語でまとめてください。
EOF
```

### tasks/review.md（コードレビュー）

```bash
cat > /volume1/docker/claude-code/tasks/review.md << 'EOF'
直近のコミットをレビューしてください。

## チェック項目
- セキュリティ脆弱性（SQLインジェクション、XSS、CSRF）
- パフォーマンス問題（N+1、不要なクエリ）
- エラーハンドリングの漏れ
- Laravel のベストプラクティスに沿っているか

結果を /logs/review-result.md に出力してください。
問題がなければ「問題なし」と記載してください。
EOF
```

### tasks/test.md（テスト生成）

```bash
cat > /volume1/docker/claude-code/tasks/test.md << 'EOF'
テストが不足しているコントローラーとモデルを特定し、
Feature テストを追加してください。

## ルール
- テストは SQLite（:memory:）を使用
- 既存テストの命名規則に合わせる
- 最低限 CRUD 操作のテストをカバー
- アサーションは具体的に（assertOk だけでなく assertJson 等）

完了したら php artisan test を実行して全テストがパスすることを確認してください。
EOF
```

## 7. タスク実行スクリプト

```bash
cat > /volume1/docker/claude-code/scripts/run-task.sh << 'SCRIPTEOF'
#!/bin/bash
# 使い方: run-task.sh <タスク名> [プロジェクト名] [--pr]
# 例:     run-task.sh refactor match_12 --pr

TASK_NAME="${1:?タスク名を指定してください（例: refactor, review, test）}"
PROJECT="${2:-match_12}"
CREATE_PR="${3}"

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/logs/${TASK_NAME}_${TIMESTAMP}.log"
BRANCH_NAME="claude/${TASK_NAME}_${TIMESTAMP}"

echo "=== Claude Code タスク実行 ===" | tee "$LOG_FILE"
echo "タスク: $TASK_NAME" | tee -a "$LOG_FILE"
echo "プロジェクト: $PROJECT" | tee -a "$LOG_FILE"
echo "開始: $(date)" | tee -a "$LOG_FILE"
echo "---" | tee -a "$LOG_FILE"

cd "/workspace/${PROJECT}" || exit 1

# 最新コードを取得
git fetch origin
git checkout main
git pull origin main

# 作業ブランチを作成
git checkout -b "$BRANCH_NAME"

# タスクのプロンプトを読み込んで実行
PROMPT=$(cat "/tasks/${TASK_NAME}.md")

claude -p "$PROMPT" --dangerously-skip-permissions \
  2>&1 | tee -a "$LOG_FILE"

# 変更がある場合のみコミット & PR
if [ -n "$(git status --porcelain)" ]; then
  git add -A
  git commit -m "claude(${TASK_NAME}): 自動${TASK_NAME} $(date +%Y-%m-%d)

Executed by Claude Code on Synology NAS (scheduled task)
Task: ${TASK_NAME}
"

  if [ "$CREATE_PR" = "--pr" ] && [ -n "$GH_TOKEN" ]; then
    git push origin "$BRANCH_NAME"
    gh pr create \
      --title "claude(${TASK_NAME}): 自動${TASK_NAME} $(date +%Y-%m-%d)" \
      --body "## 自動実行タスク: ${TASK_NAME}

Synology NAS のタスクスケジューラーにより自動実行されました。

🤖 Generated by Claude Code (scheduled task)" \
      --base main
    echo "PR を作成しました" | tee -a "$LOG_FILE"
  else
    echo "変更をコミットしました（ブランチ: $BRANCH_NAME）" | tee -a "$LOG_FILE"
  fi
else
  echo "変更なし" | tee -a "$LOG_FILE"
  git checkout main
  git branch -d "$BRANCH_NAME"
fi

echo "---" | tee -a "$LOG_FILE"
echo "終了: $(date)" | tee -a "$LOG_FILE"
SCRIPTEOF

chmod +x /volume1/docker/claude-code/scripts/run-task.sh
```

## 8. 手動でタスクを実行（動作確認）

```bash
# リファクタリング（コミットのみ）
sudo docker exec claude_code bash /scripts/run-task.sh refactor match_12

# リファクタリング（PR作成まで）
sudo docker exec claude_code bash /scripts/run-task.sh refactor match_12 --pr

# コードレビュー
sudo docker exec claude_code bash /scripts/run-task.sh review match_12
```

## 9. Synology タスクスケジューラーの設定

DSM の **コントロールパネル** → **タスクスケジューラー** で設定します。

1. **作成** → **予約タスク** → **ユーザー指定のスクリプト**
2. 設定:

| 項目 | 設定例 |
|------|--------|
| タスク名 | `Claude Code - リファクタリング` |
| ユーザー | `root` |
| 有効 | チェック |

3. **スケジュール** タブ:

| 項目 | 設定例 |
|------|--------|
| 実行日 | 毎週日曜日 |
| 時刻 | 03:00 |

4. **タスク設定** タブ → **ユーザー指定のスクリプト**:

```bash
docker exec claude_code bash /scripts/run-task.sh refactor match_12 --pr
```

### おすすめスケジュール例

| タスク | スケジュール | スクリプト |
|--------|-------------|-----------|
| リファクタリング | 毎週日曜 03:00 | `docker exec claude_code bash /scripts/run-task.sh refactor match_12 --pr` |
| コードレビュー | 毎日 06:00 | `docker exec claude_code bash /scripts/run-task.sh review match_12` |
| テスト生成 | 毎週水曜 03:00 | `docker exec claude_code bash /scripts/run-task.sh test match_12 --pr` |

## Git の設定

コンテナ起動後に Git ユーザー情報を設定してください:

```bash
sudo docker exec claude_code git config --global user.name "Claude Code Bot"
sudo docker exec claude_code git config --global user.email "claude-bot@example.com"
```

## 運用コマンド

```bash
cd /volume1/docker/claude-code

# コンテナの状態確認
sudo docker compose ps

# ログ確認
sudo docker compose logs -f claude-code

# 停止 / 再起動
sudo docker compose down
sudo docker compose restart

# Claude Code のバージョン確認
sudo docker exec claude_code claude --version

# Claude Code をアップデート（コンテナ再作成）
sudo docker compose down
sudo docker compose up -d
```

## カスタムタスクの追加

`tasks/` にファイルを追加するだけです:

```bash
cat > /volume1/docker/claude-code/tasks/security-audit.md << 'EOF'
セキュリティ監査を実施してください。

## チェック項目
- OWASP Top 10 に該当する脆弱性
- .env や認証情報のハードコード
- 依存パッケージの既知の脆弱性（composer audit）
- CORS / CSRF 設定の妥当性

結果を /logs/security-audit-result.md に出力してください。
EOF
```

実行:

```bash
sudo docker exec claude_code bash /scripts/run-task.sh security-audit match_12
```

## トラブルシューティング

### コンテナ起動後に Claude Code が使えない

初回起動時のインストールに数分かかります。ログで完了を確認:

```bash
sudo docker compose logs claude-code | grep "Claude Code ready"
```

### permission denied エラー

```bash
sudo chown -R 1000:1000 /volume1/docker/claude-code/logs
```

match_12 のソースに書き込みが必要な場合:

```bash
sudo chown -R 1000:1000 /volume1/docker/match_12
```

### Git push が失敗する

コンテナ内の Git 認証を確認:

```bash
sudo docker exec claude_code gh auth status
```

`GH_TOKEN` が `.env` に設定されていれば `gh` コマンド経由で認証されます。

### メモリ不足エラー

`docker-compose.yml` の `NODE_OPTIONS` を調整:

```yaml
- NODE_OPTIONS=--max-old-space-size=2048
```
