curl
/ Postman 驗證外部可用# Linux / macOS
curl -sS https://ngrok.com/download | sudo bash
# 或用包管理器:sudo snap install ngrok
ngrok config add-authtoken <YOUR_NGROK_AUTHTOKEN>
在 ~/.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"
# 從 yml 啟動指定通道
ngrok start ollama
ngrok 會輸出類似:
Forwarding https://odd-sunset-1234.ngrok-free.app -> http://localhost:11434
這個 https://...ngrok...
就是外部入口。
(搭配你在 Day 11 的 Flask 小服務)
python app.py # 先啟動 Flask(0.0.0.0:5050)
ngrok start flask
/api/tags
# 若開了 Basic Auth 就要帶 -u user:pass123
curl -u user:pass123 https://odd-sunset-1234.ngrok-free.app/api/tags
看到模型列表(llama、gemma:4b…)就成功了。
/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
/ask
curl -u apiuser:apipass456 \
-H "Content-Type: application/json" \
-d '{"prompt":"用兩句話定義 RAG"}' \
https://<你的-flask-ngrok域名>/ask
basic_auth: [ user:pass ]
或 CLI -basic-auth
在 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" ...
用 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():
...
在 ngrok.yml
的 ip_restriction.allow_cidrs
中列出允許的來源;或直接只給信任對象使用。
不建議直接把 WebUI 對外開放(有管理功能)。如果要分享互動體驗,可以:
固定網域:升級 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 打開,方便追蹤用量與錯誤。
localhost:11434
/5050
能通。