本地到生产,解决 AI 全栈最后一公里——构建&部署&运维

8 阅读20分钟

前言

群众对于 AI 的热情日益高涨,普通人利用 AI 尝试搭建首个个人项目,各类研发工程师利用 AI 搞一些个人提效甚至初创项目越来越普遍,「一人公司」、「一人团队」、「超级个体」 开始流行,这背后指向同一件事:聪明的人类正在用 AI 扩展自己的能力边界。

不过 AI 打破了很多细分领域的壁垒,却不能替你解决所有工程问题(真不能,无论是现在还是可预见的未来)。一个人真正要把一个项目交付到生产环境,心智负担仍然是非常沉重,跨栈太多。

很多人学全栈,前面的开发过程还好,代码本地能跑,接口也通了,一到上线就傻掉了。

  • 前端为什么还要构建?后端为什么又要打包?
  • 域名、DNS、静态资源、CDN、Nginx、Docker、K8s、镜像容器、云服务器、云数据库、对象存储、Serverless 眼花缭乱到底什么意思?
  • 前端页面如何通过域名访问?
  • 全栈项目到底应该前后端分开部署,还是合并部署?
  • 服务上线后,进程挂了怎么办?日志怎么看?CPU、内存、磁盘如何选购?

今天讲的是生产交付最后一环:「构建、部署、运维」

阅读大纲

  • 构建、部署、运维分别是什么
  • 构建到底在构建什么
  • 常见部署方式:传统部署和 Docker 容器化部署
  • 基于 Docker 容器化的极简日常运维
  • 现代全栈项目的部署方案大全
  • 全栈项目部署流程总结
  • 个人项目高性价比终极部署方案
  • 总结

构建、部署、运维分别是什么

很多人会把这几个词混在一起,但它们其实对应生产交付中的三个阶段。先简单拉齐概念,后面再展开细讲。(现代成熟的岗位分工并没有特别明确地将各环节的负责边界分割得很清晰)

1. 什么是构建

什么是构建

计算机里有类似的概念叫编译,是指将源码编译成目标的机器码或字节码,在工程上构建是个更广泛的概念,通常指把开发环境的源码,转换成生产环境可直接部署的产物,通常是包含编译的一系列步骤。

开发环境和生产环境是完全不同的环境。本地开发关注调试效率、热更新、源码可读性;生产环境关注稳定性、加载性能、资源体积和安全隔离。所以代码写完后,通常不能直接丢到线上跑,而是要先经过构建。

比如前端项目会把 TS/JSX/Vue 等源码构建成 HTML/CSS/JS 静态资源;Java 项目会构建成 jarwar 等服务包;Python 项目会整理依赖、入口脚本和运行环境;Go、Rust 这类项目可能直接构建成二进制文件;Android、iOS 项目则会构建成 apkaabipa 这类安装包。

所以构建是部署前,从“源码”到“交付物”的转换过程。

2. 什么是部署

什么是部署

部署,就是把本地构建好的产物,放到公网可访问的服务器或云服务上,并让它真正运行起来

这里的服务器,不是我们平时写代码用的个人电脑,而是专门承载公网访问的操作系统环境。它可能是一台云服务器,也可能是容器平台、云托管平台、对象存储或 CDN。它和本地电脑在网络、安全、权限、资源限制、运行方式上都有很大差别。

常见部署动作包括:把前端静态资源上传到 CDN 或对象存储,把后端服务部署到云服务器,把 Docker 镜像发布到镜像仓库再由线上环境拉取运行,以及配置域名、HTTPS、环境变量、Nginx 反向代理等访问入口。

简单说,部署就是让产物从“本地可用”,变成“公网可访问”。

3. 什么是运维

什么是运维

运维,就是项目上线后,对线上系统持续做监控、排查、修复和保障

只要服务在公网运行,就会面对真实用户、真实流量和真实风险。比如服务异常、代码逻辑 bug、CPU/内存/磁盘/带宽资源不足、并发突然升高、接口响应变慢、恶意扫描攻击、数据库异常、日志爆量、证书过期、发版失败等。

运维要做的就是通过监控、日志、告警、回滚、扩容、安全策略等手段,尽量保证系统稳定运行,并在出问题时能快速定位和恢复。

构建是产出,部署是上线,运维是长期稳定运行。

构建到底在构建什么

以 Web 端的前后端全栈项目举例(最常见),很多时候受限于技术团队(多数情况技术团队前后端分离),我们将项目区分为前端项目、服务端项目,那构建后的产物也自然被称作前端产物或服务端产物,这是有误导性的说法,尤其对于前端,现代工程化构建概念的普及,让前端构建成为了一项复杂的方向,直接称呼前端产物是非常不准确的,我们应该直接以可部署的交付产物来看待:

所有项目(Web 端)的产物最终基本只会有两种:静态资源,和可运行服务。

构建产物分类

  1. 前端项目最终常见产物是:

    • HTML
    • CSS
    • JS
    • 图片、字体、媒体文件

    这些东西本质上都是静态资源,适合放到对象存储或 CDN。

  2. 后端项目最终常见产物是:

    • Node.js 服务
    • Java 服务
    • Go 二进制
    • Python 服务

这些东西本质上都是可运行服务,需要运行在某个宿主环境里,比如服务器、容器平台、云托管平台。

但是前端也可能构建出用于部署的服务,服务端也可能构建出静态资源,和前期所谓的前后端项目的分类没什么硬性联系。

所以现代全栈项目虽然技术栈很多,但上线时你只需要先想清楚两件事:

  • 哪些东西是静态资源,适合走 CDN
  • 哪些东西是运行时服务,必须部署到服务平台

这个抽象清楚后,后面的部署选择就会简单很多。

常见部署方式:传统部署和 Docker 容器化部署

现在常见部署方式基本可以分成两类:传统部署和 Docker 容器化部署。

传统部署和 Docker 容器化部署对比

1. 传统部署

传统部署就是直接在服务器上装环境、传代码、启动服务。(传统部署并非名词,只是和现代 Docker 容器化部署相比,显得很“传统”,所以我一直叫它传统部署。)

典型流程大概是:

  • 购买云服务器
  • 登录服务器,安装 Node.js、Nginx、MySQL 等环境
  • 上传代码或构建产物、安装依赖
  • pm2systemd 等方式启动服务
  • 用 Nginx 做反向代理

它的优点是直观,操作方式与本地开发类似,很容易理解,能让你清楚感知服务到底跑在哪,一台机器也可以装很多东西,灵活度很高。

但缺点同样明显:

  • 环境容易污染,操作系统环境本身需要手动维护
  • 迁移麻烦,换机器重新配环境,无法无缝迁移
  • 人工操作多,容易出错
  • 服务器补丁、安全、监控都要自己管
  • 服务跑久后,系统、软件、依赖都会持续演进,很容易背上历史包袱

所以传统部署更适合理解基础原理、临时验证或非常简单的小服务。如果是长期维护的线上项目,不建议把它作为首选。

2. Docker 容器化部署

Docker 不是新东西,它 2013 年就已经开源,到现在已经是非常成熟的工程基础设施。现在谈部署,Docker 基本是绕不开的一环。

Docker 容器化部署的核心价值是:把应用和运行环境一起打包成镜像,让服务以标准方式交付。

Docker 容器化部署

传统部署要在服务器上装环境、配依赖、传代码、守进程,时间久了很容易变成“这台机器只有我知道怎么跑”。Docker 则把这些东西收敛到镜像里,镜像能跑,服务器、容器平台、云托管平台就可以按同一套方式运行它。

它的典型流程很简单:

  • Dockerfile
  • 构建 Docker 镜像
  • 推送到镜像仓库
  • 在线上环境拉取镜像并运行

这样带来的便利性远超传统部署:

  • 环境一致,本地和线上差异更小
  • 迁移方便,换机器或换平台成本更低
  • 扩容方便,多跑几个实例即可
  • 回滚方便,切回旧镜像版本即可
  • 更适合接入 CI/CD,自动构建、自动发布

Docker 的概念并不在代码本地开发这套体系里,有一定学习成本,镜像体积、容器、端口、网络、挂载、缓存策略都需要理解。但对大多数业务开发来说,这部分更多是常识补齐,大多数策略由服务商的平台完成,日常最常见的实操通常是写好 Dockerfile,把服务构建成一个能稳定运行的镜像。

但从今天的工程实践看,容器化已经是更主流的服务交付方式。 很多云托管平台,本质上也是在运行你的容器镜像,只是把底层服务器运维屏蔽掉了。

Docker 标准化交付

可以这样理解:传统部署像搬家时把家具、电器、工具全部散装搬过去,到新房后还要重新组装、接线、调试;Docker 则像把整个可运行的工作间装进一个标准集装箱,运到哪台服务器或哪个平台,只要支持容器,就能按同一套方式启动。

简单说:传统部署是在服务器上手工搭环境,Docker 部署是把服务封装成标准交付物,便利性和可维护性完全不是一个量级。

基于 Docker 容器化的极简日常运维

部署只是起点,服务上线后的日常运维才是真正的长期开销。传统部署在运维上的压力相当繁琐:进程随时可能崩掉、流量突增要手动扩容、出问题要登录服务器翻日志、想回滚一次要重新上传文件再重启服务,每一步几乎都依赖人工介入。

容器化部署在这方面有着本质的改善,它把大多数运维操作变成了平台层面的标准能力,大幅降低了维护成本。

1. 不需要手动管理进程

  • 容器内进程异常退出,平台按重启策略自动拉起
  • 无需额外维护 pm2systemd 等守进程工具

2. 扩缩容不需要手动操作,多实例自动处理高并发

  • 多实例只需在平台调整数字,无需逐台配置环境
  • 流量突增自动扩容,高并发请求分摊到多个实例
  • 流量回落自动缩容,不浪费资源

3. 随时回滚,风险可控

  • 每次构建的镜像都是不可变的版本快照
  • 出现问题直接切换到上一个镜像版本重新部署,几分钟内恢复

4. 日志和资源监控开箱即用

  • 服务日志由平台统一收集,控制台直接按时间、关键词筛查
  • CPU、内存、请求量等资源指标实时可见,无需额外搭建监控体系

综合来看,容器化部署把运维成本从"人工操作"转移到了"平台配置"。对个人开发者和小团队来说,省掉了守进程、手动扩缩容、手动回滚这些高频运维动作,日常能把更多精力放在业务本身,而不是被线上维护拖着跑。

现代全栈项目的部署方案大全

现代项目里(仍然以 Web 端前后端项目分离为例),我同样按前面提到的交付产物角度来总结下,所有你可能用到的方案一次性给你总结出来,不存在唯一最佳实践,以我研发 CI/CD 平台的经验,都是可实际使用的方案:

前端服务端全栈部署

1. 纯静态资源部署,无需服务端

这类项目只包含前端代码,比如 React、Vue、静态站点、纯静态项目等。

它的特点是:

  • 仅包含前端代码
  • 构建产物只有 HTMLCSSJS、图片等静态资源
  • 官网、活动页、作品集等场景,最简单的场景

部署建议:

  • 部署方式通常是上传到 CDN 或对象存储
  • 但你需要解决域名解析的问题,因为你起码需要一个域名作为入口,有些 CDN 服务支持自定义域名直接解析,简单方便便宜

2. 静态资源 + Nginx 前端项目独立部署

这类项目本质上还是纯前端代码,但不只是把静态资源上传到 CDN,而是把页面入口(HTML)产物和 Nginx 结合,生成一个可以独立部署的服务。

它的特点是:

  • 仅包含前端代码,构建产物是静态资源
  • HTML 入口和静态资源放进 Nginx 镜像,生成独立部署镜像
  • 无需后端服务即可独立部署
  • 为什么要单独部署一个 Nginx?因为直接通过 CDN 访问限制颇多,很多时候前端页面需要请求各类后端服务,需要一层 Nginx 反向代理去解决基本的跨域问题。

使用建议:

  • 适合前后端完全分离,并且前端需要独立交付的场景
  • 适合不想依赖服务端项目一起发版的前端应用,前后端各自独立域名

3. 纯服务端项目

这类项目只有 API 服务端代码,比如 API 服务、后台服务、微服务。

它的特点是:

  • 仅包含服务端代码
  • 构建产物是服务端代码

使用建议:

  • 适合单独部署的后端应用
  • 适合接口服务、管理后台接口层、微服务体系中的某个服务
  • 建议优先按 Docker 镜像部署

4. 前端 + 服务端全栈项目

这类项目同时包含前端代码和服务端代码,适合全栈项目,前端后端代码都在一个仓库里,那将所有产物都放到一个服务里是最简单的。

它的特点是:

  • 一个仓库同时包含前端代码和服务端代码,一个团队或一个人开发

  • 构建产物通常包括前端静态资源和服务端镜像

  • 前后端需要在一次发布链路里协同部署,前后端耦合

  • 构建环节静态资源产物与服务产物结合,由服务端统一做页面的入口路由和 API 请求接口

  • 可以直接将所有静态资源都放入服务代码中,去掉上传 CDN 的操作,简化部署流程,但会增加服务器的开销,通常情况下静态资源上传 CDN 是更好的选择,只需要将 HTML 入口放置到服务端的 view 模板路由即可

使用建议:

  • 适合独立开发的全栈项目,前后端耦合
  • 可减少域名解析、上传 CDN 等简化部署流程

全栈项目部署流程总结

好的,到这里总结一下:如果你是一个 AI 全栈开发者,现在手里有一个全栈项目,想把它部署到生产环境,完整链路大概是下面这样。

1. 先确定部署形态

这里以最常见的前后端全栈部署为例:

  • 前端构建产物中的 index.html 交给服务端返回
  • 前端构建产物中的 JS/CSS/图片/字体 等静态资源上传到 CDN
  • 服务端代码和前端入口 HTML 合并到一起,最终构建成一个可部署的 Docker 镜像
  • Docker 镜像部署到云服务器、容器平台或云托管服务
  • 用户访问域名时,先命中服务端;服务端返回 HTML;HTML 再加载 CDN 上的静态资源;前端渲染后通过 AJAX 请求服务端 API

这是一种比较典型、也比较清晰的全栈部署模型:HTML 入口由服务控制,静态资源交给 CDN,服务逻辑交给 Docker 镜像。

2. 准备域名和云资源

正式上线前,通常先准备这些资源:

  • 域名,用于对外访问网站,并备案
  • CDN / 对象存储,用于存放前端静态资源
  • 服务部署平台,可以是云服务器、容器平台或 Serverless 云托管
  • 镜像仓库,用于存放 Docker 镜像(通常服务厂商会随镜像部署平台一同提供)
  • 数据库、缓存、对象存储等业务依赖

3. 写构建脚本

全栈项目最好有一个统一的构建脚本,把前端和服务端构建串起来。

典型流程是:

  • 前端执行 build,生成 index.htmlJSCSS、图片等产物
  • 构建时把静态资源访问路径配置成 CDN 域名或 CDN 路径
  • JS/CSS/图片/字体 等静态资源上传到 CDN / 对象存储
  • index.html 复制到服务端的模板目录或静态入口目录
  • 服务端执行 build,生成生产环境可运行的服务代码

这里的关键点是:HTML 入口和服务端合并,静态资源和服务端分离。

4. 写 Dockerfile

构建脚本负责产出服务代码和 HTML 入口,Dockerfile 负责把这些产物封装成镜像。

一个全栈项目的 Docker 镜像里通常包含:

  • 基本的操作系统(通常是 Linux 系列)
  • COPY 服务端构建产物
  • 服务端生产依赖
  • 服务启动命令
  • 对外暴露的端口

5. 部署服务并绑定域名

到这一步,构建产物会分成两部分发布:

  • 静态资源:上传到 CDN / 对象存储
  • 服务镜像:构建 Docker 镜像,推送到镜像仓库

服务镜像推送完成后,就可以在部署平台创建服务:

  • 选择刚刚推送的 Docker 镜像
  • 配置启动端口、环境变量、数据库连接等信息
  • 配置实例数量、重启策略、健康检查
  • 部署服务,等待实例启动成功
  • 申请 HTTPS 证书
  • 将域名解析到这个服务的公网访问入口

到这一步,域名、服务、Docker 镜像、CDN 静态资源就都串起来了。

6. 最终访问链路

用户真正访问网站时,完整链路是:

  1. 用户在浏览器访问你的域名。
  2. DNS 将域名解析到线上服务入口。
  3. 服务端接收请求,返回前端入口 index.html
  4. 浏览器解析 HTML,根据里面的资源地址加载 CDN 上的 JS/CSS/图片
  5. 前端代码加载完成后,在浏览器中完成页面渲染。
  6. 页面通过 AJAX / Fetch 请求服务端 API。
  7. 服务端处理接口逻辑,访问数据库或其他依赖,并返回数据。
  8. 前端拿到接口数据后继续更新页面。

所以一个完整的全栈部署,并不是“把代码丢到服务器”这么简单,而是把域名、DNS、CDN、Docker 镜像、服务入口、HTML 返回、静态资源加载、API 请求这整条链路串起来。

个人项目高性价比终极部署方案

我有一些全栈项目,综合成本、稳定性和维护难度来看,我提供一套实际的方案:前端静态化上 CDN,后端服务容器化部署到微信云托管平台。

1. 早期方案:前后端合并部署

早期我的做法比较直接:前后端都在一个 Git 仓库里,写一个 build 脚本和 Dockerfile,把前端产物和服务端代码都放进同一个服务镜像里,然后直接部署服务。

这个方案确实简单,部署链路短,但问题也明显:

  1. 前端页面访问也依赖服务端运行,服务常驻成本偏高。
  2. 静态资源由服务端返回,缓存和访问速度通常不如专业 CDN。
  3. 如果选择按量付费并让服务无流量挂起,第一次访问会触发冷启动,打开域名时容易白屏,体验很差。

也就是说,前后端合并部署适合快速上线,但不一定适合长期低成本运行。

2. 当前方案:静态资源上传 CDN + CNAME 自定义域名解析 + 微信云托管 Serverless 平台

现在我更倾向于把系统拆成两部分:

  • 前端静态资源和 HTML 入口放在 CDN
  • 后端服务单独部署到微信云托管

这套方案的核心优势是:页面 24 小时可访问,后端按需运行,整体成本低。

前端 HTML 入口和静态资源放到 CDN 后,有几个明显好处:

  • 前端页面可保证 24 小时在线
  • CDN 缓存访问速度快,费用低
  • 服务冷启动期间,页面仍然可以正常打开
  • 涉及动态数据的请求,可以通过加载态或提示优化体验

后端只提供 API 接口,部署到微信云托管这类 Serverless 平台;云数据库也可以选择无流量挂起。这样真正产生费用的,主要是用户访问动态接口时的后端运行和数据库访问,空闲时可以自动降到很低成本。

以我自己的站点体验来说,这种冷启动通常在几分钟内完成(实际时间因配置规格和镜像体积有所差异),所以它更适合低频访问的个人项目,不适合强实时、高频访问、不能接受接口冷启动的业务。

但对个人网站来说,这个代价可以接受。因为首页和主要内容都是静态可访问的,不会一打开就白屏;真正需要后端参与的,往往是留言、登录、管理、动态数据、AI 接口这类低频能力。

最终效果就是:前端 7x24 小时在线,后端和数据库按需运行,用户体验可接受,成本大幅降低。

下面是一些示例截图。

示例:前端 HTML 和静态资源上传到 CDN 服务,并通过自定义域名 CNAME 解析到 CDN 域名

前端 HTML 和静态资源上传到 CDN

示例:项目内置一个 Dockerfile 文件,平台自动完成构建部署全流程

平台自动构建 Dockerfile

示例:配置简单的服务扩缩容策略和无流量挂起策略

服务扩缩容和无流量挂起策略

示例:部署后的服务随时回滚、挂起或重启,简单的日志查询、云端调试、服务资源监控等功能满足大多数运维场景

服务回滚挂起重启和日志监控

示例:云数据库无流量挂起

云数据库无流量挂起

总结

AI 能力的普及,让更多人有机会独立完成一个个人项目。但从“本地能跑”到“生产环境稳定运行”,中间仍然隔着构建、部署、运维这最后一环。

把这条链路跑通,你才算真正完成了从代码到产品的交付。AI 可以帮你更快写出代码,但生产环境怎么跑、怎么省钱、怎么稳定,仍然是技术人必须补上的工程能力。

原创声明

原创文章,转载请注明作者和文章原链接,插图来源 AI 生成,关注公众号看更多文章哦!

公众号二维码

本篇文章 AI 占比说明

内容创作 AI 自律声明