后端部署:Vercel / Railway / 云服务器 / Docker / K8s 选型与实战
就盯着后端部署的这几种方案:全托管 PaaS、云服务器、Serverless、容器化、Kubernetes。把每种的优缺点、成本、适用场景摸透,能根据团队大小和产品阶段选合适的,再把部署的核心工程实践练熟。
- 就按这个谱系理:从最省心的全托管 PaaS,到最灵活的自建 K8s,把每种方案的权衡搞明白。
- 掌握全托管 PaaS(Vercel/Netlify/Railway/Fly.io/Render)的适用场景和基本用法
- 就按这个流程走:环境搭建、Nginx反向代理、进程管理、HTTPS、防火墙,这是云服务器(ECS/EC2)部署的完整步骤。
- Serverless(函数计算)的原理、优势、局限和适用场景
- Docker 容器化的核心概念和基本用法,就抓四个东西:Dockerfile、镜像、容器、docker-compose。
- Kubernetes(K8s)的核心概念、适用场景,什么时候该用什么时候不该用
- 部署方案选型就看四个硬指标:团队规模、运维能力、预算、流量预期,还有技术栈。
- 就说部署的核心工程实践,就这几个:CI/CD 自动部署、环境变量管理、健康检查、滚动更新、回滚、日志
部署方案谱系:从省心到灵活
后端部署不是只有「买台服务器把代码扔上去」一种方式。从最省心到最灵活,有一个完整的谱系。选型的核心权衡是:「省心(少运维)」vs「灵活(多控制)」vs「成本」。越省心的方案越贵(流量大了成本高)、定制化越受限;越灵活的方案运维成本越高、需要更多技术能力。
# 部署方案谱系(从省心到灵活)
# 1. 全托管 PaaS(最省心)
# Vercel / Netlify / Railway / Fly.io / Render / Heroku
# → push 代码自动部署,不用管服务器/运维/扩容,按用量付费
# → 适合:小团队、MVP、Web 应用、流量不大
#
# 2. Serverless / FaaS(按需付费)
# AWS Lambda / 阿里云函数计算 / Cloudflare Workers / Vercel Functions
# → 只写函数,平台自动扩缩容,没流量不花钱
# → 适合:事件驱动、流量波动大、API 后端、定时任务
#
# 3. 容器托管(半托管)
# AWS ECS / Google Cloud Run / 阿里云 SAE / Fly.io(容器)
# → 打包成 Docker 镜像,平台管理容器编排和扩容
# → 适合:容器化应用、中等规模、需要一定控制力
#
# 4. 云服务器 IaaS(最灵活)
# 阿里云 ECS / 腾讯云 CVM / AWS EC2 / DigitalOcean
# → 拿到一台虚拟机,自己装环境/部署/运维/Nginx/监控
# → 适合:有运维能力、需要完全控制、成本可控、中大型项目
#
# 5. Kubernetes K8s(最复杂最强大)
# 自建 K8s 集群 / 托管 K8s(EKS/GKE/ACK)
# → 容器编排平台,自动扩缩容/滚动更新/服务发现/自愈
# → 适合:微服务架构、大规模、多团队、有专门运维
#
# 选型原则:从最省心的开始,遇到瓶颈再升级,不要一上来就 K8s(过度工程)全托管 PaaS:小团队的首选
PaaS(Platform as a Service,平台即服务)把服务器、操作系统、运行时、扩容、监控都托管了,你只需要 push 代码,平台自动构建部署。主流平台:
零运维:不用管服务器、操作系统、安全补丁、扩容。部署简单:push代码自动构建部署,或连GitHub自动部署。自动扩缩容:流量大了自动加实例,小了自动缩。内置HTTPS:自动签发和续期SSL证书。全球CDN:静态资源全球加速。免费额度:Vercel/Netlify免费额度够个人项目和小流量产品用。 流量大了贵:按请求数、带宽、运行时间付费,高流量时比自建服务器贵3-10倍。定制化受限:不能装任意软件、不能改系统配置,长连接/WebSocket支持有限。冷启动:Serverless函数空闲后会休眠,第一次请求慢几百毫秒到几秒。厂商锁定:迁移到其他平台有成本。后端能力有限:Vercel/Netlify主要是前端+轻量函数,复杂后端需要Railway/Render/Fly.io。 适用:个人项目、MVP、小团队、流量不大(日活<1万)、前端为主的应用。本课程的朋友好学 App前端静态导出可以部署到Vercel/Netlify(免费),后端server.js如果要托管可以用Railway/Render(支持长运行的Node服务)
云服务器:完全可控的选择
云服务器(IaaS,Infrastructure as a Service)给你一台完整的虚拟机,你有 root 权限,可以装任何软件、做任何配置。主流厂商:阿里云 ECS、腾讯云 CVM、华为云 ECS、AWS EC2、Google Compute Engine、DigitalOcean、Vultr。优势:完全可控、成本可预测(包月/包年固定费用)、适合中大型项目。劣势:需要自己运维(装环境、配 Nginx、安全补丁、监控、扩容、备份)。
云服务器部署完整流程(Node.js 应用为例)
第1步:购买和初始化服务器
选配置:CPU/内存(2核4G 起步,能跑 Node+PostgreSQL+Nginx,日活几千够用;流量大了再升配);操作系统(Ubuntu 22.04 LTS,最流行、文档最多、包管理方便);地域(选离用户近的,国内用户选国内节点,注意:国内节点需要备案域名);带宽(5M 起步,流量大了升级或用 CDN);存储(40G 系统盘起步,数据量大了加数据盘)。初始化:设置 root 密码或 SSH 密钥,安全组开放 22(SSH)/80(HTTP)/443(HTTPS) 端口。
第2步:环境搭建
创建非 root 用户,不用 root 直接跑应用;安装 Node.js,用 nvm 管理版本,或 NodeSource 源装指定版本;安装数据库,PostgreSQL 用 apt install postgresql,建库建用户,Redis 可选;安装 Nginx,做反向代理、静态文件、HTTPS;安装 PM2,Node 进程管理,自动重启、日志、集群模式;配置防火墙,用 ufw,只开放必要端口。
第3步:部署应用
代码上传:git clone(推荐,服务器上拉代码)或 scp/rsync 上传;安装依赖:npm ci(用 package-lock.json 精确安装);环境变量:.env 文件(不进 Git,手动在服务器上创建)或 PM2 ecosystem.config.js 里配置;构建:npm run build(如果是 Next.js/React 需要构建);启动:pm2 start app.js --name myapp(或 pm2 start ecosystem.config.js);设置开机自启:pm2 startup + pm2 save(服务器重启后自动启动应用)。
第4步:Nginx 反向代理
Nginx 作为反向代理,监听 80/443 端口,把请求转发给 Node 应用(通常跑在 3000/8080 端口)。配置:server { listen 80; server_name example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }。Nginx 的作用:反向代理(用户不直接访问 Node 端口);负载均衡(多个 Node 实例);静态文件服务(前端构建产物直接由 Nginx 服务,比 Node 快);HTTPS 终止(SSL 证书在 Nginx 层处理);Gzip/Brotli 压缩;限流/缓存/访问控制。
第5步:HTTPS(SSL 证书)
用 Let's Encrypt 免费证书 + Certbot 自动签发和续期:安装 Certbot:apt install certbot python3-certbot-nginx;签发证书:certbot --nginx -d example.com -d www.example.com(自动修改 Nginx 配置,开启 HTTPS,配置 HTTP 跳转 HTTPS);自动续期:Certbot 自动配置 systemd timer 续期(Let's Encrypt 证书 90 天有效期,自动续期)。注意:国内服务器用 Let's Encrypt 没问题,但域名需要备案(国内节点强制备案,不备案只能用境外节点)。
第6步:监控和日志
PM2 日志:pm2 logs myapp(实时日志),pm2 monit(监控面板),日志文件在 ~/.pm2/logs/;系统监控:htop(CPU/内存/进程)、df -h(磁盘)、free -m(内存);Nginx 日志:/var/log/nginx/access.log 和 error.log;进阶:接入 Sentry(错误追踪)、Prometheus+Grafana(指标监控)、ELK(日志聚合);告警:磁盘>80%、内存>90%、服务挂了、错误率高,用邮件/短信/钉钉/企业微信告警。
第7步:备份
数据库备份:pg_dump 每天定时备份(cron 任务),备份文件存到对象存储(阿里云 OSS/腾讯云 COS/AWS S3)或另一台服务器;代码备份:Git 远程仓库(GitHub/GitLab/Gitee);配置备份:Nginx 配置、.env、PM2 配置纳入 Git 或备份;定期测试恢复:备份了但不能恢复=没备份,定期(每月)测试从备份恢复数据库。
个人项目/MVP/日活<1万/前端为主 → PaaS(Vercel/Railway),零运维、免费额度够、上线快;日活1万-10万/有一定流量/需要长连接/复杂后端 → 云服务器(2核4G起步,包月固定成本,比 PaaS 便宜);日活10万+/微服务架构/多团队/有专门运维 → K8s(自动扩缩容/滚动更新/服务发现);流量波动极大(如活动期间流量是平时10倍)→ Serverless(自动扩缩容,没流量不花钱);别一上来就 K8s——90%的项目一台云服务器+PM2+Nginx 就够了,K8s 的运维复杂度(学习曲线陡、需要专门运维、排错难)远大于它带来的收益,除非真的需要微服务和自动扩缩容;本课程的朋友好学 App 后端 server.js 是轻量 Node 服务,小流量用 Railway/Render 免费层就够,流量大了迁到阿里云 ECS(2核4G,包月约100-200元)
Serverless:按需付费的函数计算
Serverless(无服务器)/ FaaS(Function as a Service,函数即服务):你只写处理请求或事件的函数,平台管运行时、扩容、可用性、负载均衡。按调用次数和执行时间付费,没流量不花钱。主流:AWS Lambda、阿里云函数计算 FC、腾讯云 SCF、Google Cloud Functions、Cloudflare Workers、Vercel Functions。
这是无服务器函数的优劣势,直接说: 优势:不用管服务器运维流量从0涨到几千并发,平台自动扩缩容按需付费,没流量不花钱,有流量按调用次数+执行时间算,小流量极便宜甚至免费平台多可用区部署,保证高可用HTTP请求、定时任务、消息队列、文件上传、数据库变更,都能触发函数 局限:函数空闲会被回收,第一次调用要冷启动,延迟几百毫秒到几秒,对延迟敏感的应用有影响执行时间通常5-15分钟,不能跑长任务函数实例之间不共享内存,状态得存在外部数据库/缓存本地文件系统只读或临时,不能持久化文件本地开发和调试不如传统应用方便各平台API、触发器不同,迁移有成本不适合长连接/WebSocket,部分平台支持但有限制超高流量时,按调用次数付费的成本可能比服务器高 适用场景:API后端、定时任务、事件处理、Webhook、图片处理、流量波动大的应用、小程序后端 不适用场景:长连接、长任务、需要本地文件持久化、对冷启动敏感的低延迟应用
Docker:容器化是现代部署的基础
Docker 是容器化技术——把应用和它的所有依赖(运行时、库、配置、代码)打包成一个「镜像」(Image),镜像可以在任何装了 Docker 的机器上运行,保证「在我电脑上能跑,在服务器上也能跑」(环境一致性)。核心概念:Dockerfile:构建镜像的脚本(基础镜像、安装依赖、复制代码、启动命令);Image(镜像):只读模板,包含应用和依赖;Container(容器):镜像的运行实例(可启动/停止/删除);Registry(镜像仓库):存储和分发镜像(Docker Hub、阿里云 ACR、腾讯云 TCR、AWS ECR、GHCR);docker-compose:多容器编排(一个应用+数据库+Redis 一起启动,本地开发和简单部署用)。
# Dockerfile 示例(Node.js 应用)
# # 1. 基础镜像(指定 Node 版本)
# FROM node:20-alpine
#
# # 2. 设置工作目录
# WORKDIR /app
#
# # 3. 先复制 package.json(利用 Docker 缓存,依赖不变时不重新安装)
# COPY package*.json ./
#
# # 4. 安装依赖(--only=production 只装生产依赖,减小镜像体积)
# RUN npm ci --only=production
#
# # 5. 复制应用代码
# COPY . .
#
# # 6. 构建(如果是 Next.js/React 需要构建)
# RUN npm run build
#
# # 7. 暴露端口
# EXPOSE 3000
#
# # 8. 非 root 用户运行(安全最佳实践)
# USER node
#
# # 9. 启动命令
# CMD ["node", "server.js"]
#
# 构建镜像:
# docker build -t myapp:latest .
#
# 运行容器:
# docker run -d -p 3000:3000 --name myapp --env-file .env myapp:latest
#
# 常用命令:
# docker ps # 查看运行中的容器
# docker logs myapp # 查看容器日志
# docker stop myapp # 停止容器
# docker rm myapp # 删除容器
# docker images # 查看镜像
# docker rmi myapp # 删除镜像
# docker exec -it myapp sh # 进入容器# docker-compose.yml 示例(应用+PostgreSQL+Redis 一起启动)
# version: '3.8'
# services:
# app:
# build: .
# ports:
# - "3000:3000"
# environment:
# - DATABASE_URL=postgresql://user:pass@postgres:5432/mydb
# - REDIS_URL=redis://redis:6379
# - NODE_ENV=production
# depends_on:
# - postgres
# - redis
# restart: always
#
# postgres:
# image: postgres:16-alpine
# environment:
# - POSTGRES_USER=user
# - POSTGRES_PASSWORD=pass
# - POSTGRES_DB=mydb
# volumes:
# - pgdata:/var/lib/postgresql/data # 数据持久化(容器删除数据不丢)
# restart: always
#
# redis:
# image: redis:7-alpine
# restart: always
#
# volumes:
# pgdata:
#
# 启动:docker-compose up -d
# 停止:docker-compose down
# 查看日志:docker-compose logs -f app多阶段构建(Multi-stage Build):构建阶段用完整镜像(含编译工具),运行阶段用精简镜像(alpine/slim),只复制构建产物,减小镜像体积(从 1GB 降到 100MB);利用层缓存:Dockerfile 指令顺序很重要,把不常变的(安装依赖)放在前面,常变的(复制代码)放在后面,这样代码变了不需要重新安装依赖;非 root 用户运行:容器里不要用 root,创建普通用户(USER node),减少安全风险;健康检查(HEALTHCHECK):在 Dockerfile 里定义健康检查命令,Docker 能自动判断容器是否健康,不健康自动重启;不要在镜像里存密钥:环境变量或 secrets 注入,不写进 Dockerfile(会进镜像历史);. dockerignore:和 .gitignore 类似,排除 node_modules、.git、构建产物等,减小构建上下文体积,加快构建;标签(Tag):镜像用版本号 tag(myapp:v1.2.3),不要都用 latest(latest 不可追溯,回滚困难);日志输出到 stdout/stderr:不要写文件,Docker 能收集 stdout/stderr 日志(docker logs),方便日志聚合。
Kubernetes:什么时候该用,什么时候不该用
Kubernetes(K8s)是容器编排平台——自动管理容器的部署、扩缩容、负载均衡、服务发现、滚动更新、自愈(容器挂了自动重启、节点挂了自动迁移)。核心概念:Pod(最小调度单元,一个或多个容器);Service(服务发现和负载均衡);Deployment(声明式部署,管理 Pod 副本数和滚动更新);Ingress(外部流量入口,HTTP 路由);ConfigMap/Secret(配置和密钥管理);Namespace(资源隔离);HPA(Horizontal Pod Autoscaler,自动扩缩容)。适用:微服务架构、大规模(几十上百个服务)、多团队、需要自动扩缩容和滚动更新、有专门运维团队。不适用:小团队、单应用、MVP、没有运维能力——K8s 的学习曲线极陡(概念多、排错难、运维复杂),是典型的「为了用而用」的过度工程重灾区。
见过太多团队:3个人的团队、1个应用,非要搞K8s集群,结果一半时间在折腾K8s(Pod起不来、Ingress配置不对、证书过期、节点NotReady),产品开发进度严重滞后;一台2核4G服务器就能跑的应用,非要搞3节点K8s集群,结果每个节点跑K8s组件就占了一半资源,应用性能反而更差;没有运维能力,K8s出了问题(Pod CrashLoopBackOff、节点失联、证书过期)没人能修,最后只能重建集群。90%的项目不需要K8s。一台云服务器+PM2+Nginx(或Docker Compose)能搞定90%的部署需求。等你真的有了微服务架构(10+服务)、流量大到需要自动扩缩容、有了专门的运维团队,再考虑K8s。而且即使到了那个阶段,也可以先用托管K8s(EKS/GKE/ACK),不要自建集群(自建K8s的运维复杂度是托管的3倍)。
部署工程实践
部署方案从最简单的开始,遇到瓶颈再升级,别一上来就 K8s(过度工程);部署要自动化(CI/CD),别手动 SSH 上传(容易出错、不可重复、不可追溯);部署要可回滚(出问题几分钟内能回到上一个稳定版本),回滚方案要提前演练(别等出问题才发现回滚不了);部署要可观测(日志/指标/追踪/告警),出了问题能快速发现和定位;配置和代码分离(环境变量/密钥管理),密钥绝对不进 Git 和镜像;数据库迁移要向前兼容(先加后删,分多步),别破坏性变更(直接删字段/改类型会导致老版本崩溃);先在 staging 环境验证,再上 production(别直接在生产环境测);本课程的朋友好学 App 目前是本地应用(用户下载 APK 安装),后端 server.js 是可选的(用户可以自己跑或用作者托管),如果以后做云端托管,前端静态产物→Vercel/Netlify(免费CDN),后端→Railway/Render(小流量免费层)或阿里云 ECS(流量大了包月更便宜),用 GitHub Actions 做 CI/CD 自动部署。
本节小结
部署方案谱系(省心→灵活):全托管 PaaS(Vercel/Netlify/Railway/Fly.io/Render,零运维push即部署,适合小团队/MVP/流量不大,流量大了贵)→ Serverless/FaaS(AWS Lambda/阿里云函数计算/Cloudflare Workers,按需付费没流量不花钱,适合事件驱动/流量波动大,冷启动/执行时间限制)→ 容器托管(ECS/Cloud Run,Docker镜像平台管理)→ 云服务器 IaaS(阿里云ECS/AWS EC2,完全可控包月固定成本,需要自己运维,适合中大型)→ K8s(最复杂,微服务/大规模/有运维才用,90%项目不需要是过度工程重灾区)。云服务器部署七步:购买初始化→环境搭建(Node/PG/Nginx/PM2)→部署应用(git clone/npm ci/.env/build/pm2 start)→Nginx反向代理→HTTPS(Let's Encrypt+Certbot)→监控日志(PM2/htop/Sentry)→备份(pg_dump+cron+对象存储,定期测恢复)。Docker:Dockerfile构建镜像,容器保证环境一致性,docker-compose多容器编排,最佳实践(多阶段构建/层缓存/非root/健康检查/不存密钥/.dockerignore/版本tag/日志stdout)。部署工程实践:CI/CD自动部署、环境变量管理、健康检查、滚动更新/蓝绿、快速回滚、日志聚合、数据库迁移向前兼容、灰度发布。选型心法:从最简单开始遇瓶颈再升级,不要一上来K8s;自动化、可回滚、可观测、配置分离、staging先验证。下一节讲前端部署与CDN——后端部署好了,前端怎么上线。
资深工程师加餐
底层原理 · 大厂视角 · 工程经验,点卡片展开
独立开发者选栈的第一标准是“能不能一个人最快稳定交付”,而不是哪个框架最新。Next.js 这类全栈框架把路由、构建、静态导出、服务端接口收敛到一套工具链里,配合静态导出 + WebView 原生壳,能让一个人同时覆盖 Web 与移动端;选型时先验证最不确定的环节(离线运行、原生能力、AI 流式),跑通原型再全面投入,避免做到一半发现关键能力不成立。