docs(deployment): update and expand deployment guide with detailed steps and explanations

- Rewrite and expand the deployment guide with more detailed explanations
- Add interactive tooltips to the deployment overview demo
- Include step-by-step instructions for each deployment phase
- Add troubleshooting table for common issues
- Improve structure with clear section headings and flow
This commit is contained in:
sanbuphy
2026-02-14 01:56:09 +08:00
parent f9ade6f924
commit cd2ce9e661
2 changed files with 1115 additions and 312 deletions
@@ -1,70 +1,116 @@
<template> <template>
<div class="deployment-overview"> <div class="deployment-overview">
<div class="demo-header"> <div class="demo-header">
<span class="icon">🚀</span>
<span class="title">服务上线全流程</span> <span class="title">服务上线全流程</span>
<span class="subtitle">从代码到用户眼中的网页</span> <span class="subtitle">从代码到用户眼中的网页</span>
</div> </div>
<div class="demo-content"> <div class="demo-content">
<div class="service-flow"> <div class="flow-section">
<div class="flow-step" :class="{ active: currentStep >= 1 }"> <div class="section-title">开发阶段</div>
<div class="step-icon">📦</div> <div class="service-flow">
<div class="step-title">Build</div> <div class="flow-step" :class="{ active: currentStep >= 1 }" @mouseenter="(e) => showTooltip(e, 'git')" @mouseleave="hideTooltip">
<div class="tech-term">源码可执行文件</div> <div class="step-title">Git</div>
</div> <div class="tech-term">代码版本控制</div>
<span class="flow-arrow"></span> </div>
<div class="flow-step" :class="{ active: currentStep >= 2 }"> <span class="flow-arrow"></span>
<div class="step-icon">🖥</div> <div class="flow-step" :class="{ active: currentStep >= 2 }" @mouseenter="(e) => showTooltip(e, 'cicd')" @mouseleave="hideTooltip">
<div class="step-title">Server</div> <div class="step-title">CI/CD</div>
<div class="tech-term">24h运行的电脑</div> <div class="tech-term">自动化流水线</div>
</div> </div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 3 }">
<div class="step-icon"></div>
<div class="step-title">Deploy</div>
<div class="tech-term">代码放到服务器</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 4 }">
<div class="step-icon">🔀</div>
<div class="step-title">Nginx</div>
<div class="tech-term">接收请求分发响应</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 5 }">
<div class="step-icon"></div>
<div class="step-title">DNS</div>
<div class="tech-term">域名IP地址</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 6 }">
<div class="step-icon"></div>
<div class="step-title">HTTPS</div>
<div class="tech-term">加密数据传输</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 7 }">
<div class="step-icon"></div>
<div class="step-title">CDN</div>
<div class="tech-term">就近访问加速</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 8 }">
<div class="step-icon">🔄</div>
<div class="step-title">CI/CD</div>
<div class="tech-term">自动化部署流程</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 9 }">
<div class="step-icon"></div>
<div class="step-title">Monitor</div>
<div class="tech-term">监控运行状态</div>
</div> </div>
</div> </div>
<div class="flow-section">
<div class="section-title">构建阶段</div>
<div class="service-flow">
<div class="flow-step" :class="{ active: currentStep >= 3 }" @mouseenter="(e) => showTooltip(e, 'test')" @mouseleave="hideTooltip">
<div class="step-title">Test</div>
<div class="tech-term">自动化测试</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 4 }" @mouseenter="(e) => showTooltip(e, 'build')" @mouseleave="hideTooltip">
<div class="step-title">Build</div>
<div class="tech-term">编译打包</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 5 }" @mouseenter="(e) => showTooltip(e, 'artifact')" @mouseleave="hideTooltip">
<div class="step-title">Artifact</div>
<div class="tech-term">构建产物存储</div>
</div>
</div>
</div>
<div class="flow-section">
<div class="section-title">部署阶段</div>
<div class="service-flow">
<div class="flow-step" :class="{ active: currentStep >= 6 }" @mouseenter="(e) => showTooltip(e, 'server')" @mouseleave="hideTooltip">
<div class="step-title">Server</div>
<div class="tech-term">服务器环境</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 7 }" @mouseenter="(e) => showTooltip(e, 'deploy')" @mouseleave="hideTooltip">
<div class="step-title">Deploy</div>
<div class="tech-term">部署应用</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 8 }" @mouseenter="(e) => showTooltip(e, 'nginx')" @mouseleave="hideTooltip">
<div class="step-title">Nginx</div>
<div class="tech-term">反向代理</div>
</div>
</div>
</div>
<div class="flow-section">
<div class="section-title">网络配置</div>
<div class="service-flow">
<div class="flow-step" :class="{ active: currentStep >= 9 }" @mouseenter="(e) => showTooltip(e, 'https')" @mouseleave="hideTooltip">
<div class="step-title">HTTPS</div>
<div class="tech-term">SSL证书</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 10 }" @mouseenter="(e) => showTooltip(e, 'cdn')" @mouseleave="hideTooltip">
<div class="step-title">CDN</div>
<div class="tech-term">内容分发加速</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 11 }" @mouseenter="(e) => showTooltip(e, 'dns')" @mouseleave="hideTooltip">
<div class="step-title">DNS</div>
<div class="tech-term">域名解析</div>
</div>
</div>
</div>
<div class="flow-section">
<div class="section-title">运维阶段</div>
<div class="service-flow">
<div class="flow-step" :class="{ active: currentStep >= 12 }" @mouseenter="(e) => showTooltip(e, 'monitor')" @mouseleave="hideTooltip">
<div class="step-title">Monitor</div>
<div class="tech-term">监控状态</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 13 }" @mouseenter="(e) => showTooltip(e, 'log')" @mouseleave="hideTooltip">
<div class="step-title">Log</div>
<div class="tech-term">日志收集</div>
</div>
<span class="flow-arrow"></span>
<div class="flow-step" :class="{ active: currentStep >= 14 }" @mouseenter="(e) => showTooltip(e, 'alert')" @mouseleave="hideTooltip">
<div class="step-title">Alert</div>
<div class="tech-term">告警通知</div>
</div>
</div>
</div>
<Teleport to="body">
<Transition name="fade">
<div v-if="tooltipVisible" class="tooltip-box" :style="tooltipStyle">
<div class="tooltip-title">{{ tooltipContent.title }}</div>
<div class="tooltip-content" v-html="tooltipContent.content"></div>
</div>
</Transition>
</Teleport>
<div class="info-box"> <div class="info-box">
<span class="icon">💡</span>
<strong>核心原则</strong>小步快跑 先上线MVP 逐步完善 <strong>核心原则</strong>小步快跑 先上线MVP 逐步完善
</div> </div>
</div> </div>
@@ -72,9 +118,369 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, reactive } from 'vue'
const currentStep = ref(0) const currentStep = ref(0)
const tooltipVisible = ref(false)
const tooltipStyle = reactive({
top: '0px',
left: '0px'
})
const tooltipContent = reactive({
title: '',
content: ''
})
const tooltipData = {
git: {
title: 'Git - 代码管理',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>想象一下,你写论文的时候,每次修改都Ctrl+S保存一个新文件:论文_v1.doc、论文_v2.doc、论文_v3.doc...这样你可以随时找回之前的版本。Git 就是干这个事情的,不过它是专门管代码的"另存为"。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>如果你是一个人开发,可能感觉不到它的好处。但如果是团队协作,5个人同时改一个文件,没有Git的话简直是一场灾难——你覆盖我的代码,我覆盖你的代码,最后谁也不知道哪个版本是最新的。</p>
<p>有了Git之后,每个人都在自己的"分支"上改东西,改完后再合并到一起。就像几个人同时装修一套房子,每个人负责不同的房间,最后统一验收合并。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>最常用的平台有 GitHub、GitLab、Gitee(国内的,访问速度快)。你在本地写完代码后,用 <code>git add .</code> 把改动暂存起来,用 <code>git commit -m "修复了登录bug"</code> 提交本次修改,然后用 <code>git push</code> 把代码推送到云端。</p>
<p>下次想看看之前改了什么,用 <code>git log</code> 就能看到完整的修改历史。</p>
</div>
`
},
cicd: {
title: 'CI/CD - 自动化的力量',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>你可以把它想象成一个全年无休的"机器人助手"。以前你每次上线新功能,都需要手动做一堆事情:打开电脑、登录服务器、拉取最新代码、安装依赖、运行测试、打包、部署...累死人不说,还容易漏掉某个步骤。</p>
<p>有了CI/CD之后,你只需要把代码往GitHub上一推,机器人就自动帮你完成剩下的所有事情:拉代码 → 安装依赖 → 跑测试 → 打包构建 → 部署上线,全部自动完成,你该干嘛干嘛去。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>第一个好处是省事儿,你不用每次都手动操作了。第二个好处是安全——机器人不会忘记跑测试,不会喝多了手抖打错命令。第三个好处是快,可能原本手动需要半小时的活,机器人3分钟就干完了。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>GitHub Actions 是最简单的选择,因为它集成在GitHub里,你只需要在项目里加一个 .github/workflows 目录,放一个配置文件就行。配置文件里写清楚:什么时候触发、要做哪些步骤。</p>
<p>配置文件大概长这样:代码推送后 -> 安装依赖 -> 运行测试 -> 打包 -> 部署到服务器。</p>
</div>
`
},
test: {
title: 'Test - 自动化测试',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>你可以理解为"考前模拟卷"。正式上线之前,先让电脑跑一遍测试用例,看看有没有bug。这就像考试前做几套模拟题,发现知识盲区赶紧补上,总比真正上考场才发现不会强。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>手动测试太累了,而且很容易漏掉一些边界情况。比如你改了一个登录功能的代码,表面上看没问题,但实际上可能把"忘记密码"功能给弄坏了。人工测试很容易忽略这种"顺带手"的改动,但电脑跑测试用例的话,所有相关功能都会被检查一遍。</p>
<p>而且测试跑一次就行了,下次改代码再跑一次,不用你每次都手动点点点。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>前端项目常用 Jest 或 Vitest 来写测试。你需要先写测试用例,比如"点击登录按钮,输入正确的用户名密码,应该跳转首页"。写好之后,每次 <code>npm run test</code> 就能自动跑这些测试。</p>
<p>不用追求100%覆盖率,先把核心业务流程测了就行,比如用户注册、登录、下单、支付这些关键路径。</p>
</div>
`
},
build: {
title: 'Build - 把代码变成可运行的包',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>你写的 Vue/React 代码,浏览器根本看不懂。浏览器只认识纯HTML、CSS、JavaScript这些"原始语言"。</p>
<p>这就好像你写中文论文要发表到国际期刊,得先翻译成英文一样。Build 就是这个"翻译"的过程——把你写的高级代码(Vue/React),翻译成浏览器能看懂的普通代码(HTML/CSS/JS)。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>不只是翻译,Build 还会帮你做很多优化:</p>
<ul>
<li><strong>压缩</strong>:把代码里的空格、注释全删掉,变量名也改成短的,文件能小很多,用户加载就快</li>
<li><strong>合并</strong>:你可能写了10个JS文件,打包后变成1个大文件,减少HTTP请求</li>
<li><strong>混淆</strong>:代码压缩后人类基本看不懂了,也算是一种"加密"吧</li>
<li><strong>缓存</strong>:文件名会加一串哈希值(比如 app.abc123.js),代码变了文件名就变,浏览器就会重新下载,没变的就用缓存</li>
</ul>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>运行 <code>npm run build</code>(或 <code>yarn build</code>),然后去项目根目录的 dist 文件夹里找打包好的文件。这些就是最终要上传到服务器的文件。</p>
</div>
`
},
artifact: {
title: 'Artifact - 构建产物存储',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>你可以理解为"成品仓库"。Build 之后产生的文件(dist目录里的那些HTML/CSS/JS),不能直接扔掉,得找个地方存起来。</p>
<p>这就像做好的快递包裹,不是放在配送站就行,得存进仓库里,等要发货的时候再取。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>第一,每次都重新Build太慢了,存起来下次直接用。第二,你可以给每次Build打上版本标签(比如 v1.0.0、v1.0.1),万一上线后发现有bug,可以一键回滚到上一个版本。第三,如果你有多个服务器部署,可以从仓库统一拉取,不用每个服务器都Build一次。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>简单方案:直接把Build产物上传到阿里云OSS或AWS S3这些云存储。</p>
<p>高级方案:使用 Docker Registry(如果你用Docker的话)或 Nexus。这些工具可以帮你管理不同版本的构建产物,还能设置访问权限。</p>
</div>
`
},
server: {
title: 'Server - 租一台永远不关机的电脑',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>就是你租的一台放在专业机房的电脑,24小时不关机,网络永远接通。这东西你肯定见过——就是那些互联网公司说的"服务器"。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>总不能让你自己的电脑24小时开着吧?且不说电费,你家网络也没那么稳定,万一断网了网站就访问不了。而且你家的电脑没有公网IP,别人根本找不到你。</p>
<p>服务器放在专业机房,电力有备用电源,网络是千兆光纤,还有专人维护,温度湿度都控制得好好的。你只需要SSH远程登录上去管理就行。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>国内推荐阿里云、腾讯云,新用户首年只要几十块钱。国外推荐 AWS、DigitalOcean(支持支付宝)。</p>
<p>配置不用太高,1核2G内存够跑个人项目了。学生的话阿里云有学生认证,更便宜。</p>
<p>买完服务器后,你会拿到一个IP地址(像 123.45.67.89 这样的)和密码,用 SSH 客户端(如 Termius、Xshell)登录上去就能管理了。</p>
</div>
`
},
deploy: {
title: 'Deploy - 把代码上传到服务器',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>就是把你本地Build好的文件,上传到服务器上,然后启动服务让网站跑起来。</p>
<p>这就像你开餐厅,厨房准备好了(代码写完了Build好了),得把菜端上餐桌(部署到服务器),客人才能吃到。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>代码在你本地电脑上,只有你自己能访问。要让全世界的用户都能访问,必须得部署到服务器上。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p><strong>最简单的方式</strong>:用FTP工具(如 FileZilla)手动上传文件到服务器。</p>
<p><strong>推荐的方式</strong>:用 Docker 部署。你需要先在服务器上安装Docker,然后写一个 Dockerfile(就像食谱一样,告诉我怎么运行你的应用),最后 <code>docker build</code> + <code>docker run</code> 就搞定。</p>
<p>Docker 的好处是"一次构建,到处运行"——在本地能跑,放到服务器上也一定能跑,不会出现"在我电脑上能跑啊"这种问题。</p>
</div>
`
},
nginx: {
title: 'Nginx - 站在门口的服务员',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>Nginx 就像是餐厅门口的前台服务员。用户来了,先找 Nginx,Nginx 再根据情况把用户分配到不同的"厨师"(你的应用)那里。</p>
<p>它站在服务器门口,帮你的应用挡刀干很多累活:同时接待很多用户、处理静态文件(图片/CSS/JS)、缓存响应等等。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>如果没有 Nginx,让你的应用直接面对用户,会有很多问题:</p>
<ul>
<li>一个应用只能跑一个端口,用户全挤在一起</li>
<li>处理静态文件很慢,拖累业务逻辑</li>
<li>没有负载均衡,一台服务器扛不住</li>
</ul>
<p>Nginx 就是来解决这些问题的,它可以监听80端口(HTTP默认端口),然后把请求转发到你应用的端口(比如3000)。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>Nginx 配置文件看起来复杂,其实核心就几行:</p>
<pre>server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
}
location /static/ {
alias /var/www/static/;
}
}</pre>
<p>意思就是:监听80端口,域名是 yourdomain.com,用户访问 / 路径就转发到本地3000端口的应用,访问 /static/ 就直接返回静态文件。</p>
</div>
`
},
https: {
title: 'HTTPS - 给网站装把锁',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>HTTPS 就是 HTTP + SSL/TLS,相当于在 HTTP 外面加了一层加密。简单说就是给你网站装一把"锁",用户和服务器之间传输的数据都是加密的,第三者就算截获了也看不懂。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>没有HTTPS的话,用户在你网站输入的密码、填的个人信息,都是明文传输的,中间的任何人都能偷看到。现在浏览器很聪明,会给没有HTTPS的网站显示"不安全",用户一看就不敢用了。</p>
<p>而且Google等搜索引擎也会优先收录HTTPS的网站,影响SEO。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p><strong>最省钱的方式</strong>:用 Let's Encrypt,完全免费。配合 Certbot 工具可以自动申请和续期,三四年不用管。</p>
<p><strong>最简单的方式</strong>:用 Cloudflare,它提供免费的HTTPS证书,而且是DNS级别的,你只需要把域名DNS迁到Cloudflare就行,证书自动搞定。</p>
<p>证书安装好后,Nginx 配置里加一行 <code>ssl_certificate</code> 指向证书文件,再加个 <code>listen 443 ssl</code> 就行。</p>
</div>
`
},
cdn: {
title: 'CDN - 让用户就近访问',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>CDN 就是"内容分发网络"。想象一下,你在全中国甚至全球各地都开了分店,用户访问时自动被引导到最近的那家店拿东西,而不是都跑你总店来。</p>
<p>具体来说,CDN会在各地部署"边缘节点",把网站的静态资源(图片、CSS、JS)缓存到这些节点上。用户访问时,自动连接到离他最近的节点拿资源,速度当然就快了。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>如果没有CDN,全世界用户都从你一个服务器下载资源。美国的用户要跨越整个太平洋来加载,速度慢死了。而且你服务器带宽是有限的,人多了就卡。</p>
<p>有了CDN,美国用户从美国的节点拿资源,日本用户从日本的节点拿,大家都不跨海了,速度飞快,服务器压力也小了。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p><strong>最简单的方式</strong>:用 Cloudflare,注册账号,把域名DNS改成它给的DNS地址,就完事儿了。全程不需要配置服务器。</p>
<p>国内的话阿里云CDN、腾讯云CDN都不错,不过需要你把域名DNS改过去,还要在CDN控制台添加域名配置。</p>
<p>一般配置思路:CDN 域名 → 指向你服务器IP → 用户访问时CDN回源到你服务器拉取资源并缓存。</p>
</div>
`
},
dns: {
title: 'DNS - 域名的作用',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>DNS 就是"域名系统",相当于一本"电话号码簿"。用户输入的是好记的域名(如 example.com),但电脑只认IP地址(如 192.168.1.1),DNS就是负责把域名翻译成IP地址的。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>你总不能告诉用户"请访问 123.45.67.89 这个IP地址"吧?既不好记也不专业。买一个域名(如 myproject.com),用户输入域名就能访问,这才是正确的姿势。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>第一步:买域名。阿里云、腾讯云、GoDaddy 都能买,一年几十块。</p>
<p>第二步:配置DNS记录。最常见的是"A记录"——把域名指向服务器IP。</p>
<p>配置示例:在DNS控制台添加一条记录:</p>
<ul>
<li>记录类型:A</li>
<li>主机记录:@(或者 www</li>
<li>记录值:你的服务器IP(如 123.45.67.89</li>
</ul>
<p>第三步:等生效。DNS修改后需要几分钟到24小时全球生效,可以用 <code>ping 你的域名</code> 命令检查是否生效。</p>
</div>
`
},
monitor: {
title: 'Monitor - 监控网站的健康状态',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>监控就是给服务器装一个"体检仪",实时监测各项指标:CPU使用率、内存占用、磁盘空间、网络流量、应用响应时间、错误率等等。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>服务器不会说话,它不舒服了不会主动告诉你。等用户打电话过来说"网站打不开了",你才去处理黄花菜都凉了。</p>
<p>有了监控,你可以设置阈值报警:CPU超过80%提醒我、内存超过90%提醒我、响应时间超过3秒提醒我。这样你可以在问题变严重之前就发现并处理。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p><strong>最简单的方式</strong>:用 Uptime Robot。注册账号,添加你的网站URL,它会每5分钟检查一次网站是否正常。免费版本可以监控50个网站,不支持微信/邮件通知但支持短信。网站挂了会发邮件通知你。</p>
<p><strong>进阶方式</strong>:用阿里云监控、腾讯云监控(如果你服务器在这些云商买的话,自带监控功能)。</p>
<p><strong>专业方式</strong>:用 Prometheus + Grafana,可以监控各种指标并做出漂亮的可视化图表,不过配置稍微复杂一些。</p>
</div>
`
},
log: {
title: 'Log - 出了事上哪查原因',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>日志就是应用运行时的"日记本",记录了程序运行过程中的各种信息:谁在什么时候访问了什么接口、返回了什么结果、有没有报错、报错信息是什么...</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>出问题时,日志就是破案的关键线索。没有日志,你只能靠"玄学"猜问题。有了日志,你可以清楚地看到:用户在几点几分访问了哪个功能,程序在哪一行报错了,错误信息是什么。</p>
<p>就像汽车的黑匣子——正常行驶时没人看它,但出事故了就得靠它还原真相。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p><strong>最简单的方式</strong>:把日志写到服务器的文件里(logs/access.log)。出问题时SSH登录服务器,用 <code>grep "关键词" logs/app.log</code> 搜索相关日志。</p>
<p><strong>进阶方式</strong>:用专业工具收集日志,比如 Loki(免费)、ELKElasticsearch + Logstash + Kibana,功能强大但有点复杂)、或者国内的日志服务。</p>
<p>建议日志里至少包含这些信息:时间戳、请求ID(traceId)、操作类型、关键参数、返回结果、错误堆栈。</p>
</div>
`
},
alert: {
title: 'Alert - 出问题了自动通知你',
content: `
<div class="tooltip-section">
<h4>这是什么东西?</h4>
<p>告警就是当监控系统发现问题(如服务器挂了、CPU爆了、错误率飙升),自动发消息通知你。你不用一直盯着监控面板看,它会自动叫你来处理。</p>
</div>
<div class="tooltip-section">
<h4>为什么要用这个?</h4>
<p>你不可能24小时盯着监控面板看吧?就算你可以,你睡觉的时候怎么办?告警系统就像烟雾报警器——着火了自动响,不用你一直盯着有没有烟。</p>
</div>
<div class="tooltip-section">
<h4>怎么用?</h4>
<p>最常用的方式是建一个钉钉群或企业微信群,然后添加机器人。拿到机器人Webhook地址后,配置到监控工具里就行。</p>
<p>告警通知渠道优先级建议:</p>
<ul>
<li><strong>紧急(网站完全挂掉)</strong>:发短信 + 打电话,必须马上知道</li>
<li><strong>严重(错误率飙升)</strong>:发钉钉/微信消息,看到就处理</li>
<li><strong>一般(CPU偏高)</strong>:发邮件汇总,一天看一次就行</li>
</ul>
<p>别什么问题都发短信把自己烦到了,设好告警级别很重要。</p>
</div>
`
}
}
function showTooltip(event, key) {
const data = tooltipData[key]
if (!data) return
tooltipContent.title = data.title
tooltipContent.content = data.content
const rect = event.target.getBoundingClientRect()
const tooltipWidth = 480
const tooltipMaxHeight = 550
const padding = 16
let left = rect.right + padding
let top = rect.top
if (left + tooltipWidth > window.innerWidth) {
left = rect.left - tooltipWidth - padding
}
if (left < 0) {
left = padding
}
if (top + tooltipMaxHeight > window.innerHeight) {
top = window.innerHeight - tooltipMaxHeight - padding
}
if (top < 0) {
top = padding
}
tooltipStyle.top = `${top}px`
tooltipStyle.left = `${left}px`
tooltipVisible.value = true
}
function hideTooltip() {
tooltipVisible.value = false
}
</script> </script>
<style scoped> <style scoped>
@@ -82,24 +488,23 @@ const currentStep = ref(0)
border: 1px solid var(--vp-c-divider); border: 1px solid var(--vp-c-divider);
border-radius: 8px; border-radius: 8px;
background: var(--vp-c-bg-soft); background: var(--vp-c-bg-soft);
padding: 0.75rem; padding: 1rem;
margin: 1rem 0; margin: 1rem 0;
position: relative;
} }
.demo-header { .demo-header {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
margin-bottom: 0.5rem; margin-bottom: 1rem;
} padding-bottom: 0.75rem;
border-bottom: 1px solid var(--vp-c-divider);
.demo-header .icon {
font-size: 1.25rem;
} }
.demo-header .title { .demo-header .title {
font-weight: bold; font-weight: bold;
font-size: 1rem; font-size: 1.1rem;
} }
.demo-header .subtitle { .demo-header .subtitle {
@@ -108,32 +513,33 @@ const currentStep = ref(0)
margin-left: 0.5rem; margin-left: 0.5rem;
} }
.intro-text {
font-size: 0.85rem;
color: var(--vp-c-text-2);
line-height: 1.5;
margin-bottom: 0.75rem;
padding: 0.5rem;
background: var(--vp-c-bg);
border-radius: 6px;
}
.intro-text strong {
color: var(--vp-c-brand-1);
font-weight: 500;
}
.demo-content { .demo-content {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.flow-section {
margin-bottom: 1rem;
}
.flow-section:last-of-type {
margin-bottom: 0.5rem;
}
.section-title {
font-size: 0.75rem;
font-weight: 600;
color: var(--vp-c-brand-1);
margin-bottom: 0.5rem;
padding-left: 0.25rem;
}
.service-flow { .service-flow {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
gap: 0.25rem; gap: 0.25rem;
overflow-x: auto; overflow-x: auto;
padding-bottom: 0.5rem; padding-bottom: 0.25rem;
} }
.flow-step { .flow-step {
@@ -141,17 +547,20 @@ const currentStep = ref(0)
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 0.25rem; gap: 0.25rem;
padding: 0.5rem; padding: 0.5rem 0.75rem;
background: var(--vp-c-bg); background: var(--vp-c-bg);
border: 2px solid var(--vp-c-divider); border: 2px solid var(--vp-c-divider);
border-radius: 8px; border-radius: 8px;
transition: all 0.2s ease; transition: all 0.2s ease;
flex-shrink: 0; flex-shrink: 0;
min-width: 85px; min-width: 80px;
cursor: pointer;
} }
.flow-step:hover { .flow-step:hover {
border-color: var(--vp-c-brand); border-color: var(--vp-c-brand);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
} }
.flow-step.active { .flow-step.active {
@@ -159,20 +568,16 @@ const currentStep = ref(0)
background: var(--vp-c-brand-soft); background: var(--vp-c-brand-soft);
} }
.step-icon {
font-size: 1rem;
}
.step-title { .step-title {
font-weight: 600; font-weight: 600;
font-size: 0.75rem; font-size: 0.8rem;
color: var(--vp-c-text-1); color: var(--vp-c-text-1);
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
} }
.tech-term { .tech-term {
font-size: 0.6rem; font-size: 0.65rem;
color: var(--vp-c-text-2); color: var(--vp-c-text-2);
text-align: center; text-align: center;
white-space: normal; white-space: normal;
@@ -180,21 +585,117 @@ const currentStep = ref(0)
} }
.flow-arrow { .flow-arrow {
font-size: 1rem; font-size: 0.9rem;
color: var(--vp-c-text-3); color: var(--vp-c-text-3);
flex-shrink: 0; flex-shrink: 0;
} }
.info-box { .info-box {
background: var(--vp-c-bg-alt); background: var(--vp-c-bg-alt);
padding: 0.5rem; padding: 0.75rem;
border-radius: 6px; border-radius: 6px;
font-size: 0.8rem; font-size: 0.85rem;
color: var(--vp-c-text-2); color: var(--vp-c-text-2);
margin-top: 0.5rem; margin-top: 0.75rem;
} }
.info-box .icon { .info-box strong {
margin-right: 0.25rem; color: var(--vp-c-text-1);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.15s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
<style>
.tooltip-box {
position: fixed;
max-width: 480px;
padding: 1.25rem;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
border-radius: 12px;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
z-index: 9999;
}
.tooltip-title {
font-weight: 600;
font-size: 1rem;
color: var(--vp-c-brand-1);
margin-bottom: 1rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--vp-c-divider);
}
.tooltip-content {
max-height: 500px;
overflow-y: auto;
}
.tooltip-section {
margin-bottom: 1.25rem;
}
.tooltip-section:last-child {
margin-bottom: 0;
}
.tooltip-section h4 {
font-size: 0.85rem;
font-weight: 600;
color: var(--vp-c-text-1);
margin-bottom: 0.5rem;
}
.tooltip-section p {
font-size: 0.8rem;
color: var(--vp-c-text-2);
line-height: 1.7;
margin-bottom: 0.5rem;
}
.tooltip-section ul {
margin: 0.5rem 0;
padding-left: 1.25rem;
}
.tooltip-section li {
font-size: 0.8rem;
color: var(--vp-c-text-2);
line-height: 1.6;
margin-bottom: 0.35rem;
}
.tooltip-section pre {
background: var(--vp-c-bg-soft);
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
padding: 0.75rem;
overflow-x: auto;
font-size: 0.75rem;
color: var(--vp-c-text-1);
line-height: 1.5;
margin: 0.5rem 0;
}
.tooltip-section code {
background: var(--vp-c-bg-soft);
padding: 0.15rem 0.4rem;
border-radius: 4px;
font-size: 0.75rem;
color: var(--vp-c-brand-1);
}
.tooltip-section strong {
color: var(--vp-c-text-1);
font-weight: 600;
} }
</style> </style>
+521 -219
View File
@@ -1,4 +1,4 @@
# 服务上线之旅 # 服务上线之旅:从零开始的完整指南
::: tip 🎯 核心问题 ::: tip 🎯 核心问题
**代码在本地跑得好好的,怎么让全世界的人都能访问?** **代码在本地跑得好好的,怎么让全世界的人都能访问?**
@@ -8,19 +8,15 @@
## 1. 为什么要"服务上线" ## 1. 为什么要"服务上线"
想象小明在家做了一桌子菜,现在要开餐厅让所有人来吃。这可不是"把菜端出去"那么简单 想象一下,你在自己家里做了一桌子菜,非常好吃。但问题是,只有自家人能吃到,邻居、保安、陌生人他们都尝不到
怎么办?你需要**把菜端到餐厅里**。这就是"服务上线"要做的事——把你写的代码,从个人电脑,搬到一个7×24小时永远开着的"公共电脑"上。这样任何人只要能上网,就能访问你的网站。
<DeploymentOverviewDemo /> <DeploymentOverviewDemo />
**服务上线是一场"搬家+开业"的大工程** 服务上线涉及很多环节。就像开餐厅不仅仅是端菜出去,你还需要租店面、装修、办执照、雇服务员等。开发网站也是同理。从代码到用户能访问的网站,中间隔着很多步骤。需要一步步完成构建、部署、配置网络、保证安全等工作。
1. **构建** → 打包代码成服务器能懂的格式
2. **服务器** → 租一台永远不关机的电脑 下面我会把整个流程拆开来讲。每个环节都掰碎、揉细。保证连完全没基础的小白也能看懂。
3. **部署** → 把代码上传到服务器
4. **环境** → 配置 Nginx、Node.js
5. **域名** → 配置 DNS,让用户能找到
6. **HTTPS** → 安装证书,保护数据安全
7. **CI/CD** → 自动化部署,解放双手
8. **监控** → 盯控和备份,守住底线
--- ---
@@ -28,373 +24,679 @@
### 2.1 为什么要构建? ### 2.1 为什么要构建?
浏览器只认识 HTML/CSS/JS,不认识 Vue 组件。**构建(Build)就是"打包外卖"的过程**。 新手常问:代码写好了,为什么不能直接放到服务器上让用户访问?
要回答这个问题,先搞清楚你写的代码是什么格式。你可能用 Vue、React、Express、Koa 等框架。这些框架有一个共同特点:**它们不是给浏览器或服务器直接用的**。
举个例子。你写 Vue 代码时,是不是用过 `<template>``<script setup>` 这种标签?这种语法只有 Vue 认识。浏览器根本看不懂。浏览器只认识三种语言:HTML(网页结构)、CSS(网页样式)、JavaScript(网页逻辑)。Vue 组件语法对浏览器来说就像天书,完全无法理解。
所以在把代码放到服务器之前,必须做一件重要的事:**把它翻译成浏览器能看懂的语言**。这个翻译过程叫做"构建"Build)。
### 2.2 构建具体做什么?
构建不只是翻译。它还会做很多优化。让网站跑起来更快、更省资源。详细说说它具体都干了哪些活:
**第一步:解析依赖**
写代码时,会用到各种第三方库。比如 Vue、Vue Router、Axios、Vite 等。这些库不可能每次都让用户从 npm 下载。那样太慢了。构建工具会分析代码,把所有依赖找出来。然后把它们"打包"到一起。
**第二步:编译转换**
这是最核心的一步。把 Vue 组件编译成 HTML 和 JavaScript。把 SASS/LESS 编译成 CSS。把 ES6+ 新语法转换成兼容性更好的 ES5 代码。这步完成后,代码就从"开发者能看懂的格式"变成"机器能执行的格式"。
**第三步:压缩混淆**
压缩就是把所有空格、换行、注释删掉。把变量名从英文单词改成单个字母。比如 `userName` 变成 `a``calculateTotalPrice` 变成 `b`。这样文件大小大幅减小。用户下载起来就快多了。混淆后的代码人类基本看不懂。也能起到一点"保护代码"的作用。
**第四步:代码分割**
可能写了10个页面。每个页面有自己的代码。但用户可能只访问其中一个页面。为什么要下载其他9个页面的代码?构建工具会把代码分割成多个小块。用户访问哪个页面就下载哪个页面的代码。这就是"按需加载"。能大幅提升首次访问的速度。
**第五步:生成哈希**
这是非常重要的一步。但很多人会忽略。构建完成后,文件名会变成类似 `app.abc123.js``vendor.def456.css` 这样的格式。后面那串字母数字混合的字符串叫"哈希"。
哈希的作用是:当代码有任何改动时,哈希值就会变化。浏览器就知道"这个文件变了,需要重新下载"。没变的文件,浏览器继续使用缓存。不用重复下载。这样既能保证用户看到最新代码,又能充分利用缓存提升速度。
<DeploymentBuildDemo /> <DeploymentBuildDemo />
**构建做了什么** ### 2.3 怎么执行构建?
- **翻译**Vue → HTML/CSS/JS
- **压缩**:减小代码体积(省流量、加载快) 大多数现代前端项目都已经配好构建工具。只需要记住一个命令:
- **合并**:多个文件 → 几个大包(减少请求)
- **哈希**:文件名加指纹(`app.abc123.js`),缓存友好
```bash ```bash
# 如果用 npm
npm run build npm run build
# 如果用 yarn
yarn build
# 如果用 pnpm
pnpm build
``` ```
运行完后,去项目根目录找一个叫 `dist` 的文件夹(有时也叫 `build``.output`)。里面就是构建好的所有文件。这些文件就是最终要上传到服务器的东西。不需要再做任何修改。直接拖到服务器上就行。
### 2.4 构建产物里有什么?
打开 dist 文件夹,会看到里面主要是三类文件:
- **HTML文件**:通常叫 `index.html`。这是入口文件。浏览器首先加载的就是它。
- **JS文件**:所有 JavaScript 代码。可能是1个也可能是好几个。
- **CSS文件**:所有样式代码。可能内联在 HTML 里,也可能是单独的 CSS 文件。
如果是比较复杂的后端项目(比如 Node.js),构建产物可能是一个可执行文件,或者一个 Docker 镜像。但原理是一样的:把代码变成服务器能直接运行的形式。
--- ---
## 3. 服务器:找房子 ## 3. 服务器:找一台永远不关门的"房子"
### 3.1 服务器是什么? ### 3.1 服务器到底是什么?
服务器 = **一台永远不关机、连着互联网的电脑** 很多人第一次听到"服务器",觉得是什么高大上的神秘设备。其实没那么复杂。**服务器就是一台电脑**。一台永远不关机、一直插着网线的电脑。
可能有人问:我自己家里不是有电脑吗?为什么要额外花钱租服务器?
这个问题问得好。帮你分析一下:
首先,你家的电脑不可能24小时开着。你要出门、要睡觉、偶尔还会死机重启。但服务器不一样。它专门用来干这个。可以365天全年无休地运行。网站随时都能访问。
其次,你家的网络也不行。家用宽带的上传速度通常很慢。而且家用宽带的 IP 是动态变化的。今天是这个 IP,明天可能就变成另外一个了。根本没法用来做网站服务器。服务器用的是数据中心的高速网络。IP 固定,网速飞快。
第三,你家的电脑没有"公网IP"。什么叫公网IP?就是全世界独一无二的地址。只有有这个地址,别人才能在互联网上找到你的电脑。你家电脑的 IP 通常只能在你家局域网里用。外面的人根本找不到你。服务器就不同了。它有一个固定的公网 IP。全世界的人都能通过这个 IP 找到它。
<DeploymentServerDemo /> <DeploymentServerDemo />
### 3.2 怎么选服务器? ### 3.2 怎么选服务器?
::: tip 💡 选型建议 选服务器主要看三个指标:**CPU核数**、**内存大小**、**硬盘空间**。这三个指标越高,服务器性能越好,价格也越贵。
- **个人项目/学习**1核2G,约¥100-200/年
- **小型商业项目**:2核4G,约¥500/年
- **中型项目**4核8G,约¥1000+/年
:::
| 方案 | 类比 | 优点 | 缺点 | 价格 | 对于刚入门的新手,完全没必要买特别贵的配置。记住一个简单的选法:
|------|------|------|------|------|
| 虚拟主机 | 租床位 | 便宜、简单 | 性能差 | ¥50-200/年 |
| 云服务器 | 租公寓 | 自由度高、可扩展 | 需自己配置 | ¥100-1000/年 |
| Vercel | 租会议室 | 零配置、免费额度 | 受平台限制 | 免费/按量 |
### 3.3 主流云厂商 - **个人项目、学习练手**:1核2G内存,足够了。一个月大概几十块钱。
- **小型商业项目**:2核4G内存。能承载每天几千到几万访问量。
- **中型项目**:4核8G或更高。需要专业团队来运维了。
| 厂商 | 特点 | 适合人群 | 还有一个要考虑的点:**地域**。如果用户主要在中国,就买国内的服务器(阿里云、腾讯云),访问速度快。如果用户主要在海外,就买国外的服务器(AWS、Google Cloud、DigitalOcean),或者买香港的服务器。速度快而且不用备案。
|------|------|---------|
| 阿里云 | 国内访问快 | 国内业务 |
| 腾讯云 | 价格亲民 | 小程序开发者 |
| Vercel | 零配置、免费 | 前端项目 |
--- ### 3.3 国内还是国外?
## 4. 部署:搬家 这是个很重要的问题。很多人刚开始没想清楚。后期会遇到麻烦。
### 4.1 连接服务器 **买国内服务器**的好处是速度快、延迟低。缺点是需要备案(提交网站信息给国家相关部门审核)。通常要等一周到一个月。而且国内服务器价格相对贵一些。
**SSH(远程连接工具)** **买国外服务器**的好处是不用备案。买了就能用。价格也可能更便宜。缺点是中国大陆用户访问速度可能慢一些。如果是香港或新加坡机房会好很多。
建议是:如果是个人项目、学习展示用的网站,买香港或海外的服务器。省去备案的麻烦。如果是做正规商业项目,需要长期运营,就买国内服务器。老老实实备案,后期会省很多麻烦。
### 3.4 主流云厂商对比
| 厂商 | 适合人群 | 特点 | 新用户价格 |
|------|---------|------|-----------|
| 阿里云 | 国内业务 | 市场占有率第一,生态完善 | 首年几十到一百多 |
| 腾讯云 | 小程序、游戏 | 小程序云开发支持好 | 首年优惠力度大 |
| 华为云 | 企业用户 | 政府、政务项目首选 | 价格偏高 |
| DigitalOcean | 开发者 | 简单好用,价格透明 | $4/月起 |
| Vercel | 前端项目 | 零配置,直接推送就上线 | 免费额度够用 |
新手最推荐 **阿里云****腾讯云** 的学生机/新用户优惠。通常一年只需要几十块钱。性价比极高。如果做的是纯前端项目,想省事,也可以直接用 **Vercel****Netlify**。连服务器都不用买。把代码推送上去就自动部署好了。
### 3.5 拿到服务器后该做什么?
买完服务器后,会收到一封邮件。里面包含几个重要信息:
- **IP地址**:一串类似 `123.45.67.89` 的数字。这是服务器在互联网上的门牌号。
- **登录用户名**:通常是 `root`(管理员账号)。
- **登录密码**:初始密码,或者是让你设置密码的链接。
有了这些信息,就可以用 **SSHSecure Shell** 远程登录到服务器上。对它进行各种配置。SSH 就像是给服务器发的一条加密的远程控制命令。让自己电脑上就能操作远在天边的服务器。
登录命令是这样的:
```bash ```bash
ssh root@123.45.67.89 ssh root@123.45.67.89
# 输入密码后,你就在服务器上了 # 按回车后会让你输入密码。输入正确的密码后就登录成功了。
``` ```
### 4.2 部署方式 登录成功后,就进入了服务器的命令行界面。看起来和在自己电脑上开了一个终端窗口差不多。可以在这里安装软件、创建文件夹、修改配置。一切操作都和本地电脑一样。
| 方式 | 优点 | 缺点 | ---
|------|------|------|
| FTP上传 | 简单直观 | 容易漏传 |
| Git拉取 | 快、可追溯 | 需配置Git |
**推荐**Git + Build Script ## 4. 部署:把代码搬进"房子"
### 4.1 部署是什么?
部署就是租好了服务器(房子)之后,把代码(行李家具)搬进去。然后打开门开始营业的过程。
具体来说,部署包括以下几个步骤:
1. **把代码上传到服务器**:把构建产物从本地电脑传到服务器上。
2. **安装依赖**:服务器上可能没有项目需要的各种包。需要安装。
3. **配置环境变量**:比如数据库密码、API密钥等敏感信息。
4. **启动服务**:让应用程序跑起来。开始监听用户的请求。
这四个步骤听起来挺复杂。但其实做起来没那么难。下面会详细介绍每一步怎么做。
<DeploymentServerDemo />
### 4.2 怎么把代码上传到服务器?
**方法一:FTP/SFTP 上传**
这是最直观的方式。就像用网盘一样。把文件拖到服务器上。可以在自己电脑上下载一个叫 **FileZilla** 的免费软件。填入服务器的IP、用户名、密码。就能像管理本地文件一样管理服务器上的文件了。
**方法二:Git 拉取**
这是更推荐的方式。先在 GitHub、GitLab 或 Gitee 上创建一个代码仓库。把代码推送到云端。然后在服务器上用 `git clone` 命令把代码拉下来。
这样好处是:后续更新代码只需要在服务器上执行 `git pull` 命令就行。不用每次都手动上传。而且代码存云端也安全。服务器重装了也不怕。
**方法三:CI/CD 自动部署**
这是最专业的方式。也是强烈推荐的方式。通过配置 CI/CD(持续集成/持续部署),只需要把代码推送到 GitHub。CI/CD 系统就会自动帮你完成:拉取代码 → 安装依赖 → 构建 → 部署的全过程。甚至不需要登录服务器。一切都是自动完成的。
### 4.3 部署的具体步骤
假设用最简单的方式——Git 手动部署。一步步演示整个过程:
**第一步:连接到服务器**
```bash ```bash
cd /var/www/my-site ssh root@123.45.67.89
git pull origin main # 拉取最新代码
npm install # 安装依赖
npm run build # 构建项目
pm2 restart all # 重启服务
``` ```
### 4.3 环境配置(Ubuntu **第二步:安装必要的软件**
如果是 Node.js 项目,需要先安装 Node.js
::: details 点击展开:最小化安装脚本
```bash ```bash
# 更新系统 # 以 Ubuntu 系统为例
sudo apt update && sudo apt upgrade -y
# 安装 NginxWeb服务器)
sudo apt install -y nginx
# 安装 Node.js 18
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs sudo apt install -y nodejs
```
# 安装 PM2(进程管家) **第三步:拉取代码**
```bash
# 创建放网站的目录
mkdir -p /var/www/my-website
cd /var/www/my-website
# 克隆代码仓库(需要先在GitHub上创建好仓库)
git clone https://github.com/你的用户名/你的仓库名.git .
```
**第四步:安装依赖并构建**
```bash
# 安装项目依赖
npm install
# 构建项目(生成 dist 目录)
npm run build
```
**第五步:用 PM2 启动服务**
为什么要用 PM2?它是一个进程管理工具。可以让网站在后台持续运行。就算服务器重启了也能自动启动。
```bash
# 全局安装 PM2
sudo npm install -g pm2 sudo npm install -g pm2
# 安装 Git # 启动网站(假设入口文件是 index.js)
sudo apt install -y git pm2 start index.js
```
:::
**Nginx 反向代理**:把 80 端口请求转发到 3000 端口 # 设置开机自启
pm2 startup
pm2 save
```
**第六步:配置 Nginx 反向代理**
Node.js 应用通常跑在 3000 或 8080 这样的端口上。但用户访问的是 80 端口(HTTP默认端口)。需要用 Nginx 把 80 端口的请求转发到应用端口。
```bash
# 安装 Nginx
sudo apt install -y nginx
# 创建 Nginx 配置文件
sudo nano /etc/nginx/sites-available/my-website
```
在打开的编辑器里写入以下配置:
```nginx ```nginx
server { server {
listen 80; listen 80;
server_name example.com; server_name example.com www.example.com;
# 静态文件(构建产物)直接返回
location / { location / {
root /var/www/my-website/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# API 请求转发到 Node.js 后端
location /api/ {
proxy_pass http://localhost:3000; proxy_pass http://localhost:3000;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
} }
} }
``` ```
保存退出后,启用这个配置:
```bash
# 启用配置
sudo ln -s /etc/nginx/sites-available/my-website /etc/nginx/sites-enabled/
# 测试配置是否有错误
sudo nginx -t
# 重启 Nginx
sudo systemctl restart nginx
```
现在访问 `http://example.com`(记得先把域名解析到这个服务器IP),应该就能看到网站了!
--- ---
## 5. 域名和 DNS挂牌 ## 5. 域名和 DNS给网站起个好名字
### 5.1 域名是什么 ### 5.1 为什么要买域名?
- IP地址(123.45.67.89)太难记 有了服务器 IP,为什么还要买域名?
- 域名(example.com)好记
**DNS(域名解析)** = **电话本**,把域名翻译成IP 想想看。让你记住一串数字 `123.45.67.89` 是不是很困难?是不是很容易敲错?但让你记住 `baidu.com``taobao.com` 这样的名字是不是就简单多了?
域名就是网站的名字。好记、专业。还能体现品牌形象。想象一下。告诉别人"访问我做的网站,IP 是 123.45.67.89",和"访问 woshishuaige.com",哪个更像那么回事?
<DeploymentDnsDemo /> <DeploymentDnsDemo />
### 5.2 配置步骤 ### 5.2 DNS 是什么?
1. **买域名**:阿里云/腾讯云(¥50-100/年) 好。现在买了一个域名。比如叫 `my-awesome-website.com`。但问题来了:电脑只认识 IP 地址。不认识 "my-awesome-website.com" 这种人类语言啊。
2. **配置DNS**
| 记录类型 | 用途 | 示例 | 这就需要 DNS 出场了。DNS 的全称是 "Domain Name System"。翻译过来就是"域名系统"。可以把它理解成一本巨大的"电话簿"。专门负责把人类好记的域名翻译成电脑能看懂的 IP 地址。
|---------|------|------|
| A记录 | 指向IP | `example.com``123.45.67.89` |
| CNAME | 指向域名 | `www.example.com``example.com` |
::: tip ⚠️ 注意 当在浏览器里输入 `my-awesome-website.com` 并回车时。背后发生了这些事情:
- DNS生效慢:全球同步需要几分钟到几小时
- TTL值:设置小一点(如600秒),修改后生效快 1. 浏览器问 DNS"heymy-awesome-website.com 的 IP 地址是多少?"
::: 2. DNS 查了一下"电话簿",告诉浏览器:"它的 IP 是 123.45.67.89"
3. 浏览器根据这个 IP 地址,找到了服务器,发出了请求
整个过程通常只需要几十毫秒。用户完全感知不到。
### 5.3 怎么配置 DNS
配置 DNS 通常有两个地方可以操作:
**方式一:在域名购买商那里配置**
在哪里买的域名,就去哪里配置 DNS 记录。最常见的记录类型是 **A 记录**
- **记录类型**A
- **主机记录**:通常填 `@`(代表域名本身,如 my-awesome-website.com)或者 `www`(代表 www.my-awesome-website.com
- **记录值**:服务器 IP 地址,如 `123.45.67.89`
**方式二:使用第三方 DNS 服务**
很多专业玩家不用域名商自带的 DNS。而是用 Cloudflare、阿里云 DNSPod、腾讯云 DNS 这些专业的 DNS 服务商。这些服务通常更稳定、解析速度更快。还自带 CDN、DDoS 防护等增值功能。
### 5.4 DNS 生效要多久?
这是很多人关心的问题。答案是:**不一定。通常几分钟到 24 小时**。
DNS 修改后,全球所有的 DNS 服务器需要同步这个变更。这就像往大海里扔一颗石子。波浪需要时间才能传到远方。有些 DNS 服务器更新快,几分钟就生效了。有些比较慢,可能需要等很久。
可以用以下命令检查 DNS 是否生效:
```bash
# Windows
ping 你的域名
# Mac/Linux
ping 你的域名
```
如果 ping 得通,显示的是服务器的 IP。说明 DNS 已经生效了。
--- ---
## 6. HTTPS安防 ## 6. HTTPS给网站装一把"锁"
### 6.1 为什么需要 HTTPS ### 6.1 HTTP 和 HTTPS 的区别
可能注意到了。有些网站地址是 `http://` 开头的。有些是 `https://` 开头的。这个"s"很重要。它代表"安全"Secure)。
**HTTPHyperText Transfer Protocol** 是用来传输网页的协议。可以把它理解成运输数据的卡车。但这辆卡车是**透明的**。里面装的东西所有人都能看见。在 HTTP 网站上输入的密码、填写的个人信息。在传输过程中可能被中间的任何人偷看到。
**HTTPSHTTP Secure** 是给这辆卡车加了一个**密封的集装箱**。还配了一把钥匙。只有发送方和接收方有钥匙。中间的人就算截获了也看不懂里面是什么东西。这就是加密传输。
<DeploymentHttpsDemo /> <DeploymentHttpsDemo />
- **HTTP**:数据"裸奔",谁都能看见 ### 6.2 为什么要 HTTPS
- **HTTPS**:数据加密,黑客看见也是乱码
### 6.2 怎么搞定 HTTPS 第一个原因:**安全**。没有 HTTPS,用户在网站上输入的密码是明文传输的。但凡有点技术的人都能截获。这年头,谁敢用没有 HTTPS 的网站
**Let's Encrypt(免费证书)** + **Certbot(自动工具)** 第二个原因:**浏览器警告**。现在 Chrome、Edge 这些主流浏览器都会对没有 HTTPS 的网站显示"不安全"的警告。用户一看 warning 图标。跑了都来不及。更别说注册、充值了。
第三个原因:**SEO**。Google、百度这些搜索引擎都会优先收录 HTTPS 的网站。SEO 效果会更好。
### 6.3 怎么获取 HTTPS 证书?
以前 HTTPS 证书很贵。每年要花几百甚至几千块钱。现在好了。出了一个叫 **Let's Encrypt** 的组织。提供完全免费的 SSL/TLS 证书。而且社区有很多自动化工具帮你安装和续期。
**方式一:使用 Certbot(推荐)**
Certbot 是一个自动申请和配置 Let's Encrypt 证书的工具。非常简单:
```bash ```bash
# 安装 Certbot # 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx sudo apt install -y certbot python3-certbot-nginx
# 自动申请证书并配置 Nginx # 一键申请证书并配置 Nginx
sudo certbot --nginx -d example.com sudo certbot --nginx -d example.com -d www.example.com
# 证书自动续期
sudo certbot renew --dry-run
``` ```
完成后访问网站会看到🔒小锁。 运行过程中会问几个问题。比如邮箱(用于证书到期提醒)。回答完后证书就自动配置好了。访问网站会发现地址栏多了一个小锁🔒
证书有效期是 90 天。但 Certbot 会帮你设置定时任务自动续期。基本不用管它。
**方式二:使用 Cloudflare**
如果使用了 Cloudflare 的 DNS 服务。那 HTTPS 证书根本不用自己配置。Cloudflare 会自动为域名提供 HTTPS 支持。而且连 90 天续期的问题都帮你解决了。
### 6.4 配置 HTTPS 后发生了什么变化?
配置好 HTTPS 后,用户访问从原来的 `http://example.com` 变成了 `https://example.com`。这个变化带来了一系列的安全保障:
1. **加密传输**:用户和服务器之间的所有通信都是加密的。
2. **身份验证**:证书可以证明"我真的是这个网站"。防止钓鱼网站。
3. **数据完整性**:能检测到数据是否被篡改。
--- ---
## 7. CI/CD自动化 ## 7. CI/CD让机器人帮你干活
### 7.1 什么是 CI/CD ### 7.1 什么是 CI/CD
CI/CD 是两个词的缩写:**C**ontinuous **I**ntegration(持续集成)和 **C**ontinuous **D**eployment(持续部署)。可以理解为一套帮你自动干活的机器人系统。
在没有 CI/CD 的时候。每次要发布新功能。流程是这样的:
1. 打开电脑,登录 GitHub
2. 拉取最新代码
3. 运行测试,看看有没有bug
4. 手动构建项目
5. 登录服务器
6. 拉取最新代码
7. 安装依赖
8. 构建项目
9. 重启服务
这9个步骤。每次发布都要手动做一遍。烦不烦?而且很容易漏掉某一步。比如忘记运行测试、忘记重启服务等。
有了 CI/CD 之后。流程变成了这样:
1. 把代码 push 到 GitHub
2. 喝茶坐等
3. (机器人自动完成上面9个步骤)
4. 网站自动更新了
<DeploymentCicdDemo /> <DeploymentCicdDemo />
- **CI(持续集成)**:每次提交自动测试 这就是 CI/CD 的魅力:**只需要把代码推上去。剩下的全部自动完成**。
- **CD(持续部署)**:测试通过自动部署
### 7.2 GitHub Actions 示例 ### 7.2 CI/CD 的工作流程
`.github/workflows/deploy.yml` 一个典型的 CI/CD 流程是这样的
**第一步:代码提交(Push**
完成了新功能的开发。把代码 push 到 GitHub。
**第二步:CI(持续集成)触发**
GitHub 检测到代码变动。通知 CI 系统(GitHub Actions、GitLab CI 等)开始工作。
**第三步:安装依赖和测试**
CI 系统会启动一台虚拟电脑。在上面:
- 安装项目需要的各种依赖
- 运行测试代码,确保没有 bug
- 构建项目,生成产物
如果测试失败。CI 会发邮件通知。这次部署就停了。不会把有问题的代码部署到生产环境。
**第四步:CD(持续部署)执行**
测试全部通过后。CI 系统会:
- 通过 SSH 连接到服务器
- 拉取最新代码
- 安装依赖
- 构建项目
- 重启服务
整个过程可能只需要几分钟。全部自动完成。
### 7.3 怎么配置 GitHub Actions
GitHub Actions 是 GitHub 自带的 CI/CD 功能。不需要额外付费(免费额度足够个人项目用)。配置起来也非常简单。
在项目根目录下创建 `.github/workflows/deploy.yml` 文件。写入以下配置:
```yaml ```yaml
name: Deploy to Production name: Deploy to Production
# 触发条件:每当 main 分支有代码推送时
on: on:
push: push:
branches: [main] branches: [main]
# 任务列表
jobs: jobs:
# 部署任务
deploy: deploy:
# 在什么系统上运行
runs-on: ubuntu-latest runs-on: ubuntu-latest
# 具体步骤
steps: steps:
- uses: actions/checkout@v3 # 1. 检出代码
- name: Checkout code
uses: actions/checkout@v3
# 2. 安装 Node.js 环境
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: '18' node-version: '18'
- name: Install & Build # 3. 安装依赖并构建
- name: Install and Build
run: | run: |
npm ci npm ci
npm run build npm run build
- name: Deploy # 4. 部署到服务器
- name: Deploy to Server
uses: appleboy/ssh-action@master uses: appleboy/ssh-action@master
with: with:
host: ${{ secrets.SERVER_HOST }} host: ${{ secrets.SERVER_HOST }}
username: root username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }} key: ${{ secrets.SSH_PRIVATE_KEY }}
script: | script: |
cd /var/www/my-site cd /var/www/my-website
git pull origin main git pull origin main
npm install npm install
npm run build npm run build
pm2 restart all pm2 restart all
``` ```
--- 这个配置文件告诉 GitHub Actions
::: details 📖 高级主题:CDN 和负载均衡 - 当 main 分支有新代码时触发
- 在一台 Ubuntu 电脑上执行任务
- 先安装 Node.js 18
- 然后安装依赖并构建项目
- 最后通过 SSH 连接到服务器,执行一系列部署命令
**CDN(内容分发网络)**:全球连锁仓库 配置好之后。每次 `git push origin main`。GitHub 就会自动开始部署。非常方便。
- 把图片、CSS、JS等静态资源上传到CDN
- CDN复制到全球节点
- 用户访问时从最近节点获取
**效果**:北京用户→北京节点(10ms),纽约用户→纽约节点(15ms)
**负载均衡(Load Balancer**:餐厅领班
- 看着N个服务器
- 把客人分配到最空闲的那个
- 某个服务器挂了,自动切换
**什么时候需要**
- 访问量 >10000/天
- 单台服务器 CPU/内存 >70%
:::
--- ---
## 8. 监控和备份:守夜人 ## 8. 监控和日志:做网站的"守夜人"
### 8.1 监控什么 ### 8.1 为什么要监控?
网站上线后。理论上应该 7×24 小时不间断运行。但现实世界没有这么美好。服务器可能会宕机。网络可能会抖动。代码可能会有bug。在真实的生产环境中。各种意外情况都有可能发生。
如果没有监控。就只能等用户打电话告诉你"网站打不开了"。这时候往往已经晚了。用户可能已经流失了。
有了监控之后。可以:
- **提前发现问题**:CPU 使用率 90% 了。提前加服务器。
- **快速定位问题**:网站慢了。查监控看是哪里瓶颈。
- **心里有底**:每天多少人访问、访问量什么时候最高。
<DeploymentMonitorDemo /> <DeploymentMonitorDemo />
| 指标 | 正常范围 | ### 8.2 监控哪些指标?
|------|---------|
| CPU使用率 | <70% |
| 内存使用率 | <80% |
| 磁盘空间 | <80% |
| 响应时间 | <2秒 |
| 错误率 | <1% |
### 8.2 备份策略 最重要的监控指标就这几个:
::: tip 💾 备份三要素 | 指标 | 正常范围 | 超过怎么办 |
1. **定期备份**:每天凌晨自动备份 |------|---------|-----------|
2. **多地存储**:本地 + 异地(防止单点故障) | CPU 使用率 | < 70% | 升级服务器配置或优化代码 |
3. **定期恢复测试**:确保备份能恢复 | 内存使用率 | < 80% | 检查是否有内存泄漏 |
::: | 磁盘使用率 | < 80% | 清理日志或无用文件 |
| 网站可达性 | 100% | 检查服务是否正常运行 |
| 响应时间 | < 2 秒 | 优化数据库查询或加缓存 |
| 错误率 | < 1% | 查看错误日志定位问题 |
### 8.3 怎么配置监控?
**最简单的方案:Uptime Robot**
注册 uptimerobot.com。添加网站URL。它会每 5 分钟自动检查一次网站是否正常。网站挂了会发邮件通知你。免费版本可以监控 50 个网站。对个人项目来说完全够用。
**进阶方案:阿里云/腾讯云监控**
如果服务器是在阿里云或腾讯云买的。它们自带监控功能。配置一下阈值报警就行。
**专业方案:Prometheus + Grafana**
这两个是监控领域的"瑞士军刀"。功能非常强大。可以监控任何能想到的指标。还能做出漂亮的可视化图表。不过配置起来比较复杂。适合有一定经验的开发者。
### 8.4 日志:出了问题怎么查?
监控告诉你"网站出问题了"。但具体是什么问题、为什么出问题。需要靠**日志**来定位。
日志就是程序运行时的"日记本"。记录了程序运行过程中的点点滴滴:
- 哪个用户在什么时候访问了什么页面
- 数据库查询花了多长时间
- 有没有报错,错误信息是什么
**最基础的日志用法**
在服务器上查看应用日志:
```bash ```bash
# 每天自动备份数据库 # 查看 PM2 的日志
0 2 * * * /usr/bin/mysqldump -u root -p密码 my_db > /backup/db_$(date +\%Y\%m\%d).sql pm2 logs
# 保留最近7天的备份 # 查看 Nginx 的访问日志
find /backup -name "db_*.sql" -mtime +7 -delete tail -f /var/log/nginx/access.log
# 自动上传到云存储 # 查看 Nginx 的错误日志
/usr/bin/ossutil cp /backup/db_$(date +\%Y\%m\%d).sql oss://my-backup/ tail -f /var/log/nginx/error.log
``` ```
--- **进阶的日志方案**
## 9. 常见问题速查 如果项目比较复杂。推荐使用专业的日志收集工具:
| 现象 | 可能原因 | 怎么办 | - **Loki**:免费开源。和 Prometheus 一家的。
|------|---------|--------| - **ELKElasticsearch + Logstash + Kibana**:功能强大。但配置复杂。
| 网站打不开 | 域名没解析?服务器挂了? | `ping 域名`看通不通<br>`ssh`连不上就是服务器挂了 | - **Sentry**:专门用于收集应用错误的工具。能自动收集报错信息。
| 404 Not Found | Nginx配置错了?路径不对? | `nginx -t`检查配置 |
| 502 Bad Gateway | 后端服务挂了?端口没开? | `pm2 list`看服务状态 | ### 8.5 告警:出问题怎么第一时间知道?
| HTTPS证书报错 | 证书过期?域名不匹配? | `certbot renew`续期 |
| 更新不生效 | 浏览器缓存?CDN缓存? | Ctrl+F5强制刷新<br>去CDN控制台"刷新缓存" | 监控告诉你有问题。但如果没有盯着监控面板看,怎么办?这就需要**告警**了。
| 很慢 | 性能不够?CDN没配置? | 查监控看CPU/内存<br>静态资源上CDN |
告警就是当监控系统检测到异常时。自动通过短信、微信、钉钉、邮件等方式通知你。可以设置不同的告警级别:
- **紧急(网站完全挂掉)**:发短信+打电话。必须马上知道。
- **严重(错误率飙升)**:发钉钉/微信消息。看到就处理。
- **一般(CPU 偏高)**:发邮件汇总。一天看一次就行。
告警配置的核心原则是:**分级告警,别把自己烦死**。如果什么鸡毛蒜皮的小事都给你发短信。用不了多久你就会把告警关掉。
--- ---
## 10. 上线前检查清单 ## 9. 常见问题速查表
::: details ✅ 基础检查 | 问题现象 | 可能原因 | 解决方法 |
- [ ] 代码已构建(`npm run build` |---------|---------|---------|
- [ ] 服务器环境配置完成(Nginx + Node.js | 网站打不开 | 域名没解析 / 服务器挂了 / Nginx 没启动 | `ping 域名` 看通不通;`pm2 list` 看服务状态;`systemctl status nginx` 看 Nginx |
- [ ] 域名解析正确(能ping通) | 打开是空白页面 | 构建产物路径不对 / 静态文件没正确配置 | 检查 Nginx 的 root 路径是否指向 dist 目录 |
- [ ] HTTPS证书正常(有🔒小锁) | 404 页面找不到 | 路由没正确配置 / 路径拼写错误 | Nginx 配置里加上 `try_files $uri $uri/ /index.html` |
::: | 502 Bad Gateway | 后端服务挂了 / 端口没开 | `pm2 list` 看进程是否在运行;检查端口是否正确 |
| 403 Forbidden | 权限不对 / 索引目录没开 | 检查文件权限 `chmod -R 755`Nginx 配置加上 `autoindex on` |
::: details 🔒 安全检查 | HTTPS 证书过期 | 证书到期没续期 | `certbot renew` 手动续期;检查自动续期定时任务 |
- [ ] 数据库密码不是弱密码 | 更新后看不到变化 | 浏览器缓存 / CDN 缓存 | Ctrl+Shift+R 强制刷新;去 CDN 控制台"刷新缓存" |
- [ ] 敏感信息没写在代码里 | 网站打开很慢 | 带宽不够 / 没开缓存 / 没配置 CDN | 升级服务器带宽;配置 Redis 缓存;接入 CDN |
- [ ] 开启了防火墙(只开必要端口) | 数据库连不上 | 数据库没启动 / 密码错了 / 权限问题 | 检查数据库服务状态;核对配置里的连接信息 |
- [ ] 配置了SQL注入防护
:::
::: details 🛡️ 运维检查
- [ ] 监控告警配置完成
- [ ] 日志正常记录
- [ ] 自动备份已设置
- [ ] CI/CD流程测试通过
:::
--- ---
## 总结 ## 总结
服务上线是一个系统性的大工程。涉及从代码构建到服务器部署、从网络配置到安全防护、从监控告警到日志分析的方方面面。对于初学者来说。不需要一开始就追求完美。先把最小可用版本(MVP)跑起来。然后在此基础上逐步完善。
整个流程的核心要点可以归纳为以下几点:
### 核心流程 ### 核心流程
1. **构建**代码打包成浏览器懂的格式 1. **构建**`npm run build` 把代码变成浏览器能看懂的 HTML/CSS/JS
2. **部署**代码放到服务器上 2. **部署**把构建产物上传到服务器。用 Nginx 配置反向代理。
3. **配置**Nginx、域名、HTTPS 3. **域名**购买域名并配置 DNS 解析到服务器 IP
4. **优化**CDN、负载均衡(高级) 4. **HTTPS**用 Let's Encrypt 申请免费证书。保护数据传输安全。
5. **自动化**CI/CD解放双手 5. **CI/CD**配置自动化部署。代码 push 后自动上线。
6. **保障** → 监控和备份守住底线 6. **监控**配置监控和告警。出问题第一时间知道。
### 关键原则 ### 学习路线建议
| 原则 | 说明 | - **第1天**:用 Vercel/Netlify 部署一个静态网页。体验一下"代码变成网站"的感觉。
|------|------| - **第1周**:租一台云服务器。手动部署一个 Node.js 项目。配置域名和 HTTPS。
| **小步快跑** | 先上线MVP,再逐步完善 | - **第2-4周**:配置完整的 CI/CD 流程。建立监控和告警体系。
| **自动化优先** | 能自动的别手动,减少人为失误 | - **持续学习**:学习 Docker 容器化、学习 Kubernetes 集群、学习微服务架构。
| **监控先行** | 先建监控,再上功能 |
| **备份为王** | 数据无价,备份是最后防线 |
| **安全第一** | HTTPS、防火墙、弱密码检查,一个都不能少 |
### 学习路线
**入门(第1天)**:用 Vercel 免费部署静态网页
**进阶(第1周)**:租云服务器、手动部署 Node.js 应用、配置域名和 HTTPS
**实战(第2-4周)**:搭建完整 CI/CD 流程、配置 CDN、建立监控和备份
**深入(持续)**:学习 Docker 容器化、Kubernetes 集群、微服务架构
--- ---
## 名词速查表 ## 名词速查表
| 名词 | 英文 | 人话解释 | | 名词 | 英文 | 人话解释 |
|------|------|---------| |------|------|-----------|
| 部署 | Deployment | 把代码放到服务器上让人能访问 | | 构建 | Build | 把代码翻译打包成浏览器能执行的格式 |
| 构建 | Build | 把代码翻译打包成浏览器懂的格式 | | 部署 | Deploy | 把代码放到服务器上让用户能访问 |
| 服务器 | Server | 一台永远不关机、连着互联网的电脑 | | 服务器 | Server | 7×24小时不关机、联网的电脑 |
| 域名 | Domain Name | 网站的好记名字(如 baidu.com | | 域名 | Domain | 网站的好记名字(如 baidu.com |
| DNS | Domain Name System | 域名解析系统,把域名翻译成IP | | DNS | Domain Name System | 把域名翻译成 IP 地址的"电话簿" |
| HTTP/HTTPS | HyperText Transfer Protocol | 网页传输协议(HTTP不安全,HTTPS加密 | | HTTP | HyperText Transfer Protocol | 网页传输协议(不安全,明文传输 |
| Nginx | Engine X | 高性能Web服务器(门童 | | HTTPS | HTTP Secure | 加密传输的网页协议(安全 |
| 反向代理 | Reverse Proxy | 转发请求到后端服务 | | Nginx | Engine X | 高性能 Web 服务器。做反向代理的。 |
| SSH | Secure Shell | 远程连接服务器的工具 | | 反向代理 | Reverse Proxy | 站在门口的服务员。把请求转发给后端。 |
| CDN | Content Delivery Network | 内容分发网络,全球加速 | | SSH | Secure Shell | 远程登录服务器的加密工具 |
| CI/CD | Continuous Integration/Deployment | 持续集成/持续部署(自动化) | | CDN | Content Delivery Network | 全球分布的服务器网络。加快访问速度。 |
| 监控 | Monitoring | 盯着服务器看有没有问题 | | CI/CD | Continuous Integration/Deployment | 自动化流水线。代码 push 后自动测试部署。 |
| 备份 | Backup | 备份数据,防丢失 | | SSL/TLS | Secure Sockets Layer / Transport Layer Security | 加密协议。给 HTTPS 提供安全保障。 |
| PM2 | Process Manager 2 | Node.js 进程管理器。让应用持续运行。 |