文章

前后端部署:服务器、容器与 Serverless 分别解决什么问题

从一个普通的前端、API 和数据库应用出发,梳理部署方式的责任边界,以及什么时候需要容器编排。

目录

学习部署时,我把 Docker、Kubernetes、Serverless 和几个托管平台放在了一起。但这些名字其实不在同一个层次:有的是打包应用的方法,有的是管理应用运行的系统,有的是把一部分运维责任交给平台的服务方式。

我当时想弄清楚的问题很实际:如果我的项目只是一个前端、一个调用外部 API 的后端,再加上数据库,到底需要多复杂的部署?

这篇笔记始于 2025 年 11 月。整理时修正了原稿中的服务兼容性判断,并移除了已经停止服务的 MongoDB Data API 部署方案。它是一份概念梳理,不是某个平台的最新配置教程。

先把三个问题分开

部署首先要回答:代码在哪里运行?依赖怎么保持一致?程序出问题时由谁恢复?

服务器提供运行程序的机器环境。租一台云服务器后,可以直接在上面安装运行时,启动后端进程。域名、反向代理、证书、进程守护和系统更新,需要自己安排。

容器把应用和运行所需的文件、依赖封装在一起,让环境更容易重复。它可以运行在自己的服务器上,也可以交给托管平台。容器本身不会替我完成备份、监控和扩容。Docker 文档

Serverless描述的是一种服务与运维边界:我提交代码或工作负载,由平台管理底层计算资源。在函数式服务中,代码通常由请求或其他事件触发。我仍然要处理业务逻辑、权限、数据和错误,也需要适应平台的运行时与资源限制。

因此,服务器、容器和 Serverless 不是三个互斥的技术选项。用容器封装的服务也可以由平台按需运行;在自己租的机器上运行容器,也依然需要自己管理那台机器。

一个前后端应用,可以分别部署

前端和后端没有必要部署在一起。如果前端生成的是静态文件,可以交给静态托管服务和 CDN;需要服务端渲染的前端,则还需要相应的计算环境。

后端负责接收请求、检查权限、调用外部服务、读写数据库。数据库则有自己的持久化、备份和访问控制要求,不能因为后端用了容器就忽略这些工作。

浏览器 ──→ 前端页面
   │
   └────→ 后端 API ──→ 数据库
                    └─→ 外部 API

这个结构不要求特定的平台组合。关键是每一部分的地址、权限和生命周期清楚:浏览器访问公开接口,后端保存服务端凭据,数据库只接受允许的访问。

自己运行,还是交给平台

方式 主要负责什么 需要留意什么
自己管理服务器 系统、运行时、进程、网络和应用 更新、监控、备份、恢复是否有人维护
托管容器服务 镜像、配置和应用行为;基础设施由平台承担一部分 平台提供哪些恢复与扩缩容能力,持久化数据放在哪里
托管函数服务 Handler、业务逻辑、权限和外部依赖 运行时兼容性、执行限制、连接方式与调用成本

容器对我的一个直接价值,是减少环境差异。如果程序需要特定系统依赖,例如媒体处理工具,镜像可以明确记录这些依赖。部署到自己的机器还是托管平台,是下一层选择。

函数式服务则适合把一些围绕请求展开的逻辑交给平台运行。但“REST API”这个标签本身还不足以决定部署方式:一个 API 可能很快返回,也可能在请求里运行很久的任务。要看真实工作负载,而不能只看接口形式。

Docker 后面不一定要接 Kubernetes

原来我画过这样的结构:应用代码 → Docker 容器 → Kubernetes → 云服务器集群。它描述了一种部署方式,但容易让人误以为每个项目都必须走完这几层。

Kubernetes 主要解决容器化工作负载的部署与管理,包括调度、扩缩容和故障恢复等问题。它也需要配置与维护,并不是加上之后所有运维工作就会自动消失。Kubernetes 概述

对于一个规模不大、服务数量有限的项目,可以先在一台服务器上运行进程或容器,也可以使用托管服务。是否引入编排系统,要看是否已经出现了多服务管理、可用性和团队协作方面的具体需求。高并发也不是唯一判断条件。

我从这份学习笔记里得到的一个判断是:先说清楚现在要解决哪一个运行问题,再增加相应的基础设施。

两个需要修正的判断

原稿把 Serverless 简化成“不能维持 TCP 连接”,又把 WebSocket 单独划到了容器一侧。这个分法不准确,能力取决于具体平台。例如 Cloudflare Workers 提供出站 TCP Socket API,也支持 WebSocket。是否能使用某个数据库驱动,还要继续核对运行时和连接管理方式,不能从“支持 TCP”直接推出“所有驱动都兼容”。TCP 文档、WebSocket 文档

原稿还推荐用 MongoDB Atlas Data API 连接数据库。该服务已于 2025 年 9 月 30 日结束生命周期,因此不应继续把它列为新项目的部署路径。这是整理时纠正的一处原始笔记错误。MongoDB 官方说明

真正开始部署之前

对一个“前端 + API + 数据库”的小应用,我会先回答这些问题:

  • 前端是静态页面,还是需要服务端运行?
  • 后端每次请求需要多久,是否依赖本地文件、原生库或后台任务?
  • 数据库驱动能否在目标运行时里工作,连接和凭据如何管理?
  • 出错后如何查看日志、恢复服务、回滚版本?
  • 随着访问量增长,费用和资源限制会怎样变化?

回答这些问题之后,再决定是直接运行服务、制作容器镜像,还是适配函数式运行时,会比先选一套听起来完整的技术栈更清楚。

文章

AI 助手与对话数据

团子是 AI 角色,不是本人。掷骰子等开场互动使用预先整理的公开资料,不调用模型。实时对话是否可用,以聊天框中的状态说明为准。

启用实时对话后,发送问题会将问题、当前文章的标识,以及服务器保存的近期对话与早期对话目录发送到本站后端;后端会将这些内容和检索到的公开资料发送给阿里云百炼生成回答。首次建立会话时使用 Cloudflare Turnstile 验证访客,无需注册。不要输入密钥或私人信息。模型与验证服务的数据处理适用各服务商的政策。

浏览器使用当前标签页的会话存储保存最近十条互动,便于在文章和对话间返回;清空对话会清除这些本地记录。服务器会话有效期为一小时,最多保存二十轮已完成对话;最近三轮直接作为上下文,较早记录按需读取。过期记录在后续请求时清理。“重新开始”会放弃当前会话,但不会立即删除服务器上的记录。在同一标签页的 HTTPS 页面间切换时,一小时会话凭证保存在该标签页的会话存储中,供后端恢复近期上下文和早期对话目录;它不是模型服务的 API 密钥。凭证过期或存储不可用时,需要重新验证,之前显示的记录不会自动进入新会话。

服务器另保存额度、预算和短期请求限制记录;连接标识经过带密钥的哈希处理。应用不额外记录问题日志,但服务器会话存储中包含上述对话文本。模型请求失败时,仅记录随机请求编号、错误类别、处理阶段、调用次数及是否已有部分输出,不记录问题、回答、IP 地址或密钥。AI 只能使用网站提供的公开资料工具,不能访问个人文件、私人聊天或密钥。来源链接不保证每句话准确;请检查原文,并区分作者观点、引用观点与模型推断。

嗨,我在。

不知道从哪里开始?我们可以掷个骰子。

我是 AI 角色,不是煜欣本人。当前可以玩开场互动;自由对话尚未接通。