写在前面:前几节课学了 Docker 容器化、Nginx 反向代理、React + NestJS 全栈开发。今天,这些零件终于串成了一条完整的流水线------全栈项目部署全流程 。课堂讲了从买服务器到域名备案,从 DNS 解析到安全组,从 Nginx 分流到反向代理解决跨域,再到宝塔面板、nvm 版本管理、TS 构建。最有意思的是 readme 里那个直击灵魂的问题:"用户访问网站到底发生了什么?" 今天我们就顺着这个问题,把部署全流程走一遍。以下所有概念和流程均来自课堂真实笔记。
一、部署是什么:把代码从电脑搬到互联网
先看 readme 开篇的一张"路线图":
"运维工程师------加分项。vercel 云端部署------比较固定,nextjs + supabase 项目。java,go,python 部署自由度。国内支持------腾讯云。"
部署有两条路:
| 路线 | 代表 | 优点 | 缺点 |
|---|---|---|---|
| 云平台托管 | Vercel | 一键部署,省事 | 自由度低,只适合特定栈 |
| 自建服务器 | 腾讯云 + 宝塔 | 想怎么部署就怎么部署 | 得自己搭环境 |
Vercel 适合 Next.js 项目------平台就是为它量身定制的,push 代码自动部署。但如果你用的是 Java、Go、Python,或者想自由组合技术栈,Vercel 就不够用了。
readme 的答案是------走自建路线,用腾讯云轻量服务器 + 宝塔面板。
为什么是腾讯云?readme 说的:
"国内支持------腾讯云。"
简单直接:国内访问快,备案方便。
二、部署全流程清单:开业前的准备工作
readme 列了完整的部署 checklist:
markdown
1. 花钱买服务器(约35块/月)
2. 买域名 + 备案(10-20天)
3. 配置 HTTPS(SSL 证书)
4. 装 Nginx
5. 配反向代理(解决跨域)
6. 安全配置
六件事,一件都不能少。
1. 买服务器
"轻量云服务器,linux。全量的 linux 部署,命令行成本有点高。"
服务器就是一台在云端 24 小时开机的 Linux 电脑。你用 SSH 连上去,用命令行操作。但纯命令行对新手不友好------所以有了下一个东西:宝塔面板。
2. 宝塔面板:服务器的"控制面板"
"宝塔(BT panel)是一套服务器的管理面板。可视化的,点击操作,完成服务器部署。给服务器装了一个'控制台/操作系统的后台'。"
纯命令行的 Linux 服务器像一台没有桌面的电脑------啥都得敲命令。宝塔面板给它装了一个"图形化后台":
- 想装 Nginx?点一下
- 想建数据库?点一下
- 想看 CPU 使用率?看仪表盘
- 想加站点?填个表单
readme 总结了宝塔的两个优势:
"可视化。自由度高------想怎么部署就怎么部署。"
宝塔安装后默认占用 8888 端口,访问 服务器IP:8888 就能打开面板。网站文件默认放在 /www/wwwroot 目录下------这是宝塔的"网站根目录"。
3. 买域名 + 备案
"买域名?备案 10-20天。"
服务器有了公网 IP,但一串数字不好记------所以需要域名。但国内服务器必须备案,不然域名不让解析到服务器。备案流程 10-20 天,需要身份证、手机号、网站信息。
4. HTTPS
"配置 HTTPS 更安全的 http SSL。"
HTTP 是明文传输,HTTPS 是加密传输。现在主流浏览器对非 HTTPS 的网站会标"不安全"。所以上线前必须配 SSL 证书------宝塔面板里点几下就能申请免费的 Let's Encrypt 证书。
三、用户访问网站的"城市之旅"
readme 提出了今天最核心的问题:
"用户访问网站到底发生了什么?"
这是一个经典面试题。readme 给了完整的答案------分三步。我们用"城市观光"的视角走一遍。
第一站:DNS------城市导航台
arduino
Browser → DNS (Domain Name System) 先找到服务器 Server IP
DNS 返回服务器公网 IP
先查地址,再去敲门
用户敲了个网址,比如 www.example.com。浏览器不认识这串字母------它需要 IP 地址。找谁问?DNS(域名系统)。
DNS 就是互联网的"导航台"。你说"我要去某某餐厅",它告诉你"地址是 123.45.67.89"。
但 DNS 不是查一次就完了------它有多层缓存:
"DNS 查询会缓存在本地:browser → 上网设备系统 → 局域网 → 城域网 → 根服务器 .com .cn"
从上到下依次查:
| 层级 | 在哪 | 缓存多久 | 类比 |
|---|---|---|---|
| 浏览器缓存 | 浏览器内存里 | 几分钟 | 你自己的记忆 |
| 系统缓存 | 操作系统 | 几小时 | 手机里的导航App |
| 局域网缓存 | 路由器 / ISP | 几小时到一天 | 小区物业的告示牌 |
| 城域网缓存 | 运营商 DNS 服务器 | 一天 | 城市导航台 |
| 根服务器 | 全球 13 台根 | --- | 国家地图总局 |
先查自己记得不,不记得问手机,手机不知道问运营商,运营商也不知道就往上追------最终找到权威 DNS 服务器,拿到 IP。
"先查地址,再去敲门。"
第二站:安全组 & 防火墙------小区保安
拿到 IP 后,浏览器带着请求出发了。但到达服务器之前,有两道关卡:
diff
安全组 防火墙
看门人,放不放行
- ip 限流,恶意 ip
- 尽量的少开放端口
readme 明确区分了两者:
"安全组:位置在云厂商网络层(比如腾讯云),作用是控制这台云服务器哪些端口被外网访问。类比:小区大门保安,不让进。"
"防火墙:位置在服务器操作系统内部。"
两道关卡,位置不同,职责相似:
| 关卡 | 位置 | 职责 | 类比 |
|---|---|---|---|
| 安全组 | 云厂商网络层 | 控制哪些端口对外开放 | 小区大门保安 |
| 防火墙 | 服务器操作系统内部 | 更细粒度的访问控制 | 楼内门禁 |
为什么要分两层?因为安全组是第一道防线------"尽量少开放端口"。
readme 举了几个常见端口:
- 80:HTTP 默认端口(必须开)
- 443:HTTPS 默认端口(必须开)
- 3306:MySQL 端口(尽量不开,或只允许特定 IP 访问)
"只开放给一些 IP:dev, production。"
数据库端口绝不能对外开放------万一被黑客扫到,数据就危险了。正确做法是只允许开发环境或生产环境的特定 IP 访问,或者干脆不对外暴露,只允许服务器内部访问。
第三站:Nginx------前台接待员
通过了安全组和防火墙,请求终于到达了服务器。但服务器上可能跑着好几个网站、好几个服务------谁来接这个请求?
Nginx。
readme 给 Nginx 画了一张精准的"岗位说明书":
"Nginx 是一个高性能的 Web 服务器。三件事:接受请求,返回静态文件,或把请求转发给后端(反向代理解决跨域问题)。"
三件事,一个比一个重要。
第一件事:返回静态文件
用户访问 http://175.27.132.28/,Nginx 收到请求,从 /www/wwwroot/xxx/dist/ 目录里找出 index.html,直接返回给浏览器。
"静态资源:react + ts 打包的。route,static route,返回静态资源。"
React + TS 项目经过 npm run build 后产出的 dist/ 目录,就是一堆静态文件(HTML、CSS、JS、图片)。Nginx 的活就是------请求来了,找到对应文件,返回去。
第二件事:反向代理
用户访问 http://175.27.132.28/api/todos------这不是静态文件,是 API 请求。Nginx 怎么办?
它不自己处理,而是把请求转发给后端服务。
bash
:5173 /api/todos vite 配置 mocks 拦截 /api todos
前端发送请求, vite 基础设施拦截?
:5173 /api/todos nginx? 拦截前端请求 反向代理 server 3001
readme 对比了开发环境和生产环境的两种"拦截":
| 环境 | 拦截者 | 转发到 |
|---|---|---|
| 开发环境 | Vite 开发服务器(mocks) | mock 数据 / 代理后端 |
| 生产环境 | Nginx | 后端服务(3001 端口) |
开发时,前端跑在 5173 端口,后端跑在 3001 端口------跨域。Vite 代理帮你转发,解决跨域。
生产时,前端静态文件和 API 请求都从 80(或 443)端口进来------同源,没有跨域问题 。Nginx 一看路径是 /api 开头,就转发给后端的 3001 端口:
javascript
http://175.27.132.28/api/todos
↓ Nginx 反向代理
http://175.27.132.28:3001/todos
↓ Node.js 后端处理
← 返回 JSON
← Nginx 把 JSON 返回给前端
"跨域?不存在。"
一句话道尽反向代理的妙处------前端请求都打给 Nginx,Nginx 决定哪些返回静态文件、哪些转发给后端。前端永远只跟一个源通信,跨域问题从根上消失了。
四、服务器准备:开业前的装修
Node.js 版本管理:nvm
"Node.js 版本管理器 nvm,同时容纳多个 node 版本,指针,当前是哪个版本。node 版本要求不一样,项目依赖不同的 node 版本。"
服务器上可能跑多个项目,有的要 Node 16,有的要 Node 18,有的要 Node 20。怎么办?用 nvm------Node Version Manager。
nvm 可以同时安装多个 Node.js 版本,用一个"指针"指向当前版本。想换版本?一条命令:nvm use 18------指针一挪,当前版本就变了。
"指针,当前是哪个版本。"
这个比喻很形象------nvm 就像一个多档位的开关,拨到哪个档位就是哪个版本。
数据库:MySQL
"安装 Mysql------建立 dev/production 两个库。"
数据库也要分环境------开发库和生产库分开。万一开发环境把数据搞坏了,不影响线上用户。
Nginx
"html 项目 装 nginx。"
静态 HTML 项目直接让 Nginx 托管,不需要 Node.js。前端项目 build 完就是纯静态文件,Nginx 一把梭。
五、本地开发 vs 线上部署:两条流水线
readme 最后对比了前端和后端的开发/构建流程。
前端:从组件到静态文件
arduino
react + ts 产出?
组件,
npm run dev
npm run build dist/ 静态资源文件
| 阶段 | 命令 | 产出 | 干什么 |
|---|---|---|---|
| 开发 | npm run dev |
内存中运行 | 热更新、本地调试 |
| 构建 | npm run build |
dist/ 目录 |
TS → JS,打包压缩 |
开发时 Vite 启动开发服务器,改代码自动热更新。上线前 npm run build 一把,产出 dist/ 静态资源目录------扔给 Nginx 托管。
readme 还提到了前端的一个经典复杂场景:
"瀑布流(小红书)经典复杂的前端用户体验,无限滚动(滚动到底部)。"
瀑布流 + 无限滚动------这是部署后前端最吃性能的场景之一。图片懒加载、虚拟列表、分页加载------这些优化做得好不好,直接影响用户体验。
后端:从 TS 到 JS
后端用 TypeScript 写,但 Node.js 本身只认 JS。所以需要构建流程。
arduino
ts 是大型项目标配
ts -> js -> 热更新运行 ts-node-dev
npm run dev 本地开发
npm run build ts -> js dist/
npm run start 正式启动
node dist/app.js
| 阶段 | 工具 / 命令 | 产出 | 干什么 |
|---|---|---|---|
| 开发 | ts-node-dev + npm run dev |
内存中运行 | 热更新、连开发库 |
| 构建 | npm run build |
dist/ 目录 |
TS 编译成 JS |
| 生产 | npm run start / node dist/app.js |
运行中 | 连生产库 |
readme 特别提了一个常见坑:
"线上的 dev 数据库------数据库链接失败。"
本地开发时 .env 里配的是本地数据库地址,上线后忘了改------数据库连不上。所以 .env 环境变量 是部署的关键配置:数据库地址、端口、账号密码、JWT secret------全都在 .env 里,不同环境不同配置。
".env"
一个 .env 文件,区分开发和生产环境。
六、一张图看懂完整访问链路
javascript
用户在浏览器输入网址
↓
【DNS 解析】
浏览器缓存 → 系统缓存 → 运营商缓存 → 根服务器
拿到服务器公网 IP
↓
【安全组】
云厂商网络层检查端口是否开放
80/443 放行,3306 拒绝
↓
【防火墙】
服务器操作系统层面检查
更细粒度的访问控制
↓
【Nginx】
├── 请求路径是 / 或静态资源?
│ → 返回 dist/ 目录下的静态文件
│
└── 请求路径是 /api/xxx?
→ 反向代理到 Node.js 后端(3001端口)
→ 后端处理 → 查 MySQL → 返回 JSON
→ Nginx 把 JSON 返回给前端
↓
浏览器渲染页面
七、Vercel 派 vs 自建派:两条路的选择
最后回到开头的问题------Vercel 一键部署那么香,为什么还要学自建?
readme 给了答案:
"vercel 云端部署------比较固定。java,go,python 部署自由度。"
Vercel 的好处是简单,但它是"套餐"------你只能在它提供的菜单里选。Next.js 项目最香,React 也行,但你想用 Java + MySQL + Redis + 自定义 Nginx 配置?Vercel 搞不定。
自建服务器的好处是------自由度高。
"想怎么部署就怎么部署。"
宝塔面板 + 腾讯云轻量服务器,一个月 35 块。前端、后端、数据库、Nginx,全在你掌控之中。你想跑几个项目就跑几个,想用什么技术栈就用什么技术栈。
代价是------你得会。
会买服务器、会配安全组、会装 Nginx、会配反向代理、会搞 HTTPS、会管数据库、会处理 Node 版本、会部署前端、会部署后端。
这就是 readme 说的------运维工程师,加分项。
全栈工程师懂一点运维,不是为了当运维,是为了在部署的时候不抓瞎。代码写得再溜,部署不上去等于零。
PS:下次有人问"用户访问网站到底发生了什么",把这篇文章甩给他。从 DNS 到 Nginx 到反向代理到数据库,六个关卡,一个不落。