Sshwifty Docker Compose 部署指南:从零搭建 Web 终端网关
Sshwifty 0.4.12 Docker Compose 部署指南:交付物选型与摘要固定、compose.yaml 全量样例、配置挂载、TLS 与反向代理 WebSocket 要点、升级回滚与卸载清理、部署排障速查。
Sshwifty Docker Compose 部署指南:从零搭建 Web 终端网关
本文是 Sshwifty 专栏第二篇,面向需要在自有服务器上完成部署的运维人员。版本基线:0.4.12-beta-release(官方当前最新发布标签,2026-10-30 经 releases.atom 与 shields.io 核实)。文中部署命令均在真实 Linux 服务器视角下编写,直接可复制执行。
一、部署形态选型
Sshwifty 官方 README 明确将打包交付列为推荐安装方式("Docker Image (recommended)",来源:官方 README,2026-10-30 查询),三种官方形态对比如下:
| 形态 | 适用场景 | 备注 |
|---|---|---|
| 预构建可执行文件 | 不想引入运行时的极简环境 | 官方提示为自动化流水线产物,未经逐一人工验证 |
| 打包交付(本篇) | 绝大多数服务器场景 | 进程隔离、升级回滚干净、配置挂载灵活 |
| 源码编译 | 需要二次开发或定制构建 | 需要 Go 与 Node.js 工具链 |
官方交付物发布在 Docker Hub 的 niruix/sshwifty 仓库(注意仓库名带 x,与 GitHub 的 nirui 不同,这是官方 README 特别强调的易错点),仅提供 latest 标签。0.4.12-beta-release 对应的交付物摘要为 sha256:1a3ef74bd2e2dea175dee02763f918933f5f28954c3f7788883daede382c3f6b,生产环境建议按摘要固定引用,避免 latest 漂移带来的被动升级。
二、前置条件
- 一台 Linux 服务器(x86_64),已安装 Docker Engine 24+ 与 docker compose 插件;
- 服务器网络可达将要管理的 SSH/Telnet 目标主机;
- 一个空闲的对外端口(官方默认 8182);
- 准备目录
/opt/sshwifty存放配置与编排文件。
三、编写配置文件
在 /opt/sshwifty/sshwifty.conf.json 写入最小可用配置(配置项逐项解释见专栏第三篇《Sshwifty 配置参数详解:sshwifty.conf 全项精讲》,产品定位回顾见 《Sshwifty 介绍与选型指南:浏览器里的 SSH/Telnet 终端》):
{
"HostName": "",
"SharedKey": "q1w2e3r4",
"DialTimeout": 10,
"Socks5": "",
"Socks5User": "",
"Socks5Password": "",
"Hooks": { "before_connecting": [] },
"HookTimeout": 30,
"Servers": [
{
"ListenInterface": "0.0.0.0",
"ListenPort": 8182,
"InitialTimeout": 10,
"ReadTimeout": 120,
"WriteTimeout": 120,
"HeartbeatTimeout": 15,
"ReadDelay": 10,
"WriteDelay": 10,
"TLSCertificateFile": "",
"TLSCertificateKeyFile": "",
"ServerMessage": "Authorized access only."
}
],
"Presets": [
{
"Title": "Core Server",
"Type": "SSH",
"Host": "10.20.30.40:22",
"TabColor": "001100",
"Meta": {
"User": "root",
"Encoding": "utf-8",
"Authentication": "Password"
}
}
],
"OnlyAllowPresetRemotes": false
}
两处必改:SharedKey 是进入 Web 界面的预共享口令,务必换成高强度随机值;Presets[0].Host 换成你真实的目标主机地址。示例账号统一使用 root / q1w2e3r4。
四、编写 compose.yaml
在 /opt/sshwifty/compose.yaml 写入:
name: sshwifty-0-4-12-stack
services:
sshwifty:
image: niruix/sshwifty@sha256:1a3ef74bd2e2dea175dee02763f918933f5f28954c3f7788883daede382c3f6b
restart: unless-stopped
ports:
- "8182:8182"
volumes:
- ./sshwifty.conf.json:/etc/sshwifty.conf.json:ro
environment:
- SSHWIFTY_HOSTNAME=
- SSHWIFTY_LISTENINTERFACE=0.0.0.0
- SSHWIFTY_LISTENPORT=8182
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8182/ >/dev/null 2>&1 || exit 1"]
interval: 30s
timeout: 5s
retries: 3
networks:
- sshwifty-net
networks:
sshwifty-net:
driver: bridge
要点说明:
- 配置文件与环境变量的优先级:官方加载顺序是"默认路径配置文件优先,全部失败才读环境变量"。把配置只读挂载到
/etc/sshwifty.conf.json后即走文件配置,environment段此时仅作兜底声明。也可以在environment中用SSHWIFTY_CONFIG指定其他路径; - 配置文件只读挂载(
:ro):服务进程无写配置权限,防止运行期篡改; name: sshwifty-0-4-12-stack:compose 项目名显式声明。注意 Compose 会把项目名中的点号规范化为短横线,因此带版本号的名称建议直接用短横线书写,避免执行down时因名称不一致而清不干净;- 健康检查:
wget探测本机 8182 端口首页,交付物内置了 wget 可直接使用; - 若不需要自建网络,可删去
networks段使用默认网络,不影响功能。
五、启动与验证
# cd /opt/sshwifty
# docker compose up -d
[+] Running 2/2
✔ Network sshwifty-0-4-12-stack_sshwifty-net Created
✔ Container sshwifty-sshwifty-1 Started
# docker compose ps
NAME IMAGE STATUS
sshwifty-sshwifty-1 niruix/sshwifty Up 10 seconds (healthy)
# docker compose logs --tail 5
[INF] ... Sshwifty: Initializing
[INF] ... Sshwifty > Configuration > Redundant: Configuration file "/etc/sshwifty.conf.json" has been selected
[INF] ... Sshwifty > Server (0.0.0.0:8182): Serving
日志中出现 Configuration file "/etc/sshwifty.conf.json" has been selected 与 Serving 即表明配置加载成功、服务开始监听。
浏览器访问 http://<服务器IP>:8182/,验证顺序:
- 出现预共享密钥输入页("AUTHENTICATION REQUIRED"),输入
SharedKey后进入主界面; - 点左上角加号,"Known remotes" 中应看到预设的 "Core Server";
- 选中预设 → 核对 SHA256 指纹 → 输入密码 → 出现终端提示符即全链路打通。
六、TLS 与反向代理
方式 A:反向代理终结 TLS(推荐)。在 Nginx/Traefik 上终结 HTTPS,Sshwifty 保持 HTTP 监听。Nginx 参考片段(WebSocket 升级是关键):
location / {
proxy_pass http://127.0.0.1:8182;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
}
proxy_read_timeout 必须拉长,否则终端空闲一段时间后会被代理切断长连接。若反代后仅本机可达,把 ports 改为 "127.0.0.1:8182:8182" 收敛暴露面。
方式 B:服务自身 TLS。官方为打包形态提供了免挂载的证书注入方式:将 X.509 证书内容分别写入环境变量 SSHWIFTY_DOCKER_TLSCERT 与 SSHWIFTY_DOCKER_TLSCERTKEY(证书 PEM 全文),服务启动时自动启用 HTTPS。证书到期后需重建服务才能更新,因此长期运行更建议方式 A。
七、升级与回滚
# 升级到新版本(新摘要发布后)
# docker compose pull
# docker compose up -d
# 回滚:把 compose.yaml 中 image 摘要改回旧值后
# docker compose up -d
Sshwifty 无状态(不落库、无本地数据卷),升级与回滚即更换交付物摘要并重建服务,用户书签的连接配置全部保存在浏览器端与服务端配置文件中,不受影响。
八、卸载清理
# cd /opt/sshwifty
# docker compose down -v
down -v 会移除编排内全部服务、网络与数据卷。若当初使用了带点号的项目名(如 sshwifty.0.4.12),Compose 实际创建的项目名是规范化后的 sshwifty-0-4-12,清理时应执行 docker compose -p sshwifty-0-4-12 down -v。
九、部署排障速查
| 现象 | 根因 | 处置 |
|---|---|---|
日志出现 HTTP Error (403): To use Websocket interface, a valid Auth Key must be provided | 浏览器未先完成预共享密钥认证就发起 WebSocket | 正常行为,先在页面输入 SharedKey 认证 |
日志出现 Redundant: Loading configuration from one of the default configuration files ... 且配置未生效 | 配置文件路径或 JSON 语法有误,回退到了内置默认配置 | 核对挂载路径 /etc/sshwifty.conf.json 与 JSON 合法性 |
| 服务已启动但页面打不开 | ports 映射遗漏、或防火墙拦截 8182 | ss -ltn 核对监听;放行防火墙 |
连接目标机报 connect: connection refused | 目标主机端口未监听或地址写错 | 先在服务器上 nc -zv <host> <port> 验证可达性 |
| 终端空闲数分钟后断开 | ReadTimeout/反代超时过短 | 调大 ReadTimeout;Nginx 提高 proxy_read_timeout |
十、本篇小结与下一篇
本篇完成了从配置文件到编排文件再到上线验证的完整交付。下一步进入《Sshwifty 配置参数详解:sshwifty.conf 全项精讲》,逐项吃透两套配置体系(文件与环境变量)的全部参数;日常使用与运维排障请配合《Sshwifty 使用与运维详解:连接管理、安全加固与排障实录》阅读。
专栏导航:
- 《Sshwifty 介绍与选型指南:浏览器里的 SSH/Telnet 终端》
- 《Sshwifty Docker Compose 部署指南:从零搭建 Web 终端网关》(本篇)
- 《Sshwifty 配置参数详解:sshwifty.conf 全项精讲》
- 《Sshwifty 使用与运维详解:连接管理、安全加固与排障实录》