一句话:LingCode Cloud 托管你构建的应用,因此没有服务器需要你来运维。部署分两种:静态前端(构建好的 Vite/React 打包产物),通过 https://lingcode.dev/apps/<app-id>/ 提供;以及全栈 Worker/SSR 应用,通过 https://<app-id>.run.lingcode.dev/ 提供。两者都能在 IDE 里一键发布——Deploy to LingCode Cloud。Worker 运行时是 Cloudflare V8 隔离环境(不是 Node.js),这是开始之前最值得弄清楚的那一条约束。
本页讲的是你构建好的应用最终住在哪里——你交付给用户的前端,以及在需要时为他们渲染或路由请求的那台服务器。它说的不是托管后端(数据库、认证、存储、函数);那是另一件互补的事,而且大多数服务端工作都该放到那边。我们会把两种部署目标、那个让人踩坑的运行时约束、自定义域名,以及——说实话——托管不适合干什么,都讲清楚。
当你在 LingCode 里构建一个应用时,产出的是一些文件:一个 index.html 加上若干带哈希的 JS/CSS,也许还有一份服务端打包产物。这些文件必须住在某个有公网 URL 和 HTTPS 的地方,别人才能用上它。常规的做法——租一台机器、装好运行时、配好 Web 服务器、续期证书——为了「把我的应用放上互联网」这件事,要做一大堆没有差异化价值的杂活。
LingCode Cloud 把这一切收敛成一个动作。你点一下 Deploy to LingCode Cloud,IDE 就会构建并上传应用,服务端再把它发布到自动 HTTPS 之后。你拿回一个上线的 URL。没有服务器需要你打补丁,也没有证书需要你续期。
LingCode 会看你构建出了什么,然后挑选合适的目标。区别归根结底就是一个问题:你的应用是否需要为每个请求在服务端运行代码?
| 静态前端 | 全栈 Worker / SSR 应用 | |
|---|---|---|
| 它是什么 | 构建好的 Vite/React(或类似)打包产物——index.html 加上带哈希的资源。没有服务端渲染。 |
一个在服务端渲染或路由的 TanStack Start、OpenNext,或 Cloudflare Workers 应用。 |
| 提供地址 | https://lingcode.dev/apps/<app-id>/——基于路径,带 SPA 回退。 |
https://<app-id>.run.lingcode.dev/——独立子域名。 |
| 运行时 | 没有——文件直接从边缘提供。 | 一个 Cloudflare Worker(V8 隔离环境),不是 Node.js。 |
| 限制 | 总计 ≤100 MB,单文件 ≤25 MB,≤2000 个文件。每小时 12 次部署。 | 打包产物 ≤60 MB。每小时 12 次部署。最多 10 个 worker 应用。 |
| 自定义域名 | — | 支持,并配有完整的自动 TLS。 |
| 何时选它 | 你的应用是一个单页应用,从浏览器里和后端(或第三方 API)对话。 | 你需要在请求时进行服务端渲染,或一条自定义的服务端路由。 |
对于静态前端,速率限制是每个用户每小时 12 次部署,且打包产物必须保持在总计 100 MB、单文件 25 MB、2000 个文件以内。对于 Worker 应用,你同样有每小时 12 次部署,打包产物必须保持在 60 MB 以内,而且最多能同时运行 10 个 worker 应用——尝试发布第 11 个,部署就会返回 cap_reached。
这是最大的一个坑,所以值得说精确。LingCode Cloud 上的全栈应用以 Cloudflare Worker 的形式运行——是一个 V8 隔离环境,而不是一个 Node.js 进程。V8 隔离环境是一个沙箱化的 JavaScript 运行时,它在毫秒级内启动,底层没有操作系统。这让它在边缘上运行得既快又省,但也意味着 Node 标准库里有一大块根本就不存在。
实际上,在一个 Worker 里你没有:
fs——不能在本地磁盘上读写文件(根本没有磁盘)。path——文件系统路径相关的辅助函数用不了。child_process——你不能派生子进程或调起 shell。具体后果是:一个普通的 Express/Node 服务器没法原样运行。如果你的全栈应用是「一个 Express 应用」,它就得被移植到面向 Worker 运行时的东西上——Hono、TanStack Start,或者通过 OpenNext 适配器接上的某个框架。这些都给你同样的请求/响应处理器模型,而不依赖只有 Node 才有的 API。
一个 Worker 就是一个接收 Request 并返回 Response 的函数。整个形态就这么简单。任何能套进这个形态的东西——渲染一个页面、处理一次表单 POST、校验一个 webhook——都跑得漂亮。任何套不进它的东西(保持一条连接常开、在后台跑一个循环、碰磁盘)都该放到别处去。脑子里揣着这幅图,下面绝大多数约束就不再让你意外了。
部署是一个 Mac 应用的动作,不是一个 agent 或 MCP 工具——你不用让 agent 去做,你点一个按钮。在 LingCode IDE 里,打开你构建好的应用,点 Deploy to LingCode Cloud。从那一刻起 IDE 会:
/apps/<app-id>/ 提供这些文件。对于 Worker 应用,服务端会把这次部署跑到 Cloudflare 的 Workers-for-Platforms,并挂上 <app-id>.run.lingcode.dev 这个主机名,HTTPS 会自动配置好。完成后,你会拿回一个可以打开或分享的上线 URL。想看带截图的完整演练,参见部署到 LingCode Cloud。
部署发布的是你的构建产出,所以产出必须是每个层级所期望的形态。你很少需要手写它——一份标准的 Vite/框架配置就会产生它——但了解这个形态,正是你看懂一次失败部署的方式。
一次普通的生产构建,输出到一个 dist/ 文件夹:一个 index.html 加上 dist/assets/ 下带哈希的资源。单页应用可以正常工作——未知路径会回退到 index.html。保持在上限之内(总计 100 MB,单文件 25 MB,2000 个文件)。不需要任何特殊处理;vite build 或你框架的静态导出就够了。
dist/
index.html
assets/
index-a1b2c3.js
index-d4e5f6.css
一次 Worker 部署期望的是 Cloudflare 的构建布局——一个 dist/server/,并在服务端入口旁边放一个 wrangler.json。那个文件由 Cloudflare Vite 插件产出;如果它缺失,部署会以 no_build_config 失败(参见排错)。一份能产出它的最小 Vite 配置:
// vite.config.ts
import { defineConfig } from 'vite';
import { cloudflare } from '@cloudflare/vite-plugin';
export default defineConfig({
plugins: [cloudflare()],
});
构建随后会产出两半——客户端资源,以及服务端打包产物加上它的 wrangler.json:
dist/
client/ # 静态资源,从边缘提供
server/
index.js # 你的 Worker(V8 隔离环境——不是 Node)
wrangler.json
对于 Next.js,用 OpenNext 的 Cloudflare 适配器(@opennextjs/cloudflare),而不是 Node 输出——它会产出部署能看懂的、同样的 Worker 形态构建。无论哪种方式,上一节那条规则依然成立:它以 V8 隔离环境运行,所以没有 fs、path 或原生模块。
no_build_config 意味着没有产出 Worker 布局——你的构建跑成了一个普通的 Node/静态构建,所以加上 Cloudflare 插件(或 OpenNext 适配器)再重新构建。bundle_too_large 意味着服务端打包产物超过了 60 MB——精简依赖。cap_reached / rate_limited 是账户限制(10 个应用,每小时 12 次部署)。完整列表见排错。
你可以在一个托管应用前面放上自己的域名,替代默认的 *.run.lingcode.dev URL。配置就是一次指向 LingCode 边缘的 DNS 改动:
apps.lingcode.dev 的 CNAME 记录,或者138.197.107.228 的 A 记录。把这条记录保持为 DNS-only / 不走代理(如果你的 DNS 服务商提供代理开关,把它关掉),这样边缘才能完成 TLS 握手。证书随后会自动、按需签发——没有什么需要你上传或续期。一步步的操作说明在绑定自定义域名里。
对于大多数服务端工作,托管后端是更好的归处:把密钥放进保险库,把厂商调用和受信逻辑放进函数,把数据放进数据库。这覆盖了「我需要这个跑在服务器上,而不是浏览器里」绝大多数的情况,而且你不必拥有任何基础设施。
只有在你需要请求时的服务端渲染或一条自定义服务端路由时,才专门动用全栈 Worker 应用。举个例子:一个必须校验原始请求体的 Stripe webhook 处理器,就该作为一条路由放在你托管的 Worker 应用内部——它需要那个未经解析的请求,而内置函数不会把它交到你手上。这就是那条分界线。服务端渲染和自定义请求处理 → Worker 应用;密钥、厂商调用和数据访问 → 后端。
一个典型上线的 LingCode 应用会同时用到平台的两半。前端——无论是 /apps/<id>/ 上的静态 SPA,还是 <id>.run.lingcode.dev 上的服务端渲染应用——是用户加载的东西。在它背后,数据库、函数和存储做着数据和受信的活儿。托管把你的应用放上互联网;后端给它一件能做的事。构建,点 Deploy to LingCode Cloud,再(可选地)把一个域名指向它——整个闭环就是这样。