news 2026/9/17 9:37:53

portless 环境变量实战:从稳定本地 URL 到手机直连与公网分享的调法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
portless 环境变量实战:从稳定本地 URL 到手机直连与公网分享的调法

portless 环境变量实战:从稳定本地 URL 到手机直连与公网分享的调法

【免费下载链接】portlessReplace port numbers with stable, named local URLs. For humans and agents.项目地址: https://gitcode.com/GitHub_Trending/por/portless

本地开发时,localhost 后面的端口号每次重启都变。portless 的本地代理让你直接访问https://myapp.localhost;它的调优靠PORTLESS_*环境变量。

端口号由 portless 在4000–4999区间随机分配,之后一直替你管理,你只需要记住名字。想先了解背景,可以看 README;本文不列清单,而是按一条使用动线讲——本地跑起来 → 手机/局域网访问 → 对外分享 → 旁路与排障——每个变量放在它真正被用到的场景里。

一条命令跑起来:URL 稳定下来,端口交给 portless 管

portless myapp next dev时,实际发生三件事:

  1. portless 先起一个 HTTPS 反向代理,默认占443(纯 HTTP 时为80);
  2. 你的应用拿到4000–4999里一个随机端口,通过注入的PORT环境变量知道该监听哪里;
  3. 之后https://myapp.localhost永远指向这个应用,端口换了你也不用改任何东西。

关键在这里:所有显式PORTLESS_*环境变量优先于portless.json和上次运行记忆的默认值。本地场景最常动的六个变量如下(完整定义见 配置文档):

变量它解决的痛点默认值
PORTLESS_PORT443 需要 root 或被其他服务占着443(HTTPS)/80(HTTP)
PORTLESS_HTTPSCI 或不信任本地 CA 时关掉 HTTPS开启
PORTLESS_TLD本地域名结构和生产对不上localhost
PORTLESS_WILDCARD想恢复"未注册子域回退父路由"严格匹配
PORTLESS_SYNC_HOSTS自己管 hosts 文件或环境受限开启
PORTLESS_APP_PORT外部工具已经指定了应用端口随机 4000–4999

代理端口被占或不想要 sudo:PORTLESS_PORT

443 需要 root 权限,开发机上还常被其他服务占着。给代理换个端口,一行就行:

PORTLESS_PORT=8443 portless proxy start

执行后代理改在 8443 上监听,你再也不用为抢 443 加 sudo;写进~/.bashrc就长期生效。

别踩这个坑:非法值(非数字、超出 1–65535)会被静默忽略并回落到协议默认端口,不会报错提醒你,解析逻辑在 cli-utils 实现。

让本地域名结构和生产一致:PORTLESS_TLD

想让本地 URL 长得像线上?TLD 支持单个或多段域名,逗号分隔:

PORTLESS_TLD=localhost,dev.example.com portless

执行后你会拿到dev.example.com后缀的 URL;多个 TLD 重叠时按"最长后缀优先"匹配,注入的PORTLESS_URL取第一个 TLD。变更历史见 CHANGELOG。

⚠️ 别把PORTLESS_TLD写成.local——它和 mDNS/Bonjour 冲突;.dev被 Google 持有且有 HSTS 风险。官方推荐 IANA 保留的.test

CI 里关掉 HTTPS:PORTLESS_HTTPS=0

CI 机器通常没有本地 CA,浏览器也不值得信任它。设PORTLESS_HTTPS=0等价--no-tls,代理切到 80 端口的纯 HTTP,整条链路不再涉及证书。

外部工具已经指定端口:PORTLESS_APP_PORT 的优先级链

有些工具链或团队约定已经给应用定好端口,这时别让 portless 随机分:

PORTLESS_APP_PORT=3100 portless myapp next dev

启动后子进程会收到PORT=3100,应用监听这个固定端口而不是随机端口。

应用端口的取值优先级(高到低):--app-port参数 >PORTLESS_APP_PORT>package.json"portless"键 >portless.json> 自动分配,规则见 配置文档。取值必须是 1–65535,否则启动报错退出,校验在 cli.ts。

子域严格匹配与 /etc/hosts 同步的取舍

默认是严格路由:api.myapp.localhost不会悄悄回退到myapp.localhost。设PORTLESS_WILDCARD=1可恢复"未注册子域回退父路由"的宽松行为。

另一件默认行为:portless 会自动同步/etc/hosts,目的是让 Safari 这类不走浏览器内置.localhost解析的环境也能打开页面。如果你自己管理 hosts 文件或处于受限环境,设PORTLESS_SYNC_HOSTS=0即可旁路,实现见 hosts.ts。

让手机直接打开开发页:LAN 模式的两个变量

真机调试时,手机和电脑不在同一个 loopback 上,myapp.localhost根本到不了手机。PORTLESS_LAN=1让代理绑定0.0.0.0/::,并通过 mDNS 发布<name>.local主机名——同一 Wi-Fi 下的手机直接访问https://myapp.local就能看到你的开发页:

PORTLESS_LAN=1 portless

执行后每次启动默认进 LAN 模式(写进 shell 配置就是长期行为)。

VPN、多网卡会让自动探测拿错 IP,这时用PORTLESS_LAN_IP固定:

PORTLESS_LAN_IP=192.168.1.50 portless

执行后代理会绑定你指定的这块网卡地址,探测逻辑被跳过。

💡 portless 会"记住"LAN 模式:停止后重启仍是 LAN 模式;临时想切回.localhost,只需单次加PORTLESS_LAN=0

把开发页发给同事和公网:Tailscale、Funnel、ngrok 三个开关

演示、联调、外部同事要看你的本地应用,又不想改框架配置(比如basePath)?三个变量都是设1生效:

1后的效果应用里读到的 URL 变量前提
PORTLESS_TAILSCALE:在 Tailscale 内网(tailnet)分享给所有设备PORTLESS_TAILSCALE_URLtailscale CLI 已安装、已连接并开启 HTTPS 证书
PORTLESS_FUNNEL:通过 Tailscale Funnel 暴露公网(隐含 tailscale)PORTLESS_TAILSCALE_URL同上
PORTLESS_NGROK:通过 ngrok 暴露公网PORTLESS_NGROK_URLngrok CLI 已配置 authtoken
PORTLESS_FUNNEL=1 portless myapp

启动后portless list会同时显示本地 URL 和分享 URL;应用退出时隧道自动清理,不用手动收尾。

一句话:把开关写进~/.bashrc.env即全局生效,不用每条命令都拖着。

应用代码怎么读自己的 URL:portless 注入的变量

portless 启动子进程时自动注入一批变量,应用代码直接读就行,不用硬编码地址:

注入的变量内容典型值
PORTLESS_URL应用的主 URLhttps://myapp.localhost
PORT应用应监听的临时端口4321
HOST通常为127.0.0.1(Expo LAN 模式下省略)
NODE_EXTRA_CA_CERTSportless 本地 CA 路径(HTTPS 时)
PORTLESS_TAILSCALE_URLTailscale 地址(启用分享时)https://dev.tail1234.ts.net
PORTLESS_NGROK_URLngrok 地址(启用时)https://abc.ngrok.app

注入逻辑在 cli.ts。

📌 典型用法——OAuth 回调地址不再硬编码:

const baseUrl = process.env.PORTLESS_URL || "http://localhost:3000";

这样回调地址在本地、LAN、隧道三种环境下都正确。完整集成方式见 OAuth 技能说明。

不想走代理:PORTLESS=0 旁路的边界在哪

除了带星号的变量,还有一个隐藏主角——不带星号的PORTLESS

PORTLESS=0 pnpm dev

执行后命令原样直接运行,完全绕开 portless 代理,原始输出直接可见。适用场景:调试代理本身、跑vite build这类不需要路由的任务、或临时想看未经加工的输出。

边界要分清楚:portless proxyportless clean这类子命令不受旁路影响,始终正常执行;子命令的退出码会原样透传。行为见 旁路测试 与 命令参考。

一台机器跑两套代理:用 PORTLESS_STATE_DIR 隔离状态

把代理装成开机自启服务时,环境变量会被固化进服务定义,这就给"双份代理"留了口子:

PORTLESS_STATE_DIR=~/.portless-lan PORTLESS_LAN=1 portless service install

装完后这套服务的所有状态文件(routes.jsonproxy.pid等)都落在~/.portless-lan,默认那套仍住在~/.portless,实现见 service.ts。

这样同一台机器可以同时跑"日常.localhost代理"和"独立 LAN 代理"两套状态,互不干扰。

常用组合命令卡与动手前自查清单

⚠️ 最常见的情况先说:改了环境变量但代理没变化?已有代理正在运行时,portless 会警告并要求你先portless proxy stop——新变量只对新启动的代理生效。

常用组合,按需复制:

PORTLESS_PORT=8443 portless proxy start PORTLESS_APP_PORT=3100 portless myapp next dev

第一条给代理换端口免 sudo,第二条固定应用端口。

PORTLESS_LAN=1 portless PORTLESS_FUNNEL=1 portless myapp

第一条进 LAN 模式给手机用,第二条开 Funnel 公网分享。

PORTLESS_STATE_DIR=~/.portless-lan PORTLESS_LAN=1 portless service install PORTLESS=0 pnpm dev

第一条装一套独立状态的 LAN 服务,第二条临时旁路代理。

动手前自查五条:

  1. PORTLESS_PORT非法值会被静默忽略(回落 443/80);PORTLESS_APP_PORT非法值会报错退出。两者取值都必须是 1–65535 的数字。
  2. 优先级:显式环境变量 >portless.json> 上次运行记忆。怀疑配置冲突时,先确认 shell 里没有同名变量。
  3. PORTLESS_TLD避开.local(撞 mDNS)和.dev(Google 持有、HSTS 风险),推荐.test
  4. 开分享前确认tailscaleCLI(已连接、HTTPS 证书)或ngrokCLI(authtoken)就绪,否则隧道起不来。
  5. 代理在跑时改变量无效——先portless proxy stop,再带着新变量启动。

【免费下载链接】portlessReplace port numbers with stable, named local URLs. For humans and agents.项目地址: https://gitcode.com/GitHub_Trending/por/portless

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 9:33:10

把Scratch改造成游戏引擎:三个月实战改造指南

“Scratch变成游戏引擎&#xff1f;说实话&#xff0c;三个月前我自己也不信。”这个想法起源于一次暑期班的课后复盘——孩子们用积木搭出来的小游戏&#xff0c;每次重开都要手动复位角色、重置变量、重新播放背景音乐&#xff0c;玩起来就像没有导演的舞台剧。我当时随口说了…

作者头像 李华
网站建设 2026/9/17 9:31:11

Spring Boot文件上传下载实战与优化策略

1. 文件传输在现代Web应用中的核心地位文件上传与下载功能看似基础&#xff0c;实则是现代Web应用中最高频使用的功能模块之一。从社交媒体平台的图片分享到企业OA系统的文档流转&#xff0c;从在线教育平台的课件分发到医疗系统的影像传输&#xff0c;文件交互能力直接影响着用…

作者头像 李华
网站建设 2026/9/17 9:31:07

Ubuntu / WSL 安装pipx uv 管理项目

一、pipx管理工具 1.1 安装 pipx 在 Ubuntu / WSL 上可以用两种方式安装&#xff0c;推荐第二种&#xff08;官方脚本&#xff09;或第三种&#xff08;pip 安装最新版本并自动配置 PATH&#xff09;。 1.1.1、apt 安装&#xff08;最快&#xff0c;但版本往往偏旧&#xff…

作者头像 李华