ローカルAIチャットボットを自作する:Docker ComposeでOllamaとOpen WebUIを構築する方法

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

午前2時のデータ漏洩事故と、AIを「ローカル」に移行した決断

すべては、チームのエンジニアがロジックの修正を依頼するために、AWSのAPIキーを含むコードを誤ってChatGPTに貼り付けてしまったことから始まりました。わずか15分後、セキュリティ部門から緊急アラートが発せられました。ChatGPTやClaudeのような「即席」のツールは非常に便利ですが、その代償として入力データに対する制御権を失います。その瞬間、ローカルLLM(大規模言語モデル)の構築は、単なる趣味の範疇ではなく、必須のセキュリティ要件であると確信しました。

私が管理している30以上のコンテナで構成される本番システムにおいて、隔離性は最優先事項です。そこで、Docker Compose上で動作するOllamaOpen WebUIの組み合わせを選択しました。このソリューションは、ネイティブインストールと比較してメンテナンスの手間を約40%削減できます。ローカルマシンのシステムをそのまま数分でサーバーに移行することも可能です。

なぜ直接インストール(ネイティブ)を避けるべきなのか?

Dockerを採用する前にいくつか方法を試しましたが、そこから得た教訓は以下の通りです:

  • ネイティブインストール (Binary): セットアップは速いですが、CUDAやPythonのライブラリ競合が非常に発生しやすいです。OSを一度アップデートするだけで、AIエンジン全体が即座に動作しなくなる可能性があります。
  • プライベートクラウド (AWS Bedrock): セキュリティは高いですが、維持コストが非常に高額です。継続的なクエリが発生する場合、月末の請求額が数千ドルに達することもあります。
  • Docker Compose: これが最適な選択肢です。すべてが綺麗にパッケージ化されています。NVIDIA GPUからCPU実行に切り替えたい、あるいはデータのバックアップを取りたい場合も、YAMLファイルとデータフォルダを操作するだけで完了します。

OllamaとOpen WebUIコンビの強力さ

Ollamaは、Llama 3.1、Mistral、Qwenなどのモデルを制御する「心臓部」の役割を果たします。一方、Open WebUIは洗練されたインターフェースを提供し、RAG(検索拡張生成)やプロフェッショナルなユーザー管理にも対応しています。この組み合わせにより、有料版のChatGPTに劣らない体験が可能になります。

最小ハードウェア構成

チャットボットを遅延なく高速に動作させるために、以下の準備が必要です:

  • Docker & Docker Compose: インストール済みで、安定して動作していること。
  • NVIDIA GPU: 最低8GBのVRAM(RTX 3060や4060など)を推奨します。8GB VRAMがあれば、7B〜8Bクラスのモデルを50〜70 tokens/sの速度で快適に動作させることができます。
  • NVIDIA Container Toolkit: Dockerがグラフィックボードのドライバーと通信するために必須のコンポーネントです。
# GPUドライバーの確認コマンド
nvidia-smi

Docker Composeによるクイックデプロイ

ネットワーク管理が困難になるため、docker runコマンドを個別に実行するのは避けましょう。代わりに、すべてをdocker-compose.yamlファイルにまとめて一元管理します。

local-aiディレクトリを作成し、設定ファイルに以下の内容を貼り付けます:

services:
  ollama:
    volumes:
      - ./ollama:/root/.ollama
    container_name: ollama
    pull_policy: always
    tty: true
    restart: unless-stopped
    image: ollama/ollama:latest
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    volumes:
      - ./open-webui:/app/backend/data
    depends_on:
      - ollama
    ports:
      - "3000:8080"
    environment:
      - 'OLLAMA_BASE_URL=http://ollama:11434'
      - 'WEBUI_SECRET_KEY=change_this_key_immediately'
    restart: unless-stopped

重要なパラメータの解説

  • Volume: ./ollamaフォルダをホストマシンにマウントすることで、コンテナをアップグレードしてもモデル(通常5GB〜40GB)を保持できます。
  • Deploy (GPU): ここでハードウェアのパワーを有効化します。CPUのみのマシンを使用している場合は、起動エラーを避けるためにdeployブロック全体を削除してください。
  • OLLAMA_BASE_URL: IPアドレスの代わりにサービス名ollamaを使用します。Dockerが2つのコンテナ間の内部トラフィックを自動的にルーティングします。

起動と実行

以下のコマンド1つでシステム全体を起動できます:

docker compose up -d

Dockerがイメージのプルを完了したら、http://localhost:3000にアクセスしてください。Open WebUIのインターフェースで以下の手順を実行します:

  1. 管理者アカウントを登録します(このデータは完全にあなたのマシン内に保存されます)。
  2. Settings > Modelsに移動し、llama3.1:8bと入力します。
  3. Pullをクリックします。100Mbpsの回線であれば、4.7GBのデータのダウンロードに約3〜5分かかります。

実践的なトラブルシューティング

運用中に遭遇しがちな3つの主な問題を紹介します:

1. GPUドライバーが見つからないエラー

ログにcould not select device driverと表示される場合、NVIDIA Container Toolkitがインストールされていません。Ubuntuで修正するには以下のコマンドを実行してください:

sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

2. チャットボットのレスポンスが極端に遅い

docker logs -f ollamaを確認してください。CPU使用率が100%なのにGPUがアイドル状態の場合、NVIDIAドライバーが古すぎる可能性があります。Ollamaは自動的にCPU実行(フォールバック)に切り替わり、速度が60 tokens/sから2〜3 tokens/sまで低下します。

3. メモリ不足(Out of Memory)

8Bモデルを安定して動作させるには、約5GBのVRAMが必要です。RTX 3060で70Bモデルを動かそうとすると、システムは即座にクラッシュします。解決策として、インテリジェンスを維持しつつ容量を削減できるQuantized (GGUF)版を優先的に使用してください。

おわりに

AIシステムを自らコントロールすることで、情報漏洩を心配することなく顧客の機密データを自信を持って扱うことができます。また、ハードウェア投資後の運用コストはほぼゼロです。企業に導入する場合は、クライアント端末とサーバー間の通信を保護するために、Nginxリバースプロキシの設定とSSLの有効化を忘れないでください。

Share: