用途:在浏览器里点按钮切换 qwen36 / qwen3-2507 / glm47 三个模型,不需要打开终端敲命令。 架构:一个极简 Python 网页服务,打包成 Docker 容器,通过挂载 docker.sock 调用宿主机的 docker compose 来实际切换模型。
第一步:连上NAS的命令行
两种方式选一种:
方式A(已配过SSH) 在你的电脑(不是NAS本身)打开终端/CMD:
ssh 你的用户名@192.168.0.188
方式B(没配过SSH,更简单) 登录fnOS网页管理界面 → 找"终端"/"Shell"类应用,直接在网页里打开。
✅ 确认标准:提示符变成 你的用户名@主机名:~$。
第二步:创建项目目录和三个文件
mkdir -p /vol3/1000/docker/llama/switch-panel
cd /vol3/1000/docker/llama/switch-panel
cat > app.py << 'EOF'
from http.server import HTTPServer, BaseHTTPRequestHandler
import subprocess
import urllib.parse
MODELS = ["qwen36", "qwen3-2507", "glm47"]
SCRIPT = "/vol3/1000/docker/llama/switch-model.sh"
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
parsed = urllib.parse.urlparse(self.path)
if parsed.path == "/switch":
qs = urllib.parse.parse_qs(parsed.query)
model = qs.get("model", [""])[0]
if model in MODELS:
subprocess.Popen(["bash", SCRIPT, model])
self.send_response(200)
self.send_header("Content-type", "text/html; charset=utf-8")
self.end_headers()
self.wfile.write(f"<h2>正在切换到 {model} ...</h2><a href='/'>返回</a>".encode())
return
self.send_response(200)
self.send_header("Content-type", "text/html; charset=utf-8")
self.end_headers()
buttons = "".join(
f'<a href="/switch?model={m}"><button style="font-size:24px;padding:20px;margin:10px;width:250px">{m}</button></a><br>'
for m in MODELS
)
self.wfile.write(f"<html><body style='text-align:center;margin-top:100px'><h1>模型切换面板</h1>{buttons}</body></html>".encode())
HTTPServer(("0.0.0.0", 9000), Handler).serve_forever()
EOF
cat > Dockerfile << 'EOF'
FROM python:3.11-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl gnupg \
&& install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \
&& chmod a+r /etc/apt/keyrings/docker.asc \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
> /etc/apt/sources.list.d/docker.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends docker-ce-cli docker-compose-plugin \
&& rm -rf /var/lib/apt/lists/*
COPY app.py /app.py
CMD ["python3", "/app.py"]
EOF
cat > docker-compose.yml << 'EOF'
services:
switch-panel:
build: .
container_name: switch-panel
restart: unless-stopped
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /vol3/1000/docker/llama:/vol3/1000/docker/llama
entrypoint: ["python3", "/app.py"]
EOF
这三个文件分别在做什么:
app.py:网页服务本体,收到按钮点击后调用switch-model.shDockerfile:给python镜像装上docker命令行客户端(默认镜像里没有)docker-compose.yml:定义容器怎么跑,关键是两个挂载:docker.sock→ 让容器内的docker命令能指挥宿主机/vol3/1000/docker/llama整个目录 → 因为switch-model.sh里会cd到这个目录执行docker compose stop/up,必须能看到这里的docker-compose.yml
✅ 确认标准:
ls /vol3/1000/docker/llama/switch-panel
应该看到 app.py、Dockerfile、docker-compose.yml 三个文件。
第三步:构建并启动容器
cd /vol3/1000/docker/llama/switch-panel
docker compose up -d --build
第一次会花点时间装docker-cli,耐心等。
✅ 确认标准:
docker ps --filter "name=switch-panel"
状态应为 Up。
如果失败,先看日志:
docker logs switch-panel
第四步:浏览器测试
同一局域网下,打开浏览器访问:
http://192.168.0.188:9000
(IP换成你NAS实际IP)
✅ 确认标准:看到"模型切换面板"标题和三个按钮,点一个后跳转显示"正在切换到 xxx ...",几秒后用 docker ps --filter "name=llama-" 能看到对应模型容器已经切换。
打不开的话:去fnOS控制面板的防火墙设置里放行9000端口。
点击后无反应/报错的话:
docker logs switch-panel
把报错内容发出来看,常见原因是docker.sock权限问题。
第五步:开机自启动
不需要额外配置。docker-compose.yml 里的 restart: unless-stopped 已经保证:
NAS重启后,只要Docker服务本身启动,这个容器会自动跟着起来
容器意外崩溃也会自动重启
第六步:加到桌面(PWA效果)
在NAS桌面浏览器或手机浏览器打开 http://192.168.0.188:9000,用浏览器菜单里的"添加到主屏幕",桌面/主屏幕上就会出现一个图标,点开直接是三个按钮的面板。
安全提示
这个方案给容器挂载了 docker.sock,意味着它对整台NAS上所有Docker容器都有控制权限,不只是那三个模型。同时目前网页没有任何身份验证,同一局域网内任何设备都能访问 9000 端口触发切换。
如果你的家庭网络本身可信,先这么用没问题;如果想加一层保护,可以后续在 app.py 里加一个简单的URL token校验(比如访问链接要带 ?token=xxxx 才生效),或者干脆不做端口映射,只在NAS本机内部访问。
常用维护命令备忘
# 查看容器状态
docker ps --filter "name=switch-panel"
# 查看日志
docker logs switch-panel
# 重启容器
cd /vol3/1000/docker/llama/switch-panel && docker compose restart
# 修改app.py后重新构建生效
cd /vol3/1000/docker/llama/switch-panel && docker compose up -d --build
# 彻底停止并删除容器
cd /vol3/1000/docker/llama/switch-panel && docker compose down
评论区