乐于分享
好东西不私藏

一天打通服务器公网部署和App构建

一天打通服务器公网部署和App构建

昨天,一个公网链接终于打开了。

同一天,一款装着 78 张塔罗牌的应用,也真的跑在了 Android 手机上。

如果把它们写进工作日报,大概只有两行:网站部署完成,App 真机验证通过。

可真正做完以后,我反而觉得,这两行把最麻烦的部分全藏掉了。

因为写完代码,只是让项目在自己的电脑里活着。交付,是让它离开这台电脑,到了别人手里还能活。

网页能打开,不代表网站已经上线

先说那个看起来更简单的网站。

它在本地已经能正常运行。按最直觉的想法,后面无非就是把文件传到服务器,再给它一个访问地址。

问题偏偏就出在这个“无非”。

这次最典型的坑,是构建路径和服务器上的访问路径没有对齐。结果很迷惑:页面地址能访问,样式和脚本却没有跟着加载,最后看到的仍然可能是一片白。

也就是说,服务器上出现了文件,和别人能正常打开网站,根本不是一回事。

后来我把这件事拆成了一条不能跳步的链路:

完成开发 → 生产构建 → 打包静态产物 → 上传服务器 → Web 服务托管 → 检查页面与资源 → 公网验收 → 接入域名

这串流程看起来长,其实每一步都在回答一个不同的问题。

构建,是确认发布版真的能生成;打包,是只带走网站运行所需的产物;独立目录和访问路径,是避免碰坏服务器上原有的站点;页面打开后,还要继续检查样式、脚本和图片,而不是看到首页就宣布成功。

域名、备案和 HTTPS,则是文件已经能被公网访问之后的下一层工作。它们不能替代前面的资源验收,也不该和“文件上传成功”混成同一个节点。

所以网站部署真正值得记住的,不是某条命令,而是一种排错顺序:别把“上传”当成终点,要沿着构建、传输、托管、资源加载和公网访问,一段一段验。

78 张牌进了手机,才开始像个产品

另一个项目的起点,是手里的 78 张塔罗牌卡面。

原始图片一共约 251 MB。直接全部塞进应用当然省事,但安装包也会跟着变重。最后采用的办法是保留原图,另外生成压缩后的 WebP 副本,专门供移动端使用。

素材进去之后,应用还要把整条体验接起来:12 种牌阵、正逆位、问题输入、随机抽牌、AI 解读、最多三轮追问、本地历史,以及洗牌、抽牌和翻牌时的声音与动画。

不过,功能能演示,还不等于它能交到别人手上。

最先需要处理的是模型密钥。它不能直接缝进安装包,否则安装包一旦被拆开,密钥也跟着暴露。于是调用关系被拆成三段:

移动端应用 → 云端接口 → AI 模型

应用只负责提出请求;云端保存密钥,同时处理邀请码、使用次数和模型调用。这样交出去的是使用入口,不是服务器的钥匙。

接下来才轮到 Android 的交付链路:

写代码 → 自动测试 → Release 构建 → 生成 APK → 安装到手机 → 真机验证

这条线目前已经跑通,最新版安装到了 Android 真机,完整测试 78/78 通过。

注意,测试通过和真机能用仍然是两个节点。前者说明预设行为没有明显出错,后者才确认安装包真的能装、能启动、能走进实际流程。

一套代码可以复用,交付流程不能复制

做到这里,还有一个很容易被一句“支持多端”掩盖的问题。

Android 已经完成 Release 构建和真机验证,但 iOS 还没有完成真机发布。它可以复用大部分业务代码,真正到构建、签名和分发时,依然需要 Mac、Xcode 或云构建服务,还要处理开发者账号、设备注册和签名。

小程序也仍然只是形态与适配探索。它不是给现有 App 换个外壳,接口、数据存储、动画能力和审核要求都需要重新确认。

所以这次没有“一次开发,三端完成”那么漂亮的结论。更准确的说法是:业务逻辑可以复用,但 Android、iOS 和小程序,各自都有一段不能代走的交付路。

现在再回头看昨天的两个结果,一个是能从公网打开的页面,一个是出现在手机里的应用图标。

它们真正改变的,是我对“项目完成”的判断标准。

下次再准备写下“已经做完”之前,我会先问四个问题:

  • • 别人能不能打开,或者安装?
  • • 页面、图片和核心功能是不是都能正常使用?
  • • 密钥这类敏感信息有没有留在客户端?
  • • 出了问题,能不能定位到交付链路里的具体一段?

这四个问题都能回答,项目才算真正离开了开发者的电脑。

如果你也在做自己的 AI 项目,可以先把这份自检收藏下来。代码跑起来以后,再往前走一步:把它交到另一个人手里试试。