PortPilot¶
一个轻量的 Windows 本地服务发布工具,让只在
localhost上运行的网站和 Web 服务,可以按需要提供给手机、另一台电脑、Tailnet 或互联网访问。
1 项目定位¶
平时开发本地 Web 工具时,经常会遇到一个很实际的问题:
程序在自己电脑上通过 localhost 访问完全正常,但想在手机、另一台电脑上打开,或者临时发给别人看,就需要重新配置监听地址、防火墙、HTTPS、反向代理,甚至还要处理 Tailscale 或公网访问。
PortPilot 就是为了解决这类问题。
它不要求修改原来的 Web 服务,而是在外面增加一层统一的访问入口。对于已经运行的 HTTP / HTTPS 服务,只需要填写原始地址;对于一个普通静态网站目录,也可以直接由 PortPilot 启动服务。
核心目标不是做一个完整的 Web Server,而是把“本机服务如何被其他设备访问”这件事统一管理起来。
2 支持的访问方式¶
PortPilot 将不同网络场景整理为五种模式:
| 模式 | 适用场景 |
|---|---|
| IPv6 Direct | 本机有公网 IPv6,希望直接从互联网访问 |
| Tailscale Direct | 仅在自己的 Tailnet 设备之间访问 |
| Tailscale Serve | Tailnet 内需要 HTTPS |
| Tailscale Funnel | 临时把本地服务公开到互联网 |
| Remote Bridge | 远端设备也必须通过自己的 localhost 使用服务 |
其中 Remote Bridge 是我后来比较喜欢的一种模式。
有些本地 Web 工具不仅要求服务本身监听 127.0.0.1,前端也可能对 Host、Origin 或浏览器安全上下文比较敏感。简单把端口暴露出去并不能完全解决问题。
Remote Bridge 的思路是:
电脑 B 浏览器
http://127.0.0.1:13081
│
▼
PortPilot Bridge Client
│
Tailscale
│
▼
PortPilot Bridge Server
│
▼
电脑 A localhost 服务
这样电脑 A 上的原服务仍然只监听本机,电脑 B 的浏览器看到的也仍然是自己的 localhost。
3 核心能力¶
PortPilot 目前主要包括:
- 同时管理多个本地服务
- 支持静态网站目录和已有 HTTP / HTTPS 服务
- 每个服务可以独立启动、停止、重启
- 自动生成并展示访问地址
- 支持 HTTP 与 WebSocket 转发
- 对
localhost目标恢复正确的Host和Origin - 集成 Tailscale CLI
- 支持 Tailscale Direct / Serve / Funnel
- 支持两台设备之间的 Remote Bridge
- 托盘常驻
- 定期检查入口状态,异常时尝试恢复
- 配置和日志统一保存在用户目录
程序关闭主窗口后仍可在系统托盘运行,比较适合这种“启动之后长期放着不管”的小工具。
4 技术实现¶
项目使用 Go 1.26 开发,Windows 桌面界面使用 lxn/walk。
整体可以理解成三层:
4.1 本地反向代理¶
对于已经运行的 Web 服务,PortPilot 不负责启动原程序,而是在指定入口上建立转发。
除了普通 HTTP,请求链路还需要处理 WebSocket。对于目标是 localhost 的服务,会恢复后端期望的 Host,并在存在 Origin 时同步修正,避免部分 Web UI 因来源校验导致访问失败。
4.2 Tailscale 集成¶
Tailscale 相关功能没有重复实现自己的虚拟网络,而是直接调用本机 Tailscale CLI。
PortPilot 负责把用户看到的“访问模式”转换为对应的 Serve、Funnel 或 Tailnet 地址管理逻辑,把比较零散的命令行操作收敛到一个桌面界面里。
4.3 Remote Bridge¶
Remote Bridge 由服务端和客户端两部分组成。
服务端运行在真正提供 Web 服务的电脑上,客户端在远端电脑建立一个本机 127.0.0.1 入口,两端通过 Tailnet 建立连接。
这个模式的重点不是公网穿透,而是让远端程序仍然以“访问本机 localhost”的方式工作。
5 数据与部署¶
PortPilot 的运行数据统一放在:
%LOCALAPPDATA%\BeyondXinXin\PortPilot\
├─ config\
│ └─ services.json
├─ logs\
│ └─ PortPilot.log
└─ resources\
项目最终发布为 Windows x64 单文件程序,不需要额外安装 Go、Node.js 或 Web Server。
使用 Tailscale 相关模式时,需要电脑已经安装并登录 Tailscale。
需要注意,IPv6 Direct 和 Tailscale Funnel 都可能把服务直接暴露到互联网。PortPilot 本身不替目标应用增加账号、鉴权或限流,因此只应该公开本身就适合公开访问的服务。
6 为什么做这个项目¶
PortPilot 的起点其实很简单:我有越来越多只在本机运行的小型 Web 工具。
这些工具本身并不复杂,但每次想换一台电脑、用手机访问,或者临时在外面打开时,都要重新处理网络问题。
单独解决某一次很容易:
- 改监听地址
- 开一个 HTTP Server
- 写一个反向代理
- 用 Tailscale
- 用 Funnel
- 手工做端口转发
真正麻烦的是这些方法分散在不同工具和配置里。
所以最后干脆把它们整理成一个自己的 Windows 小工具:本地服务是什么不重要,我只选择“这一次准备让谁访问”。
这也是 PortPilot 最核心的设计思路。
7 项目状态¶
PortPilot 是一个面向自己日常开发场景持续使用的小工具,目前已经覆盖局域设备、Tailnet、HTTPS、公网临时分享和远端 localhost 桥接几类常见需求。
源码与 Release: