
Puter 网站部署实战将 Puter.js 应用发布到任意静态托管与免费*.puter.site子域名并配置.puter_site_config站点行为【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter当你的应用完成 Puter.js 集成后下一步就是让它上线。Puter.js 是一个完全运行在浏览器里的普通 JavaScript 库这意味着你的应用本质上是一个静态网站——不需要为它单独准备任何后端服务。本文基于仓库中的 Deployments 部署指南 与 Site Configuration 站点配置指南完整讲解 Puter 网站的三条上线路径任意平台托管、Puter 免费子域名托管、GitHub Actions 自动部署并结合仓库源码剖析puter site deploy、静态站点中间件与.puter_site_config的底层实现让你既能照着操作也能理解背后发生了什么。部署形态总览为什么 Puter.js 应用没有部署门槛Puter.js 的全部逻辑都在浏览器端执行。应用通过script src...puter.js...方式加载后与 Puter 云端服务的通信文件系统、KV、AI 等能力都是从浏览器直接发出的托管位置并不参与这些交互。这一点在部署上带来了两个直接推论无需配置专属后端应用源码里的相关模块例如文件系统调用等能力封装可参考 puter-js 源码目录全部是纯前端逻辑部署方不需要理解 Puter 的内部协议部署方式与普通网站完全一致构建产物是一组静态文件扔到任何能跑 Web 服务器的环境即可。仓库文档 supported-platforms.md 也对 Puter.js 可运行的宿主环境做了说明。正因如此部署在 Puter 语境下只有两个关键词静态文件与Web 服务器。部署到任意平台Deploy anywhere既然 Puter.js 完全在浏览器中运行你的应用就可以像任何普通网站一样构建并托管在任何宿主上——无论是通用的托管平台如 Vercel、Cloudflare Pages、Netlify、GitHub Pages还是你自己维护的服务器甚至是本地开发服务器。唯一硬性要求应用必须由一个 Web 服务器来提供。托管服务商、自建服务器、本地开发服务器都可以但直接从磁盘双击打开 HTML 文件是行不通的——这既是因为浏览器对file://协议下脚本与网络请求的限制也是因为 Puter.js 需要以 HTTP(S) 方式与云端服务通信。其余没有任何额外配置。无论你的应用部署在哪里它都会照常从浏览器与 Puter 的服务通信。换句话说把你的构建产物index.html加其余静态资源当作普通网站发布即可这就是Deploy anywhere的全部含义。部署到 Puter免费的*.puter.site子域名托管如果你不想自己维护托管基础设施Puter 也可以直接帮你托管网站并提供一个免费的*.puter.site子域名。仓库中与此对应的服务端实现位于静态托管中间件 puterSite.ts它接收形如subdomain.puter.site的请求通过 SubdomainStore 把子域名解析到该用户在 Puter 云盘上的一个站点根目录再回传其中的静态文件。也就是说站点根目录就是你的云盘目录后续更新文件即更新网站。方式一在 puter.com 图形界面中发布对于不熟悉命令行的场景最快的方式是把网站文件直接上传到 puter.com 桌面并发布完整操作步骤如下创建站点文件夹在桌面上右键新建一个文件夹用于存放网站文件比如命名为my-site上传文件打开该文件夹在其内部空白处右键并选择Upload Here在此上传把网站的index.html及其它静态资源上传进去发布为网站在文件夹上右键选择Publish as Website发布为网站选择子域名并发布在弹出的面板里挑选一个子域名如my-site点击Publish。你的站点将立即在https://my-site.puter.site上线。提示原版文档在此处配有四张界面截图新建目录、上传、发布、上线结果仓库的图片资源中不包含这些截图故此处以文字还原操作流程。方式二使用 Puter CLI 从终端部署CLI 方式适合把部署纳入本地工作流。Puter CLI 的包名与版本信息可以在仓库 src/cli/package.json 中确认heyputer/cli当前 0.4.0bin名为puter要求 Node 18。全局安装npm install -g heyputer/cli⚠️ 当前 CLI 仍处于 beta0.x阶段命令与行为可能在未来变化——这一点官方文档明确提示过。登录认证首次使用CLI 支持交互式浏览器登录也支持把 token 通过 stdin 注入以便脚本自动化puter login # 浏览器登录流程交互式 echo $TOKEN | puter login --with-token # 通过 stdin 传入 token puter logout puter whoami在自动化环境如 CI中可以直接设置环境变量PUTER_AUTH_TOKENCLI 会跳过登录流程参见 src/cli/README.md。部署站点目录到一个*.puter.site子域名puter site deploy [dir] [subdomain]两个参数都是可选的直接运行puter site deploy而不带任何参数时CLI 会交互式地提示你输入要部署的目录与子域名目录的默认初始值为当前目录.。若想避免重复提示也可以显式给全例如puter site deploy dist my-site。站点管理命令与部署同属puter site子命令组puter site deploy [dir] [subdomain] # 部署两个位置参数均可选 puter site list # 列出你的全部站点 puter site get subdomain # 查看某个站点的信息 puter site delete subdomain [-y] # 删除站点交互终端需确认-y 跳过puter site deploy背后发生了什么从实现看site.js 部署命令 的流程远比传文件复杂理解它有助于你在 CLI 与 GUI 两种方式间自由切换目录与子域名校验目录必须真实存在子域名会被先规范化自动剥离粘贴进来时的.puter.site后缀再以正则^a-z0-9?$校验——只允许小写字母、数字与连字符且连字符不能出现在首尾垃圾文件过滤上传前会剔除.DS_Store、Thumbs.db、.localized等操作系统/平台产生的文件仅上传这些文件会得到空上传批次原子化、带版本号的目录结构每次部署都会在~/Sites/subdomain/deployment之下新建一个自动去重的目录deployment、deployment (1)、deployment (2)……上一版文件被完整保留便于回滚逐目录上传按目录遍历整棵文件树后分批上传并带重试与进度提示只要有任何文件上传失败整个部署就会失败——因为一个缺文件的站点就是坏站点绝不能先把子域名指过去指向新目录先查询该子域名是否已存在。不存在则调用puter.hosting.create(subdomain, targetPath)创建已存在则在交互式确认后调用puter.hosting.update(subdomain, targetPath)更新指向。如果子域名被别的账号占用会明确报错提示换名。这些hosting.create/update/get/list/delete调用对应的客户端封装可以在 puter-js hosting 模块 中查阅每个文件对应一个 API 操作。方式三用 GitHub Actions 自动部署如果你的代码托管在 GitHub 上可以借助官方的 Puter Subdomain Deploy Action让每次 push 都自动重新部署站点。在仓库中新建.github/workflows/deploy.yml即可官方文档给出的完整工作流如下name: Deploy to Puter on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Deploy website uses: HeyPuter/puter-subdomain-deploy-actionv1.0.6 with: subdomain: my-site # publishes to my-site.puter.site puter_path: ~/Sites/my-site/deployment/ # where to store the files on Puter source_path: dist # the folder to deploy (e.g. your build output) puter_token: ${{ secrets.PUTER_TOKEN }}使用要点配置仓库 Secret在 GitHub 仓库的 Settings → Secrets 中新建名为PUTER_TOKEN的 repository secret把值设为你的 Puter 认证 token前置构建如果项目有构建步骤例如npm ci npm run build把它放在 deploy step 之前执行并把source_path指向构建输出目录上例中的dist部署的就是真正的产物而非源码。托管服务端与站点的底层支撑源码视角为了让部署不只是个黑盒这里补充仓库中的服务端实现证据帮助你理解静态托管的边界与限制。静态托管中间件 puterSite.ts用户托管的站点由 puterSite.ts 这个 Express 中间件负责回源服务。它的职责边界在文件头注释里写得很清楚匹配托管域名*.puter.site及其它静态托管域名把子域名映射到站点根目录下的文件处理未知子域名、文件缺失、账号被停用等场景并返回 404走fsEntry.readContent透传 Range / ETag / Last-Modified支持静态文件断点续传与缓存校验在回源之前会读取并应用.puter_site_config详见 puterSiteConfig.ts决定错误页如何响应。值得注意的是该中间件还包含一个服务端 Worker 保留目录__workers/位于站点根目录下这个目录中的文件服务端 worker 源码可能包含用户机密永不被回源——无论是直接访问、文件夹到index.html的兜底还是作为自定义错误页目标见文件内WORKERS_FOLDER相关代码。此外用户已停权suspended时站点同样返回 404。站点与子域名管理接口创建 / 更新 / 查询站点并不直接暴露为 HTTP controller 路由而是通过 Puter 的 subdomains 驱动puter.hosting.*以 v1 形态的数据结构含 uuid 与嵌套对象提供给客户端。唯一保留为顶层 HTTP 路由的是删除操作在 HostingController.js 中POST /delete-site要求携带site_uuid且带有限流默认 60 次 / 60 秒窗口免费订阅 30 次、临时订阅 10 次同时会拒绝删除protected子域名以及不属于当前用户的站点——删除操作的破坏性决定了它额外的保护层。用.puter_site_config配置站点行为站点上线后你可以在其目录根部放一个.puter_site_config文件让 Puter 定制服务器对该站点的响应方式。目前它只控制一件事当请求不匹配任何文件时该返回哪个页面——而这恰好也是让单页应用SPA客户端路由生效的关键。文件放在哪里放在你发布目录的顶层与index.html同级。例如你把~/Desktop/my-site发布成了站点则该文件应位于~/Desktop/my-site/.puter_site_config。该文件永远不会被提供给访客请求/.puter_site_config会像请求任何不存在的路径一样返回 404从而避免暴露站点目录结构。这个逻辑在服务端由 puterSiteConfig.ts 中的isSiteConfigPath()配合 puterSite.ts 共同实现。让单页应用的客户端路由可用SPA 回退如果应用使用客户端路由React Router、Vue Router 等访客直接访问/dashboard时服务器会去查找一个并不存在的/dashboard文件。此时你希望服务器用index.html应答并返回正常的200把后续渲染交给前端路由。配置如下{ errors: { 404: { file: /index.html, status: 200 } } }把该文件随构建产物一起部署深层链接、刷新与分享出去的 URL 就都能正常工作。自定义 404 页面同一个思路但你想要一个真正的错误响应。此时省略status字段响应就会保留404状态码——这正是真正的页面不存在提示所需的行为{ errors: { 404: { file: /404.html } } }配置参考schema 与字段说明{ errors: { status code: { file: /path/to/page.html, status: 200 } } }字段类型是否必填说明errorsobject是把 HTTP 状态码映射到为其服务的页面。是文件里唯一允许的顶层键。errors.codeobject—被处理的状态码以字符串形式的键书写。取值必须落在400–599之间。目前只有404真正生效。errors.code.filestring是要服务的页面路径必须以/开头且相对于站点根目录。errors.code.statusnumber否随响应一起发送的状态码允许200–599。默认为被处理的状态码本身——也就是说为404写的规则默认返回404除非你显式改写。SPA 回退场景下把它设为200。说明除404之外的状态码会被接受并完成校验但暂时不会真的被用来回源页面。你可以先把它们写好等支持落地后自动生效但不要在今天依赖它们。源码级的解析与安全模型.puter_site_config的解析、缓存与安全边界全部集中在 puterSiteConfig.ts这份实现直接印证了上文文档中的每一条行为大小上限文件在读取前先检查条目大小、读取时再有流式字节计数兜底MAX_CONFIG_BYTES被硬编码为64 * 102464 KB见 puterSiteConfig.ts超限配置会被忽略容错解析parsePuterSiteConfig全程 try/catchJSON 语法错误、字段形状不合法都会静默返回空配置而非报错——坏配置永远不致命状态码白名单只有整数且落在400–599的errors键会被接受拒绝 2xx/3xx 键避免静默覆盖正常响应路径status字段必须为200–599的整数否则整条规则被丢弃路径逃逸防护每个file都会被当作 URL 路径规范化以/开头pathPosix.normalize折叠..并在回源前再次在resolveErrorTarget中防御性重校验确保解析结果始终落在站点根目录之下配置无法触达任何未发布的内容Redis 缓存与负缓存配置解析结果以puter-site-config:rootDirId为键缓存 60 秒CACHE_TTL_SECONDS没有任何配置的站点会写入一个负缓存哨兵值避免每次访问都去远端存储确认一次。缓存写入是尽力而为的fire-and-forgetRedis 抖动不会拖慢请求循环防护如果规则指向的错误页本身不存在则回落到 Puter 默认 404绝不递归触发 404→404→404 的循环该职责由消费方 puterSite.ts 承担。仓库中 puterSite.test.ts 对这些安全敏感分支配置门控、未知子域名、停权账号、缺少根目录等做了针对性的测试固定。使用注意事项配置生效有最多一分钟延迟。站点配置会被缓存 60 秒。编辑或重新上传文件后先等一分钟再去验证不要急着下结论说没生效。坏配置被忽略而不是致命。如果文件有 JSON 语法错误、超过 64 KB、或不符合上面的结构Puter 会表现得像没有这个文件一样正常服务站点——坏配置绝不会让站点宕机。但副作用是拼写错误也会安静地失败所以改完后要实际验证行为确实变化了而不是假设它生效了。缺失的错误页会回退。如果file指向的页面不存在访客会得到 Puter 的默认 404 页面不会出现重定向循环。路径无法逃出你的站点。file会在站点根目录内解析..段会被剥除因此配置不可能触达任何你没有发布的内容。什么是不支持的.puter_site_config不支持重定向、URL 重写、自定义响应头、干净 URL、cache-control 规则或目录列表。如果你正从其他托管平台移植_redirectsNetlify/Amplify 风格或vercel.json请注意只有错误页部分在这里有等价物。有两类重写是始终发生、无需配置的请求/或请求任何文件夹路径时都会返回该文件夹下的index.html。这保证了站点根路径一定能打开。端到端工作流串联把上面所有路径串成一个完整的上线工作流开发本地用 Puter.js 开发应用构建出静态产物index.html 资源发布三选一——puter.com 桌面 GUI新建文件夹 → 上传 → 发布为网站 → 选子域名、CLIputer site deploy、或 GitHub Actionspush 即部署。CLI 与 Actions 适合可重复部署GUI 适合快速验证验证访问https://subdomain.puter.site配置把.puter_site_config随构建产物一起发布处理 SPA 深链与自定义 404后续迭代重新执行puter site deployCLI 会保留历史版本目录或触发一次 pushActions 自动重新部署管理用puter site list/puter site get/puter site delete或puter.hosting.*API 管理站点。如果你想以编程方式而非文件上传创建和管理站点可以参考 Hosting API 文档puter.hosting.create/list/get/update/delete客户端实现见 puter-js hosting 模块。部署的完整背景说明可在 Deployments 部署指南 中继续查阅。【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考