iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0
AI & Data

「30 天打造 Discord AI 助手:結合本地 LLM 與 IoT 的智慧生活」系列 第 12

Day 12:整合 ngrok,將本地 Ollama Server 暴露至網路供他人試用

  • 分享至 

  • xImage
  •  

🎯 目標

  1. 安裝並設定 ngrok
  2. 對外公開 Ollama(11434)或 Flask(預設 5050)
  3. 加上最小存取保護(金鑰 / Basic Auth / 速率限制 / IP 白名單)
  4. curl / Postman 驗證外部可用

1) 安裝與基本設定

安裝 ngrok

# Linux / macOS
curl -sS https://ngrok.com/download | sudo bash
# 或用包管理器:sudo snap install ngrok

取得並設定 Authtoken

  1. 到 ngrok 官網註冊 → 取得 authtoken
  2. 設定到本機:
ngrok config add-authtoken <YOUR_NGROK_AUTHTOKEN>

建立 ngrok 設定檔(建議)

~/.config/ngrok/ngrok.yml(或 ~/.ngrok2/ngrok.yml)建立:

version: "2"
authtoken: <YOUR_NGROK_AUTHTOKEN>

# 預設全局設定(可選)
tunnels:
  ollama:
    addr: 11434
    proto: http
    # --- 基本保護 ---
    # 1) Basic Auth:瀏覽器 & curl 都能用
    # 注意:Basic Auth 只套在 HTTP 入口,API 訪問需帶 Authorization 標頭
    basic_auth:
      - user:pass123

    # 2) IP 白名單(可選):只允許某些 IP 訪問
    # ip_restriction:
    #   allow_cidrs:
    #     - 203.0.113.0/24
    #     - 198.51.100.10/32

    # 3) 速率限制(Edge 設定更細,這裡示意)
    # schemes: ["https"]  # 僅走 HTTPS
    # host_header: rewrite

  flask:
    addr: 5050
    proto: http
    basic_auth:
      - apiuser:apipass456

你也可以不寫到 yml,改用 CLI 參數臨時加:

ngrok http 11434 --basic-auth="user:pass123"


2) 對外公開服務

方式 A:公開 Ollama(11434)

# 從 yml 啟動指定通道
ngrok start ollama

ngrok 會輸出類似:

Forwarding  https://odd-sunset-1234.ngrok-free.app -> http://localhost:11434

這個 https://...ngrok... 就是外部入口。

方式 B:公開 Flask(5050)

(搭配你在 Day 11 的 Flask 小服務)

python app.py  # 先啟動 Flask(0.0.0.0:5050)
ngrok start flask


3) 從外網測試

測試 Ollama /api/tags

# 若開了 Basic Auth 就要帶 -u user:pass123
curl -u user:pass123 https://odd-sunset-1234.ngrok-free.app/api/tags

看到模型列表(llama、gemma:4b…)就成功了。

測試 Ollama /api/generate

curl -u user:pass123 \
  -H "Content-Type: application/json" \
  -d '{"model":"gemma:4b","prompt":"說三點 Docker 的好處","stream":false}' \
  https://odd-sunset-1234.ngrok-free.app/api/generate

測試 Flask /ask

curl -u apiuser:apipass456 \
  -H "Content-Type: application/json" \
  -d '{"prompt":"用兩句話定義 RAG"}' \
  https://<你的-flask-ngrok域名>/ask


4) 最小存取保護選項(擇一或並用)

A. Basic Auth(最簡單)

  • 在 ngrok yml 加 basic_auth: [ user:pass ] 或 CLI -basic-auth
  • 優點:0 成本、馬上可用
  • 缺點:同用戶共用帳密、無法細控配額

B. 自行加「API 金鑰」檢查(Flask 端)

在 Day 11 的 Flask 加上簡單 Header 檢查:

from flask import request, jsonify

API_KEY = "secret-token-xyz"

def require_key(func):
    def _wrap(*args, **kwargs):
        if request.headers.get("X-API-Key") != API_KEY:
            return jsonify({"error": "forbidden"}), 403
        return func(*args, **kwargs)
    _wrap.__name__ = func.__name__
    return _wrap

@app.post("/ask")
@require_key
def ask():
    ...

外部請求就必須帶:

curl -H "X-API-Key: secret-token-xyz" ...

C. 速率限制(Flask 端)

flask-limiter

pip install flask-limiter

from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(get_remote_address, app=app, default_limits=["60 per minute"])

@app.post("/ask")
@limiter.limit("20/minute")
def ask():
    ...

D. IP 白名單(ngrok 端)

ngrok.ymlip_restriction.allow_cidrs 中列出允許的來源;或直接只給信任對象使用。


5) 與 Open WebUI 的外網共用

不建議直接把 WebUI 對外開放(有管理功能)。如果要分享互動體驗,可以:

  1. 只公開 FlaskOllama API,給對方一個前端(你自己做的簡頁、或 Postman collection)
  2. 若一定要公開 WebUI,務必
    • 開啟 WebUI 平台的使用者註冊限制 / 管理員控管
    • 用 ngrok Basic Auth 先擋一層
    • 定期換密碼、關閉匿名註冊

6) 開發者實務小貼士

  • 固定網域:升級 ngrok 方案可以保留自訂子域,避免每次重開都換網址。

  • TCP 隧道:需要暴露非 HTTP/HTTPS(例如 SSH)的話,可用 ngrok tcp 22

  • CORS:若要給網頁前端直接打你的 Flask API,記得加 CORS 白名單:

    pip install flask-cors
    
    
    from flask_cors import CORS
    CORS(app, resources={r"/*": {"origins": ["https://你的前端網域"]}})
    
    
  • 日誌ngrok http 11434 --log=stdout 或把 Flask access log 打開,方便追蹤用量與錯誤。


7) 常見問題排查

  • 502 / 504:本地服務沒起來,或埠錯。確認 localhost:11434/5050 能通。
  • Basic Auth 無效:確認是掛在 ngrok 這層,不是你在本地反向代理的其它設定干擾。
  • 串流中斷:外部網路不穩或閾值限制;增加 Flask timeout、確保 SSE/串流路由不被代理攔截。
  • 速度變慢:ngrok 免費線路到遠端地區延遲高,改區域、升級方案或改用其他隧道工具(見下)。

8) ngrok 替代方案(可選)

  • Cloudflare Tunnel (cloudflared):免費、穩定、可綁自域名,較適合長期公開
  • Tailscale Funnel:基於 WireGuard 的私網 + 公網入口,團隊內共享超好用
  • LocalTunnel:超輕量,但較不穩定、功能少

上一篇
Day 11:使用 Python 連接 Ollama API,實現程式化呼叫模型
系列文
「30 天打造 Discord AI 助手:結合本地 LLM 與 IoT 的智慧生活」12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言