自宅PCのローカルLLMを外出先のスマホから使う。Ollama+Open WebUI+WireCanal

自宅PCのローカルLLM(Ollama+gemma4)にOpen WebUIでチャット画面を付け、トンネル経由で安全に公開して外出先のスマホから使うまでの実測手順。DockerもWSLもポート開放も不要です。

自宅PCのローカルLLMを外出先のスマホから使う。Ollama+Open WebUI+WireCanal

こんにちは!

自宅のGPU入りPCでローカルLLMを動かしていると、外出先でふと「あれ、手元のモデルに聞きたい」という場面がやってきます。

家のPCには自分で選んだり、自分でチューニングしたモデルが載っていて、会話履歴の保存先も自分のPCの中にできる。

せっかく作った環境なので、スマホからも使いたくなります。

かといって、自宅ルーターのポートを開けて外へさらすのは怖い。

結論から言うと、

Windows PC 1台だけで、外出先のスマホから自宅のローカルLLMと日本語チャットできる状態

まで持っていけます。DockerもWSLも使いません。ポート開放もしません。

この記事では、Ollamaとgemma4でローカルLLMを動かし、Open WebUIでチャット画面を付けて、トンネルで公開し、スマホの実機から使うまでの手順を最初から最後まで書きます。

手順・コマンド・画面はすべて筆者が実際に動かして確認したものです。検証機はWindows 11 Pro+GeForce RTX 3090 Ti(24GB)ですが、モデルを選べば12GBクラスのGPUでも同じ構成が組めます。

なお、この記事は「自分ひとりで、家のPCのLLMを外から使う」までを扱います。

図1 自宅のローカルLLMをスマホから使う構成
図1 自宅のローカルLLMをスマホから使う構成

手順1: Ollamaを入れてgemma4をGPUで動かす

まず、LLMを動かすランタイムのOllamaを入れます。

Ollama公式サイトからOllamaSetup.exeをダウンロードして実行するだけです。ウィザードを進めれば入ります(筆者はサイレント導入 OllamaSetup.exe /VERYSILENT で入れました。動作確認したのはv0.32.6)。

GPUは自動認識されるので、CUDAの手動セットアップは要りません。

ひとつだけ先に決めておきたいのがモデルの置き場所です。既定ではCドライブのユーザーフォルダにモデルがたまっていきます。1モデルで10GB前後を平気で食うので、大きいドライブに逃がしたい場合はシステム環境変数で指定します。
わたしは、Dドライブを置き場にしました。

OLLAMA_MODELS = D:\qualiteg_examples\ollama-models

モデルは、ollamaのライブラリの人気上位から、日本語が自然で手元のGPUに収まるgemma4(ダウンロード9.6GB)を選びました。

ollama pull gemma4

取得できたら動作確認です。

> ollama run gemma4 "日本の首都は"
東京(とうきょう)です。

GPUに載っているかは ollama ps で見えます。

NAME             ID              SIZE      PROCESSOR    CONTEXT
gemma4:latest    c6eb396dbd59    3.4 GB    100% GPU     32768

PROCESSORが100% GPUになっていれば成功です。CPUに落ちていると応答が桁違いに遅くなるので、ここは必ず確認してください。なお、ダウンロードは9.6GBですが、筆者のOllama 0.32.6ではps上のSIZEが3.4GBと表示されました(加工せず実測のまま載せています)。

手順2: 「最初の1回だけ返事が来ない」を先に潰す

構築中にいちばん焦ったのがこれでした。

しばらく放置したあとに質問すると、画面が数十秒うんともすんとも言わない。壊れたのかと思ってログを見ると、推論自体は2.1秒で終わっていました。

犯人はOllamaの既定動作です。未使用のまま5分たつと、モデルをGPUから降ろします。次の質問が来た瞬間に9.6GBを積み直すので、その間ずっと無反応に見えるわけです。

外からスマホで使う用途だと「たまに開いて1問聞く」が典型パターンなので、毎回この再ロードを踏むことになります。システム環境変数で常駐させておきましょう。

OLLAMA_KEEP_ALIVE = -1

設定後にOllamaを再起動して ollama ps を見ると、UNTIL列がForeverになります。

NAME             ID              SIZE      PROCESSOR    CONTEXT    UNTIL
gemma4:latest    c6eb396dbd59    3.4 GB    100% GPU     32768      Forever

これで何時間放置しても最初の1問から即答します。GPUをゲームや学習にも使うPCなら、-1のかわりに 24h のような値で妥協点をさぐりましょう。

手順3: Open WebUIはpipで入る(Dockerは要らない)

チャット画面はOpen WebUIを使いました。

ChatGPTライクなUIで、Ollamaを自動で見つけてくれる定番のOSSです。

Open WebUIはpipインストールが公式にサポートされています。

Open WebUIがサポートするPythonは3.11と3.12で、3.13は未対応です
(公式の推奨は3.11。筆者はcondaで3.11.15の環境を作りました。venvでも同じです)。

pip install open-webui

依存パッケージが多いので数分かかります。入ったら、環境変数を2つ与えて起動します(動作確認したのはv0.11.0)。

$env:OLLAMA_BASE_URL = 'http://localhost:11434'
$env:DATA_DIR = 'D:\qualiteg_examples\open-webui-data'
open-webui serve --port 3000

OLLAMA_BASE_URLは手順1のOllama、DATA_DIRはユーザー情報やチャット履歴の置き場です。

筆者環境では起動から約35秒で http://localhost:3000/health{"status":true} を返しました。

ブラウザで http://localhost:3000 を開くと、最初のアカウント作成を求められます。ここで作る最初のアカウントが管理者になります。公開はまだ先ですが、癖として「公開する前に管理者登録を済ませる」を徹底してください。先に公開してしまうと、たまたまURLを踏んだ第三者が管理者になれてしまいますので注意しましょう。

手順4: 受信ポートを開けずに外へ公開する

ここからが本題です。localhost:3000を外出先のスマホから届く場所に出します。

外に出す方法はいくつかあります。

方法手軽さ気になる点
ルーターのポート開放+DDNS設定が多い自宅の受信ポートが常時さらされる
VPN(Tailscale等)手軽使う端末すべてにアプリ導入が必要
トンネル型(本記事)手軽中継サーバーを経由する

今回はトンネル型を使います。

自宅側からトンネル事業者へ張った外向きの接続だけで通信するので、自宅の受信ポートは1つも開きません。

この記事では、当社が開発・運営しているWireCanalで進めます。本記事の用途であれば無料プランで十分足ります。カード登録も不要です。

手順は3つだけです。

まず、WireCanalのダッシュボードでcanal(トンネルの公開口)を作ります。種類はHTTP、転送先に localhost:3000 を指定すると、公開URLが1本発行されます。

canal(トンネルの公開口)の詳細画面。公開URLと転送先が1対1で決まる

次に、自宅PCへAgentを入れます。セットアップガイド(wirecanal.com)のとおり、PowerShellで1行です(動作確認したAgentはv0.18.0です)。

irm https://download.wirecanal.com/install.ps1 | iex

ダッシュボードからwirecanal.json(接続設定)をダウンロードしてAgentと同じフォルダに置けば準備完了です。

最後に、AgentをWindowsサービスとして登録します。手動起動でも動きますが、サービスにしておくとPCを再起動しても勝手に復帰します。

.\wirecanal.exe service install -config wirecanal.json
wirecanal service install: service "wirecanal-agent" installed (auto start; restarts 5s after a failure)
wirecanal service install: service started.

これで公開URLにアクセスすると、自宅のOpen WebUIのログイン画面が表示されます。PCのブラウザで一度フルフロー(ログイン→質問→応答)を通して、動くことを確かめてから外に持ち出しましょう。

公開URL経由のPCブラウザでのチャット画面
公開URL経由でPCブラウザからgemma4とチャットしているところ

手順5: スマホから使う

あとは外出先のスマホで公開URLを開くだけです。

あらかじめ、canal詳細画面でcanalのURLのQRを表示させてスマホで読ませておくとURL入力の手間が省けて便利です

手順3で作ったアカウントでログインすると、家のPCで見ていたのと同じチャット画面がそのまま出ます。

iPhone実機でのチャット画面
iPhone実機。モバイル回線から自宅のgemma4が応答する

モバイル回線から、自宅のRTX 3090 Ti上のgemma4が日本語で答えてきます。

モデル本体とOpen WebUIの会話履歴の保存先は自宅のPCです(スマホとの通信そのものは、トンネルの中継サーバーを経由します。公開URLはHTTPSです)。

これで自分だけの専用LLMに外出先からアクセスできました

インターネット側に公開するときの安全の考え方

今回の構成では、Open WebUI自身のログインを門番にします。手順3で「公開すWireCanal側にもIP・国・時間帯といったアクセス保護が標準で付いているので、用途に合わせて併用してください。

canalはスマホブラウザからいつでも一時停止・再開ができるので、使うときだけ回線をひらき、使わない期間はcanalを止めておく、というのも簡単にできます。

本記事は「ポート開放なしで外から使う」ための構成例として読んでください。

常駐化していつでも使えるようにする

最後に、PCの再起動や再ログオンに耐える形にします。Agentは手順4でサービス化済みなので、残るはOllamaとOpen WebUIです。タスクスケジューラに「PC起動時」のタスクとして登録します(PowerShellを管理者で実行)。

$action   = New-ScheduledTaskAction -Execute 'powershell.exe' `
  -Argument '-NoProfile -ExecutionPolicy Bypass -File D:\qualiteg_examples\open-webui\run-open-webui.ps1'
$trigger  = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) `
  -RestartCount 5 -RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName 'openwebui-serve' -Action $action -Trigger $trigger `
  -User 'SYSTEM' -RunLevel Highest -Settings $settings

run-open-webui.ps1の中身は手順3の起動コマンドとほぼ同じですが、1か所だけ重要な違いがあります。SYSTEMで動くタスクはconda activateを通らないので、open-webuiは環境内の実行ファイルを絶対パスで指定します。

$env:OLLAMA_BASE_URL = 'http://localhost:11434'
$env:DATA_DIR = 'D:\qualiteg_examples\open-webui-data'
& 'C:\tools\Anaconda3\envs\openwebui\Scripts\open-webui.exe' serve --port 3000

ポイントは、実行時間の制限を無効にすること(既定の72時間で切られます)と、SYSTEMで動かしてログオンと切り離すことです。Ollama側も同じ型で ollama serve のタスクを作ります。こちらもollama.exeを絶対パスで指定してください(筆者環境では C:\Users\<ユーザー名>\AppData\Local\Programs\Ollama\ollama.exe)。通常のインストーラ版はログオン時の自動起動も入るので、二重起動にならないよう自動起動側は無効にしておきます。

もうひとつ注意点があります。SYSTEMタスクから起動するPowerShellスクリプトに日本語コメントを書くと、文字コードの解釈違い(BOM無しUTF-8をANSIとして読む)で動かないことがあります。スクリプトはASCIIだけで書くか、BOM付きUTF-8で保存してください。ここでも30分溶かしました。

まとめ: 家のGPUが、ポケットの中から使える

やったことを並べると、インストーラ1本、pip 1回、トンネル設定、いくつかの環境変数でした。大げさな仕掛けなしに、自宅のGPUマシンが「自分専用のLLMサーバー」になります。

最後に、今回の構成の勘所を置いておきます。

勘所設定
モデルをGPUに常駐させるOLLAMA_KEEP_ALIVE=-1
管理者の乗っ取りを防ぐ公開前に最初のアカウントを作る
再起動に耐えるAgentはサービス化・Ollama/Open WebUIは起動時タスク(絶対パス)

それでは、また次回、お会いしましょう!

出典・参考

関連記事

Read more

MCPサーバーの作り方 — 自作MCPサーバーをWeb版のChatGPT・Claudeから使えるようにする(後編)

MCPサーバーの作り方 — 自作MCPサーバーをWeb版のChatGPT・Claudeから使えるようにする(後編)

自作MCPサーバーをWeb版のChatGPT・Claudeから使えるようにする手順を、実際に接続した画面つきで解説します。localhostのサーバーに公開URLとOAuth認証を付け、コードを1行も変えずにブラウザのAIから売上データベースへ日本語で聞けるようにします。

By Qualiteg プロダクト開発部