Skip to content

Instantly share code, notes, and snippets.

@niratama
Last active September 5, 2026 15:06
Show Gist options
  • Select an option

  • Save niratama/02b8cc46924acd48422001167bf5acb7 to your computer and use it in GitHub Desktop.

Select an option

Save niratama/02b8cc46924acd48422001167bf5acb7 to your computer and use it in GitHub Desktop.
Windowsホスト側のOllama環境構築、ファイアウォール設定、WSL2上のDocker環境(コンテナ実行環境)のセットアップから、グローバルCLIによる自律エージェント運用までを一連の流れとしてまとめた完全ガイドです。

ローカルLLM × WSL2 × Docker サンドボックス完全構築ガイド

Windows 上で動作するローカル推論サーバー(Ollama)を WSL2 経由で安全に参照し、プロジェクトリポジトリを一切汚さない独立した Docker サンドボックス上で自律型 AI エージェント(Hermes Agent)を稼働させるための完全セットアップマニュアルです。


本環境の特徴

  • 初回ウィザードの完全自動スキップ: 極小マスター設定ファイル(config.yaml)を自動シードすることで、新規プロジェクトや空キャッシュ環境でも対話確認(プロバイダ/URL/モデル入力)なしに即座起動。
  • リポジトリへの完全不可侵(Non-intrusive): プロジェクト配下に除外ファイル(.gitignore)やスクリプトを一切配置せず、Git ツリーを本来の純粋な状態に維持。
  • ホスト原本コードの絶対保護: ホスト側のソースディレクトリはコンテナに直接マウントせず、キャッシュ配下の独立した Git ローカルクローン上で AI に作業させる。
  • 安全な差分レビュー&マージ: AI の作業完了後、コミットログや差分を吟味した上でワンタッチでホスト側ブランチへマージまたは破棄が可能。
  • パーミッション競合の完全排除: コンテナ内部の実行 UID/GID をホスト側の UID/GID へ自動同期させ、ファイルの所有権トラブル(UID 10000 混入)を根絶。

1. Windows ホスト環境のセットアップ(Ollama & Firewall)

Windows 側の Ollama は、デフォルトではローカル(127.0.0.1)からの接続しか受け付けません。WSL2 や Docker コンテナからのアクセスを通すため、バインドアドレスの変更と Windows Defender ファイアウォールの受信許可を設定します。

1-1. Ollama のリッスンアドレス変更

  1. スタートメニューで「環境変数」と検索し、「システム環境変数の編集」を選択。
  2. 「環境変数」ボタンをクリック。
  3. システム環境変数(またはユーザー環境変数)に以下を追加:
  • 変数名: OLLAMA_HOST
  • 変数値: 0.0.0.0:11434
  1. タスクバーの通知領域(トレイアイコン)にある Ollama アイコンを右クリックし、「Quit Ollama」で完全終了。
  2. スタートメニューから再度 Ollama を起動。

1-2. Windows Defender ファイアウォールの受信許可

WSL2 の仮想ネットワークからの通信がブロックされないよう、ポート 11434 の受信規則を追加します。

PowerShell(管理者として実行)で以下を実行:

New-NetFirewallRule -DisplayName "Ollama for WSL" `
  -Direction Inbound `
  -LocalPort 11434 `
  -Protocol TCP `
  -Action Allow

2. WSL2 側の Docker 環境セットアップ

スタンドアロンの Docker Engine を WSL2(Ubuntu)内で動かすセットアップ手順です(Docker Desktop で WSL 統合を使用している場合は本ステップは不要です)。

2-1. Docker Engine のインストール

WSL2 ターミナルで実行します。

# 必要パッケージのインストール
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg acl

# Docker公式GPGキーの追加
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# リポジトリの登録
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Dockerのインストール
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 現在のユーザーをdockerグループに追加
sudo usermod -aG docker $USER

※ 反映のため、一度 WSL ターミナルを閉じて入り直すか、newgrp docker を実行してください。

2-2. WSL2 からの疎通確認

WSL2 ターミナルから Windows ホスト側の Ollama へ通信できるか確認します。

curl -s http://127.0.0.1:11434/api/tags

利用可能なモデル一覧の JSON が返ってくれば、ネットワークとファイアウォール設定は正常です。


3. ディレクトリと極小マスター設定の作成

スクリプト配置先、共通設定、プロジェクトキャッシュ領域を作成し、ウィザードをスキップするための最小設定を配備します。

mkdir -p ~/.local/bin ~/.config/ai-sandbox ~/.cache/ai-sandbox

~/.local/bin が環境変数 PATH に含まれていない場合は、~/.bashrc に以下を追記してください。

export PATH="$HOME/.local/bin:$PATH"

極小マスター設定ファイル(~/.config/ai-sandbox/config.yaml

Hermes Agent のスキーマ(_config_version: 40)に完全適合させ、初回プロンプトをスキップするために必要な最小限の設定です。

cat << 'EOF' > ~/.config/ai-sandbox/config.yaml
_config_version: 40
model:
  default: gemma4:26b
  provider: custom
  base_url: http://localhost:11434/v1
  api_key: none
custom_providers:
  - name: Ollama Local
    base_url: http://localhost:11434/v1
    key_env: HERMES_CUSTOM_OLLAMA_API_KEY
    model: gemma4:26b
    models:
      gemma4:26b: {}
    models_discovered: true
EOF

4. グローバル CLI スクリプトの配備

プロジェクトディレクトリを汚さず、カレントディレクトリに対して外側から実行できる 2 つのコマンドを作成します。

4-1. 起動スクリプト: ~/.local/bin/hermes-run

  • プロジェクト原本を直接マウントせず、~/.cache/ai-sandbox/<プロジェクト>/worktree に独立した Git ローカルクローンを作成。
  • 新規プロジェクト初回起動時、~/.config/ai-sandbox/config.yaml を自動シードしてプロバイダ設定対話をスキップ。
  • コンテナ内ユーザーをホストの UID/GID に自動リマップ(HERMES_UID / HERMES_GID)し、ファイル所有権トラブルを根絶。
cat << 'EOF' > ~/.local/bin/hermes-run
#!/usr/bin/env bash
set -e

# 1. Git リポジトリ判定
PROJECT_DIR="$(git -C "$(pwd)" rev-parse --show-toplevel 2>/dev/null || true)"

if [ -z "${PROJECT_DIR}" ]; then
    echo "❌ エラー: カレントディレクトリ ($(pwd)) は Git リポジトリではありません。"
    exit 1
fi

PROJECT_NAME="$(basename "${PROJECT_DIR}")"
AI_BASE_DIR="${HOME}/.cache/ai-sandbox/${PROJECT_NAME}"
AI_DIR="${AI_BASE_DIR}/worktree"
DATA_DIR="${AI_BASE_DIR}/data"
GLOBAL_CONFIG_FILE="${HOME}/.config/ai-sandbox/config.yaml"
BRANCH_NAME="ai-sandbox"

DEFAULT_OLLAMA_URL="http://127.0.0.1:11434"
DEFAULT_MODEL="${HERMES_DEFAULT_MODEL:-gemma4:26b}"

cd "${PROJECT_DIR}"

if ! git rev-parse HEAD >/dev/null 2>&1; then
    echo "❌ エラー: コミットが1つも存在しません。初期コミットを作成してください。"
    exit 1
fi

# コミッター情報の取得 (AI作業者として識別)
RAW_GIT_NAME="$(git config user.name || true)"
HOST_GIT_NAME="${RAW_GIT_NAME% (AI)}"
HOST_GIT_EMAIL="$(git config user.email || true)"
GIT_AUTHOR_NAME="${HOST_GIT_NAME:-$(whoami)} (AI)"
GIT_AUTHOR_EMAIL="${HOST_GIT_EMAIL:-$(whoami)@$(hostname).local}"

mkdir -p "${DATA_DIR}"

# 2. 最小マスター設定の自動シード(新規プロジェクトでもセットアップを完全回避)
if [ ! -f "${DATA_DIR}/config.yaml" ] && [ -f "${GLOBAL_CONFIG_FILE}" ]; then
    cp "${GLOBAL_CONFIG_FILE}" "${DATA_DIR}/config.yaml"
fi

# モデル指定の動的切り替え(環境変数による指定がある場合)
if [ -n "${HERMES_DEFAULT_MODEL}" ] && [ -f "${DATA_DIR}/config.yaml" ]; then
    sed -i "s/default: .*/default: ${HERMES_DEFAULT_MODEL}/" "${DATA_DIR}/config.yaml"
fi

# 3. AI作業用クローンの検証と作成
if [ ! -d "${AI_DIR}/.git" ] || [ -f "${AI_DIR}/.git/objects/info/alternates" ]; then
    echo "📦 AI用ローカルクローンを作成しています: ${AI_DIR}"
    chmod -R u+w "${AI_DIR}" 2>/dev/null || true
    rm -rf "${AI_DIR}"
    git clone --no-hardlinks "${PROJECT_DIR}" "${AI_DIR}"
    cd "${AI_DIR}"
    git checkout -B "${BRANCH_NAME}"
    git config user.name "${GIT_AUTHOR_NAME}"
    git config user.email "${GIT_AUTHOR_EMAIL}"
    cd "${PROJECT_DIR}"
else
    git -C "${AI_DIR}" config user.name "${GIT_AUTHOR_NAME}"
    git -C "${AI_DIR}" config user.email "${GIT_AUTHOR_EMAIL}"
fi

echo "=== Hermes Agent Git Sandbox ==="
echo "Host Repository : ${PROJECT_DIR} (main)"
echo "AI Sandbox Dir  : ${AI_DIR} (${BRANCH_NAME})"
echo "Git Committer   : ${GIT_AUTHOR_NAME} <${GIT_AUTHOR_EMAIL}>"
echo "Host UID / GID  : $(id -u):$(id -g)"
echo "Ollama Endpoint : ${DEFAULT_OLLAMA_URL} (Model: ${DEFAULT_MODEL})"

if ! curl -s "${DEFAULT_OLLAMA_URL}/api/tags" > /dev/null; then
    echo "❌ エラー: WindowsホストのOllama (${DEFAULT_OLLAMA_URL}) に接続できません。"
    exit 1
fi
echo "✅ Ollama接続確認完了。"

# 4. コンテナ起動
docker run -it --rm \
  --name hermes-sandbox \
  --network host \
  --cap-drop=all \
  --cap-add=CHOWN \
  --cap-add=SETUID \
  --cap-add=SETGID \
  --cap-add=DAC_OVERRIDE \
  -e HERMES_UID="$(id -u)" \
  -e HERMES_GID="$(id -g)" \
  -e "GIT_CONFIG_PARAMETERS='safe.directory=*'" \
  -v "${DATA_DIR}:/opt/data:rw" \
  -v "${AI_DIR}:/opt/data/workspace:rw" \
  -w /opt/data/workspace \
  nousresearch/hermes-agent:latest \
  hermes
EOF

chmod +x ~/.local/bin/hermes-run

4-2. レビュー&マージスクリプト: ~/.local/bin/hermes-review

AI が作成したコミットや差分を吟味し、安全にホスト側の main ブランチへマージまたは破棄します。

cat << 'EOF' > ~/.local/bin/hermes-review
#!/usr/bin/env bash
set -e

# 1. ホスト側 Git リポジトリ判定
PROJECT_DIR="$(git -C "$(pwd)" rev-parse --show-toplevel 2>/dev/null || true)"

if [ -z "${PROJECT_DIR}" ]; then
    echo "❌ エラー: カレントディレクトリ ($(pwd)) は Git リポジトリ配下ではありません。"
    exit 1
fi

PROJECT_NAME="$(basename "${PROJECT_DIR}")"
AI_DIR="${HOME}/.cache/ai-sandbox/${PROJECT_NAME}/worktree"
BRANCH_NAME="ai-sandbox"

cd "${PROJECT_DIR}"

# 2. AI作業ディレクトリ及び .git の存在確認
if [ ! -d "${AI_DIR}/.git" ]; then
    echo "❌ エラー: AI作業環境 (${AI_DIR}) に有効な Git リポジトリが見つかりません。"
    echo "先に 'hermes-run' を実行して作業環境を生成してください。"
    exit 1
fi

# 3. AI側の未コミット変更チェック
if ! git -C "${AI_DIR}" diff --quiet 2>/dev/null || [ -n "$(git -C "${AI_DIR}" status --porcelain 2>/dev/null)" ]; then
    echo "⚠️  注意: AI作業環境に未コミットの変更が残っています。"
fi

# 4. AIリポジトリの最新HEADをローカルの ai-sandbox ブランチとして確実に取得
git fetch "${AI_DIR}" HEAD:"${BRANCH_NAME}" --force >/dev/null 2>&1 || true

echo "=== AI作業 (${BRANCH_NAME}) レビュー: ${PROJECT_NAME} ==="
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔍 main..${BRANCH_NAME} のコミットログ:"
LOG_OUTPUT="$(git log --oneline main..${BRANCH_NAME} 2>/dev/null || true)"
if [ -n "${LOG_OUTPUT}" ]; then
    echo "${LOG_OUTPUT}"
else
    echo "   (マージ対象の新しいコミットはありません)"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

show_diff() {
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "🔍 差分プレビュー (main vs ${BRANCH_NAME})"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    git diff --color=always main..${BRANCH_NAME}
    echo ""
}

# レビュー対話ループ
while true; do
    read -p "main ブランチにマージしますか? (y/N/d: 差分表示/r: 作業リセット): " ans
    case "$ans" in
        [dD]*)
            show_diff
            ;;
        [yY]*)
            if [ -z "${LOG_OUTPUT}" ]; then
                echo "マージするコミットがありません。"
                exit 0
            fi
            git merge "${BRANCH_NAME}"
            echo "✅ main に正常にマージされました。"

            # AI側の作業ツリーも最新の main に同期
            cd "${AI_DIR}"
            git fetch origin main >/dev/null 2>&1 || true
            git reset --hard origin/main 2>/dev/null || true
            cd "${PROJECT_DIR}"
            echo "🔄 AI作業ツリーを main と同期させました。"
            break
            ;;
        [rR]*)
            cd "${AI_DIR}"
            git fetch origin main >/dev/null 2>&1 || true
            git reset --hard origin/main 2>/dev/null || true
            git clean -fd 2>/dev/null || true
            cd "${PROJECT_DIR}"
            git branch -f "${BRANCH_NAME}" main 2>/dev/null || true
            echo "🧹 AI作業ブランチの変更を破棄し、main の状態に巻き戻しました。"
            break
            ;;
        [nN]*|"")
            echo "マージを中断しました。"
            exit 0
            ;;
        *)
            echo "y (マージ)、n (終了)、d (差分確認)、r (変更破棄) を選んでください。"
            ;;
    esac
done
EOF

chmod +x ~/.local/bin/hermes-review

5. 日常の開発ワークフロー

ステップ 1: エージェントの起動

任意の Git 管理されたプロジェクトディレクトリに移動してコマンドを実行します。

cd ~/projects/my-app
hermes-run

初回起動時・新規プロジェクト・キャッシュ消去後であってもプロバイダ確認ウィザードは表示されず、gemma4:26b がセットされた状態で即座にプロンプト(hermes>)が起動します。

※一時的に別モデルで起動したい場合は、実行時に環境変数で指定します。

HERMES_DEFAULT_MODEL="qwen2.5-coder:32b" hermes-run

ステップ 2: エージェントによる自律作業

プロンプト上で作業を指示します。エージェントは隔離された環境内でファイルの閲覧・編集・テスト実行・Git コミットまでを自律的に行います。

hermes> src/calc.js に割り算関数を追加して、テストをパスすることを確認してコミットしてください。

作業が完了したら exit でコンテナを終了します。

ステップ 3: 差分の確認とマージ

プロジェクトディレクトリでレビューコマンドを実行します。

hermes-review
  • d (diff): ホスト側の main と AI 側の変更差分をカラー表示
  • y (yes): 変更を承認し、main にマージ(AI 側クローンも同期)
  • r (reset): AI 側の変更を全破棄し、main の最新状態へロールバック
  • n (no): マージせずに終了(作業状態は保持)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment