在上一篇文章中,已经在本地用 Nginx 跑通了静态站点。然而,http://localhost 只有你自己的电脑能访问。如果想让网站发布到互联网,需要将它部署到 。
什么是生产环境
从本地开发到线上生产,核心变化在于服务对象的改变。我们用一张表直观对比:
| 维度 | (Development) | 生产环境 (Production) |
|---|---|---|
| 服务用户 | 你自己 | 互联网真实用户 |
| 运行时间 | 随用随开 | 7 × 24 小时无间断 |
| 网络边界 | 本地局域网 | 互联网公网可达 |
| 数据故障 | 随时重来 | 线上事故 |
要让网站,生产环境必须跨越两个最低门槛:7 × 24 小时运行 与 具备公网 IP。对于个人而言,最快捷、低成本的达成方案就是租用一台 。
为什么选择云服务器
满足 7 × 24 小时运行和公网 IP 这两个条件,最短路径就是云服务器。云厂商对新用户扶持力度大,包年购买一台入门的 2 核 2G(2C2G) 轻量服务器通常只需数十元。
在选购云服务器时,规格选择 2 核 2G,系统镜像首选 Ubuntu 22.04 或 24.04 LTS,避开预装各种面板的系统,保持环境纯净。
您可以通过我的专属优惠链接直接选购:
💡 运维小经验:2C2G 的配置为什么够用? Linux 生产服务器无须运行图形界面,系统本身开销通常不到 200MB。Nginx 作为服务器时也很轻量,2GB 内存足以支撑个人站点和学习环境。
准备工作
SSH 连接服务器
购买云服务器后,你通常会拿到三类信息:
| 信息 | 作用 |
|---|---|
| 公网 IP | 从互联网访问这台服务器 |
| 登录用户 | 不同厂商系统可能不同,推荐使用默认用户 ubuntu |
| 登录密码或 SSH 密钥 | 用来证明“你有权限登录” |
连接服务器有两种常见方式。
方式一:在本地终端使用 SSH
这是最推荐掌握的方式,因为后续部署、上传文件、排查问题都离不开命令行:
ssh ubuntu@your-public-IP如果云厂商默认用户不是 ubuntu,就把命令里的 ubuntu 换成对应用户名,高权限操作通过 sudo 临时提权,能降低误删系统文件、误改全局配置的风险。
whoami可以查看当前登录用户。
首次 SSH 连接会提示确认主机指纹,输入 yes,然后输入服务器登录密码即可登录。
连接成功后,你会看到类似这样的终端提示:
Welcome to Ubuntu 24.04 LTS (GNU/Linux 5.15.0-xx-generic x86_64)
ubuntu@your-server:~$这说明你已经登录到一台运行在云端的 Linux 服务器上了。
方式二:使用云厂商提供的 WebUI
阿里云、腾讯云等控制台通常都提供“远程连接”之类的浏览器入口(腾讯云侧常见为 OrcaTerm 等),不需要你本地先配好 SSH。
WebUI 适合第一次确认服务器能否登录。但它更像备用入口:后续 scp 上传、脚本化部署、CI 自动发布,都会更依赖本地终端里的 SSH。
密码登录和 SSH 密钥有什么区别
SSH 是连接服务器的协议,密码和 SSH 密钥是两种不同的认证方式。
| 认证方式 | 怎么理解 | 优点 | 缺点 |
|---|---|---|---|
| 密码登录 | 输入服务器账号密码 | 简单直观,适合初学者第一次登录 | 容易被弱密码、撞库、暴力破解影响 |
| SSH 密钥 | 本地保存私钥,服务器保存公钥 | 更安全,适合长期使用和自动化部署 | 初学者第一次配置稍微复杂 |
我的建议是:初学者第一次学习可以先用 ubuntu 用户 + 密码登录,跑通完整流程;一旦网站真正长期在线,就切换到 SSH 密钥登录,并关闭 root 密码登录。
把终端这把剑磨快
开发写代码、运维连服务器、排障看日志——软件从业者几乎每天都要和终端、Shell 打交道。GUI 能完成一部分工作,但一到 SSH、脚本、批量操作、远程排查,终端才是真正的主战场。
既然这把剑天天出鞘,就值得认真武装:选一个顺手的终端 App,配好 Shell 与必备插件,让补全、高亮、分屏成为肌肉记忆。App 决定长相,插件决定手感,两者叠加,不冲突。Windows 用户用 PowerShell 即可上手;想和云服务器对齐,装 WSL Ubuntu(Linux 子系统)并用 Windows Terminal 打开——本地与云上同一套 Linux 习惯,不用来回翻译。Mac 自带 Terminal 已够用;想换更现代的 AI 终端,Warp 值得一试。选型见延伸阅读。
按环境把“剑”磨利:
| 使用环境 | 推荐阅读 |
|---|---|
| Mac | Mac 终端起手式:iTerm2、zsh 与插件 |
| Windows | Windows 上使用 WSL Ubuntu 开发 |
| 云服务器 | 云服务器 Linux 起手式优化 |
安装 Nginx
在服务器上安装 Nginx(和本地一样的步骤):
sudo apt update
sudo apt install nginx验证安装:
nginx -v启动 Nginx:
sudo systemctl start nginx如果浏览器访问公网 IP 加载超时,优先检查云控制台的 或“防火墙”是否已放通 TCP 80 端口。
此时在浏览器访问 http://your-public-IP,应该能看到 Nginx 默认欢迎页面。恭喜,你的服务器已经在公网可访问了。
手动部署
现在把本地的网站文件传到服务器上。
本地构建
在本地项目目录中构建生产版本:
pnpm run docs:build构建产物在 docs/.vitepress/dist/ 目录下。
scp 上传到服务器
使用 scp 命令将构建产物上传到服务器:
scp -r docs/.vitepress/dist ubuntu@your-public-IP:~/这条命令做了什么:
scp:基于 SSH 的文件复制命令-r:递归复制目录docs/.vitepress/dist:本地构建产物目录ubuntu@your-public-IP:~/:复制到服务器ubuntu用户的家目录
上传完成后,登录服务器,将文件复制到 Nginx 静态资源目录:
sudo cp -r ~/dist/* /var/www/html/静态资源已经复制到 Nginx 目录,不需要重启 Nginx。刷新浏览器访问 http://your-public-IP,看到你的网站了——这就是 上线。
上线只是开始
到这里,你已经完成了一次完整的“本地 → 服务器”部署。流程是通的,但用不了多久你就会遇到这些问题。
本地和服务器环境不一致
部署不是一步到位的。第一次把网站放到服务器上,大概率不会一次成功——Nginx 配置路径不对、权限不够、文件位置不对,都需要登录服务器反复调试。这意味着你需要同时维护本地开发环境和服务器生产环境两套配置。
回顾一下:本地 Mac 上安装 Nginx 用 brew install nginx,服务器 Ubuntu 上用 apt install nginx,连安装方式都不一样。配置文件路径也不同——Mac 在 /opt/homebrew/etc/nginx/,Ubuntu 在 /etc/nginx/。
好消息是,这些差异通常只需要首次部署时排查清楚,后续就稳定了。坏消息是,可迁移性很差——如果你换了一台服务器(比如从阿里云换到腾讯云),或者换了操作系统版本,之前踩过的坑可能要重新踩一遍。环境配置的细节散落在操作记忆里,没有被固化下来。
当前部署的是纯静态资源,跨平台传输没有问题。但涉及编译产物时,环境差异的影响会更加突出,我们在第 04 篇展开。
每次发布都要手动 scp
软件交付其实分两段,节奏完全不同:
| 阶段 | 角色 | 环境 | 节奏 | 在干什么 |
|---|---|---|---|---|
| 开发 | 开发者 | 本地 | 循环多次 | 改 → 预览 → 再改,直到满意 |
| 部署 | 开发者操作 | 本地 → 云服务器 | 验收后通常一次 | 构建 → 上传 → 落盘 → 公网验证 |
一句话:多次 dev,一次 prod——本地转很多圈;生产发布是“做完再发”,不是边改边发。

本地热更新很快;真正费事的是验收后那一次跨机器发布——构建在本地,上传与落盘在云服务器,验证还要看公网。步骤一多就容易漏,表面都是“页面没变化”。
不过发布链本身可以模板化:构建 → 上传 → 落盘 → 验证。这就是 (Pipeline)的雏形——也是本系列给“运维工作”下定义的入口。
用数学语言定义运维工作
业务工作回答“改什么”:文案、功能、逻辑。
运维工作回答“怎么稳定地让改动变成线上可用状态”:同一套动作可重复、可验证,不因业务细节每次重写。
本系列把(自动化)运维先钉成一句定义:
在约定的规范集合内,用固定结构的运维动作,把任意一次合法业务变更,稳定变成约定的发布结果。
写成数学形态:
| 符号 | 含义 | 在本篇的例子 |
|---|---|---|
| 一次具体的业务变更(源码改动) | 改了一段 Markdown | |
| 规范集合:这套流程承诺能接管的变更范围 | “VitePress 静态站点” | |
| 运维动作:固定结构的动作链 | 构建 → 上传 → 落盘 → 验证 | |
| 约定结果:产物路径、落盘位置、验证方式一致 | dist/ → /var/www/html,公网可访问 |
读法:只要 仍落在 内, 就不改。 业务可以改一万次;运维侧重复同一条动作链。
关键在于 与 的关系,而不是公式本身:
- 业务仍在 内(文案、参数、局部逻辑)—— 不动。
- 变化突破 (换构建工具、引入新中间件、交付形态变了)—— 才演进。
- 演进后,对更大的 重新闭合。
因此,运维工作的稳态是关于 的闭包:集合内业务怎么热闹都与 无关;只有边界被突破时, 才升级一次,然后再次回到“对所有 输出恒定”。
“集合 → 闭包 → 扩容 → 再闭包”——这正是后续 DevOps、CI/CD 能持续运转的基石:让运维动作稳定,业务变化自由。
套回今天这次部署:
- = 构建 → 上传 → 落盘 → 验证(仍是手动四步)
- = “VitePress 静态站点”
- =
dist/经 scp 落到/var/www/html,Nginx 直接服务
下次只改文案,这四步还是这四步——就是“, 不变”。
当前缺口不是定义不成立,而是 的每一步仍靠人敲:定义有了,自动化还没有。
没有版本记录
运维领域的常规做法是:部署前先备份当前版本,再覆盖新版本。比如把旧的 dist 重命名为 dist-20260713,然后再上传新的 dist。这样出了问题至少还能手动回退。
但手动备份有三个绕不开的断点:
第一,备份这一步本身会被跳过。 “这次改动很小,应该没问题”、“备份目录越来越多,占空间”、“上次备份了也没用过”——这些理由每次都成立,结果就是备份时有时无,一旦跳过就回不去。
第二,即使做了备份,也只是“一份旧的目录”。 dist-20260713 对应的是哪次代码变更?改了什么?只有日期,没有上下文。事后想排查“当时为什么挂”,找不到入口。
第三,回退要重做一遍部署动作。 出问题后,要手动把备份目录重命名回去,再手动重启服务。回退本身就是另一轮容易出错的手动流程——一次部署出错的概率不高,但部署 + 回退都要靠人不出错,概率就高了。
这三个断点叠在一起,手动备份有点像错题本:抄了但没看,看了又找不到,找到也用不上——形式上在做,实际上只是一套越来越繁琐的运维琐事。
更隐蔽的是版本不一致。本地构建的 dist 是基于当前代码生成的,但服务器上跑的 Nginx 配置、环境变量、依赖版本可能是上次部署时遗留的。你更新了 dist,却忘了同步 Nginx 配置;或者反过来,改了 Nginx 配置,但 dist 还是旧的。新旧版本混在一起,踩坑是常态——页面白屏、接口 404、样式错乱,排查半天才发现是前后端版本对不上。
手动备份解决不了 版本管理。 它只是把“覆盖”变成了“覆盖前先复制一份”,但“历史可追溯”、“变更可对比”、“回退可一键”这些能力,手动方式都给不了。这些不是备份的问题,是版本管理的问题——下一步我们会看到,Git 天然就有这套能力。
流程旁白
- 谁发起:开发者(本人)决定“可以上线了”。
- 谁执行:同一人完成构建、
scp、落盘、公网验证。 - 谁审批:本步无审批——个人学习场景下,发起即执行。
- 职责边界:业务改动可以任意试;服务器上的发布动作与回退仍未成文,默认全压在执行者记忆里。后续篇会逐步把边界写清楚。
小结
生产环境的两个最低必要条件是 7×24 和公网 IP,云服务器是最短路径。通过 SSH 连接服务器 + scp 上传文件,就能完成一次最朴素的手动部署。
本篇同时埋下运维定义:——规范集合内动作恒定。手动部署能跑通,但 的每一步仍靠人。下一步引入 Git 和 GitHub,先解决版本与可追溯,再谈如何把 跑稳。
思考
- 如果你的服务器宕机了,用户访问会发生什么?生产环境的“7×24”是由谁保证的?
scp和直接在服务器上改文件有什么区别?为什么我们选择在本地构建再上传?- 你在
scp时输错了目标路径,覆盖了服务器上的其他文件,怎么办?
延伸阅读:终端怎么选
终端 App 和 Shell 插件是两层叠加:App 负责长相,插件负责手感。选型优先 稳定、延迟低、习惯顺手——花哨功能其次。
终端 App
| 平台 | 默认 / 推荐 | 一句话特点 |
|---|---|---|
| Windows | PowerShell(系统自带) | 原生上手;命令习惯偏 Windows |
| Windows | Windows Terminal + WSL Ubuntu | 学 Linux 运维的默认组合 |
| macOS | Terminal.app(系统自带) | 够用,配 zsh 已现代化 |
| macOS | iTerm2 | 分屏、搜索、主题成熟 |
| macOS | Warp | AI 终端:补全、解释、工作流内置 |
为什么还要装 Windows Terminal? WSL Ubuntu 自带的是系统 Console 里的基础窗口——能用但丑、无分屏、字体受限。Windows Terminal 是独立的“终端前端”,能挂 WSL、PowerShell、SSH 等多个 shell 到同一窗口,标签页 / 分屏 / 字体 / 配色统一管。这是两个不同的东西,WSL 自带的那个不是 Windows Terminal。
Mac 默认 Terminal 与云服务器命令习惯完全兼容(都是 Unix 一脉),换 Warp / iTerm2 是体验升级,不是必需。
Shell 插件(zsh,Mac / WSL Ubuntu / Linux 都适用)
| 插件 | 作用 |
|---|---|
| oh-my-zsh | zsh 配置框架,主题 + 插件管理 |
| git | 大量 gst / gco / gp 别名 + 提示 |
| zsh-syntax-highlighting | 合法命令变绿、非法变红——输错当下就知道 |
| zsh-autosuggestions | 按历史灰字提示,→ 一键采纳 |
| zsh-completions | 补全 kubectl / docker / aws 等额外命令 |
最小可用组合:oh-my-zsh + git + zsh-syntax-highlighting + zsh-autosuggestions。Windows 原生 PowerShell 走自己体系(PSReadLine、posh-git),不通用。