0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OllamaサーバーにOpen WebUIを"Dockerを使わずに"追加してTailscale経由でスマホから使えるようにする

0
Posted at

はじめに

前回の記事で、自宅のWindows PCをOllamaサーバー化し、Tailscale経由で外出先から安全にアクセスできるようにしました。ただ、あのままだと curl でAPIを叩く以外に使い道が無く、普段使いとしての実用性はイマイチです。

Ollama公式アプリには2025年にChatGPTライクなチャットUIが搭載されましたが、これはそのPC上で動いているOllamaにしか繋がらないローカル専用UIで、スマホから使うことはできません。外出先からチャットUIで使いたい場合は、Open WebUIというOSSのフロントエンドをサーバー側にもう一つ立てるのが定番です。

Open WebUIは公式にDockerでの配布が主流ですが、今回はあえてDocker Desktopを使わず、pip配布版をネイティブのWindowsプロセスとして動かす方法を紹介します。Docker Desktop(WSL2バックエンド)はWindows環境だと癖が強く、ログインセッション前提のアプリなのでサーバー運用にも向きません。pip版ならOllamaの OLLAMA_HOST と同じ発想で、Open WebUI自体をTailscaleのIPだけに直接バインドできるので、素直な構成にできます。

この記事では、前回と同じOllamaサーバーPCに、Dockerを使わずOpen WebUIを追加し、Ollamaと同じくTailscale経由でしか届かない構成を作ります。

前提環境

  • Ollamaサーバー: 前回の記事で構成したWindows11 PC(OLLAMA_HOSTをTailscale IPにbind済み、ファイアウォールも11434番をTailscaleのCIDRに絞り込み済み)
  • Python: 3.11または3.12が必要です(2026年時点のOpen WebUIは3.13には非対応)。既に3.13など別バージョンが入っていても、後述の方法で共存できます

Step 0. OLLAMA_HOSTの設定を確認する

Dockerを使わないので、以前の記事のようにOllama自体もTailscaleの特定IPだけにバインドしておけば十分です(Docker Desktop特有の「host.docker.internal経由だと特定IPバインドに届かない」問題が発生しないため)。

もし何らかの理由で OLLAMA_HOST を 0.0.0.0 に変更していた場合は、元のTailscale IP限定バインドに戻しておきます。

  1. Win + R → sysdm.cpl → 「詳細設定」タブ → 「環境変数」
  2. システム環境変数の OLLAMA_HOST を編集
  3. 変数値を <TAILSCALE_IP>:11434 に変更(TAILSCAl)
  4. OKで保存し、Ollamaを再起動(タスクトレイのOllamaアイコンを右クリック→終了してから再度起動)

Step 1. Python 3.12を用意する

通常のPowerShellで、インストール済みのPythonバージョンを確認します。

py -0

一覧に 3.12 が無い場合は、python.orgから3.12系の最新版インストーラーをダウンロードしてインストールしてください。オプションはデフォルトのままで構いません(「Add python.exe to PATH」はチェックしなくてもOKです。py ランチャー経由でバージョンを指定するので困りません)。

既に3.12がある場合はこのステップは不要です。


Step 2. 仮想環境を作ってOpen WebUIをインストールする

既存のPython環境を汚さないよう、専用の仮想環境を作ります。場所はお好みのドライブで構いません(以下は例)。

py -3.12 -m venv K:\open-webui\venv
K:\open-webui\venv\Scripts\Activate.ps1

プロンプトの先頭に (venv) と表示されたら、そのまま以下を実行します。

pip install open-webui

依存パッケージが多いため、インストールには数分かかります。


Step 3. Open WebUIを起動する

(venv) が有効な状態のまま、まず作業フォルダを移動してから、環境変数を設定して起動します。

cd K:\open-webui
$env:OLLAMA_BASE_URL = "http://<TAILSCALE_IP>:11434"
$env:DATA_DIR = "K:\open-webui\data"
$env:CORS_ALLOW_ORIGIN = "http://<TAILSCALE_IP>:3000"
open-webui serve --host <TAILSCALE_IP> --port 3000
  • cd K:\open-webui: これを忘れると起動に失敗します。 PowerShellを開いた直後のカレントディレクトリ(C:\WINDOWS\system32など)は書き込み権限がなく、PermissionErrorで起動に失敗するため、必ず書き込み可能な作業フォルダに移動してから起動してください
  • --host <TAILSCALE_IP>: OllamaのOLLAMA_HOSTと同じ要領で、Open WebUI自体をTailscaleのIPだけにバインドします。これによりそもそも家庭内LANや他のネットワークからは届かない状態になります
  • OLLAMA_BASE_URL: 同じPC上のOllamaが待ち受けているTailscale IP宛に指定します。Dockerのような特殊な内部ホスト名(host.docker.internal)は不要で、素直にIPを書くだけです
  • DATA_DIR: チャット履歴やアカウント情報の保存先を明示的に指定しておきます(指定しないとカレントディレクトリ配下に作られるため、後述のタスクスケジューラ運用時に迷子にならないよう固定しておくのがおすすめです)
  • CORS_ALLOW_ORIGIN: 未設定だとデフォルトが *(全オリジン許可)になっており、起動時に WARNING: CORS_ALLOW_ORIGIN IS SET TO '*' - NOT RECOMMENDED FOR PRODUCTION DEPLOYMENTS. と警告が出ます。今回はフロントエンド・バックエンドとも同じ http://<TAILSCALE_IP>:3000 から配信されるので、この1つのオリジンだけを明示的に指定しておけば十分です

WEBUI_SECRET_KEY を明示的に設定しなかった場合、初回起動時に自動生成され、カレントディレクトリの .webui_secret_key ファイルに保存されます。再現性を持たせたい場合は、以前と同じように事前にランダムな文字列を生成して環境変数にセットしておいても構いません。

$env:WEBUI_SECRET_KEY = -join ((1..32) | % { '{0:x2}' -f (Get-Random -Maximum 256) })

起動後、同じPC上のブラウザで http://<TAILSCALE_IP>:3000 を開き、最初のアカウント登録画面が出れば成功です(--host を特定IPに絞っているため、localhost:3000 では開けません。これは正しい挙動です)。
image.png

ポイント(サインアップは最初の1人だけ): Open WebUIは最初にサインアップしたユーザーが自動的に管理者になり、それ以降は新規サインアップが自動的に無効化される仕様です。つまり、自分が最初に登録さえしてしまえば、後から知らない誰かが勝手にアカウントを作れる心配はありません。


Step 4. (任意)Windowsファイアウォールでも二重に絞る

--host でTailscaleのIPに直接バインドしているため、この時点で家庭内LANなど他の経路からは原理的に届きません。とはいえ、Ollamaのときと同じく念のためファイアウォールでも絞っておくと、万一の設定ミスに対する保険になります。管理者権限のPowerShellで実行します。

New-NetFirewallRule -DisplayName "OpenWebUI-Tailscale" -Direction Inbound -LocalPort 3000 -Protocol TCP -RemoteAddress 100.64.0.0/10 -Action Allow

Step 5. 動作確認

同じTailscaleアカウントでログインしたスマホなどから、ブラウザで

http://<TAILSCALE_IP>:3000

にアクセスし、Open WebUIのログイン画面が表示されれば成功です。作成したアカウントでログインし、モデルを選んでチャットが通ることを確認します。

image.png

ポイント(モデルの選び方): チャット画面上部にモデル選択欄があるので、そこでOllama側に既に ollama pull 済みのモデル名を入力・選択するだけでOKです。もしまだ何もpullしていない場合でも、そこにモデル名を入力するとOpen WebUI側からOllamaにダウンロードを指示してくれます。

Tailscaleに参加していない端末(自宅Wi-FiのみでTailscale未インストールの端末など)からも http://<TAILSCALE_IP>:3000 および http://<LAN_IP>:3000 へのアクセスを試し、どちらも繋がらないことを確認しておくと安心です。--host を特定IPに絞っている構成であれば、Dockerのときのような「別経路からうっかり公開されてしまう」心配は基本的にありません。


おまけ: ログイン不要で自動起動させる

Docker Desktopをやめた副次的なメリットとして、Open WebUIはただのネイティブなWindowsプロセスになったので、タスクスケジューラで比較的素直に自動起動を組めます。

まず、起動処理をまとめたスクリプトを作っておきます(K:\open-webui\start-openwebui.ps1)。

Set-Location K:\open-webui
$env:OLLAMA_BASE_URL = "http://<TAILSCALE_IP>:11434"
$env:DATA_DIR = "K:\open-webui\data"
$env:CORS_ALLOW_ORIGIN = "http://<TAILSCALE_IP>:3000"
K:\open-webui\venv\Scripts\open-webui.exe serve --host <TAILSCALE_IP> --port 3000

Step3と同じ理由で、Set-Location を入れて作業フォルダへ明示的に移動しています。

タスクスケジューラで新しいタスクを作成します。

  1. 「全般」タブ: 名前を入力し、「ユーザーがログオンしているかどうかにかかわらず実行する」を選択、「最上位の特権で実行する」にチェック
  2. 「トリガー」タブ: 新規 →「タスクの開始」を「スタートアップ時」に設定
  3. 「操作」タブ: 新規 → プログラム/スクリプトに powershell.exe、引数に以下を入力
    -WindowStyle Hidden -ExecutionPolicy Bypass -File "K:\open-webui\start-openwebui.ps1"
    

保存すればOKです。同じ考え方でOllama本体側もタスクスケジューラに登録しておけば、Windows Updateなどによる予期しない再起動後も、誰もサインインしなくてもOllama・Open WebUIの両方が自動的に復旧するようになります。


まとめ

  • Ollama公式アプリのチャットUIはローカル専用なので、リモートから使うにはOpen WebUIなどを別途用意する必要がある
  • Open WebUIはDockerだけでなくpip配布もされており、open-webui serve --host <IP> --port <PORT> でOllamaのOLLAMA_HOSTと同じ発想で特定IPに直接バインドできる
  • Docker Desktop(WSL2バックエンド)を避けることで、IPバインドの癖やログインセッション依存といった問題から解放される
  • ネイティブプロセスになったことで、タスクスケジューラを使った「ログイン不要の自動起動」も比較的素直に組める
  • Open WebUIには最初のサインアップだけを受け付けて以降は自動的にサインアップを閉じる、というログイン機能が最初から付いている

最初は『Docker Desktopのままログイン不要で自動起動できないか』といろいろ試行錯誤していたのですが、結局は素直にpipでネイティブプロセスとして動かしてしまう方が、シンプルで見通しの良い構成になりました。

Sources:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?