
portless 状态目录架构解析~/.portless 文件布局与 sudo 路由共享指南【免费下载链接】portlessReplace port numbers with stable, named local URLs. For humans and agents.项目地址: https://gitcode.com/GitHub_Trending/por/portlessportless 状态目录~/.portless是这款本地开发代理工具存放路由注册、代理进程状态和 TLS 证书的唯一位置。本文带你快速搞懂它的完整文件布局以及一个精巧设计为什么用 sudo 启动代理绑定 443 端口时root 进程和普通用户应用进程依然能共享同一份路由表。为什么需要固定的状态目录 portless 的核心玩法是把localhost:3000这类随机端口地址换成https://myapp.localhost这样稳定、可命名的本地 URL。要做到这一点代理必须记住两件事谁在运行哪个子域myapp、api.myapp…对应本机哪个随机端口4000-4999 区间怎么运行HTTPS 还是 HTTP、使用哪个 TLD、LAN 模式是否开启、证书是否已信任这些信息全部持久化在用户主目录下的~/.portless目录中而不是/tmp或项目目录。好处很直接重启电脑后自动复用上次配置重启或重新开机不会静默回退到默认值详见 README.md 的说明。状态目录的解析逻辑只有一处出口无论代理跑在 443、80 还是自定义端口都统一使用~/.portless。入口定义在 cli-utils.ts解析函数在 cli-utils.ts。~/.portless 文件布局一览 官方清理命令portless clean维护了一份已知状态文件白名单这份清单就是最权威的文件布局文档见 clean-utils.ts。按职责可以分成三组路由注册文件文件作用routes.json全部子域 → 端口的路由表JSON 数组格式routes.lock多进程并发写入路由时的文件锁路由存储的读写入口在 routes.ts。这是整个代理的地址簿你每次运行portless myapp next dev本质就是往这里注册一条myapp.localhost → 127.0.0.1:随机端口的记录。代理进程状态文件文件作用proxy.pid代理守护进程的 PID用于proxy stop和管理proxy.port代理实际监听的端口proxy.log守护进程的运行日志proxy.tls标记当前是否启用 HTTPS存在即开启proxy.custom-cert标记使用了自定义--cert/--key证书proxy.tld/proxy.tlds记住自定义 TLD如.test、dev.example.comproxy.lan记住 LAN 模式.local发现是否开启这些标记文件让代理具备记忆能力下次portless run自动拉起代理时直接沿用上次你选择的端口、TLS、TLD 和 LAN 设置。TLS 证书文件文件作用ca.pem/ca-key.pem本地自签 CA 及其私钥portless trust把 CA 加入系统信任库ca.trusted/ca.trust-refresh-pending记录 CA 是否已加入信任库、是否需要刷新server.pem/server-key.pem代理自身的服务器证书server.csr/server-ext.cnf/ca.srl证书签发过程的中间产物host-certs/目录按主机名签发的子域证书所有证书相关逻辑集中在 certs.ts其中host-certs/目录为每个注册的子域单独签发证书这正是浏览器访问https://myapp.localhost时不报安全警告的原因。⚠️ 版本提示portless 处于 pre-1.0 阶段不同版本间状态目录格式可能变化升级后可能需要重新运行portless trust。sudo 下路由共享是如何实现的 这是整个状态目录设计里最精巧的部分值得单独讲。问题root 进程的 HOME 不是你的 HOMEHTTPS 默认要绑定 443 特权端口小于 1024在 macOS/Linux 上必须由 root 执行。于是出现一个典型矛盾代理进程被 sudo 提权后运行它的$HOME变成了/root而注册路由的普通用户进程portless run读写的却是/Users/you/.portless如果两者各看各的目录路由表就分裂了root 代理根本不知道你要转发哪个子域。解法resolveUserHome 三级回退portless 的答案是——提权后仍然解析发起用户的主目录。核心函数 resolveUserHome 的逻辑非常清晰看SUDO_USER环境变量sudo 会自动设置它指向发起提权的普通用户。如果未设置或就是 root 本人直接返回常规os.homedir()HOME优先若HOME存在且不是/root或/var/root说明环境已正确保留用户目录直接用它查/etc/passwd读取SUDO_USER对应的家目录路径utils.ts约定式兜底macOS 落到/Users/用户名Linux 落到/home/用户名有了正确的主目录USER_STATE_DIR自然指向/Users/alice/.portless而不是/root/.portless。于是 root 代理和普通用户进程读写的是同一份routes.json——README 对这一行为的官方描述是it resolves this path from the invoking users home so the proxy and unprivileged app processes share the same route registrations。CLI 帮助文案也明确承诺了这一点Elevated proxy processes keep the invoking users ~/.portless state directory见 cli.ts。对应行为在测试中有完整断言例如 sudo 场景下USER_STATE_DIR应解析为发起用户的家目录见 cli-utils.test.ts。覆盖与清理两个实用操作 用 PORTLESS_STATE_DIR 换目录如果你需要跑多套互不干扰的代理实例比如一套.localhost、一套 LAN可以设置PORTLESS_STATE_DIR环境变量指向独立目录例如PORTLESS_STATE_DIR~/.portless-lan。解析优先级见 resolveStateDir环境变量优先否则一律~/.portless。顺带一提代码中还保留了一个已废弃的系统级目录/tmp/portlessWindows 为临时目录作为 LEGACY_SYSTEM_STATE_DIR仅供老版本安装迁移和清理时引用新状态一律住~/.portless。portless clean 的白名单清理portless clean不会无差别删目录而是只删除白名单里的已知文件removePortlessStateFiles你放在该目录下的其他文件不受影响。清理时会同时扫描用户目录、遗留系统目录和PORTLESS_STATE_DIR三处collectStateDirsForCleanup并顺带从系统信任库移除 portless 安装的本地 CA。关键源码路径速查状态目录常量与解析cli-utils.tssudo 主目录解析utils.ts状态文件白名单与清理clean-utils.ts路由表读写与文件锁routes.ts证书生成与信任certs.ts服务安装时状态目录注入launchd/systemd/Task Schedulerservice.ts小结一句话总结portless 把所有可变状态收敛到~/.portless一个目录用标记文件实现配置记忆用resolveUserHome的 sudo 感知解析保证 root 代理与用户进程共享同一份路由表。理解了这个布局你就理解了portless doctor体检、portless clean清理、多实例隔离这些运维能力背后的全部机制。【免费下载链接】portlessReplace port numbers with stable, named local URLs. For humans and agents.项目地址: https://gitcode.com/GitHub_Trending/por/portless创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考