基于Angular Cli+Express+DigitalOcean的自动化部署最佳实践咨询
Angular+Express部署方案优劣分析与最佳实践
作为常年折腾SPA+Node后端部署的开发者,我来给你拆解下这两种方案的利弊,结合你的场景给出实际建议。
先明确你的核心场景:Angular CLI开发前端,Express做后端,代码存在BitBucket,部署在DigitalOcean的Ubuntu 16.04 Droplet上,前端构建产物输出到server/public。
方案1:服务器克隆源码后构建运行
核心流程:仓库存源码(通过.gitignore排除server/public),服务器克隆/拉取代码→安装全量依赖→执行生产构建→pm2启动服务
优点
- 版本一致性拉满:所有构建都基于仓库的源码,彻底避免“本地改了代码没提交就构建,导致服务器代码和仓库不一致”的玄学问题,团队协作时这一点尤其重要
- 环境可控:如果服务器和本地用相同版本的Node.js、Angular CLI,构建产物的可靠性更高,减少环境差异带来的bug
- 回滚成本低:要回滚版本?直接在服务器上切换Git分支,重新构建启动就行,不用折腾本地重新构建再上传的流程
- 本地无压力:如果你的项目很大,本地构建慢,服务器性能又不错,可以把构建压力转移到服务器上
缺点
- 服务器资源占用高:服务器需要安装Node.js、Angular CLI等构建工具,还要下载全量依赖(包括devDependencies),额外占用磁盘和内存
- 构建影响服务:如果在生产高峰期执行构建,服务器的CPU、内存占用会飙升,可能影响现有服务的稳定性
- 部署流程稍慢:克隆仓库+安装依赖+构建,整个流程比单纯传文件要耗时一些
方案2:本地构建后仅上传server目录
核心流程:本地执行ng build --prod→把包含构建产物的server目录传到服务器→安装Express生产依赖→pm2启动服务
优点
- 服务器轻量化:服务器只需要安装运行时依赖(Express相关的prod依赖),不需要构建工具,资源占用少,适合性能一般的小Droplet
- 部署速度快:只传编译后的文件,比克隆仓库+安装依赖+构建快很多,紧急修复时能快速上线
- 不影响服务器运行:构建在本地完成,不会占用服务器的资源,生产时段部署也不用担心影响服务
缺点
- 版本风险高:完全依赖本地操作,如果本地代码没提交到仓库就构建上传,会导致服务器代码和仓库版本不一致,后期排查问题时很难定位
- 环境差异隐患:如果本地和服务器的Node.js版本不一致,或者依赖包的安装环境不同,可能出现“本地构建的产物在服务器上跑不起来”的问题
- 回滚麻烦:要回滚的话,得本地切换分支重新构建,再上传覆盖服务器上的文件,或者提前备份旧版本的
server目录,操作比Git切换分支繁琐
最佳实践建议
没有绝对的“最优方案”,完全看你的团队规模和服务器情况:
如果你是个人开发/小团队,服务器性能一般
优先选方案2,轻量化、部署快,适合快速迭代。但要注意几个关键点:
- 每次构建前必须确保本地代码已经提交到BitBucket,并且和远程分支完全一致,避免版本混乱
- 本地和服务器用相同版本的Node.js,用
nvm来管理版本是最方便的,比如两边都装v16.x(Ubuntu 16.04建议用LTS版本,避免兼容性问题) - 写个自动化脚本简化流程,比如本地的bash脚本:
# 1. 先提交代码到远程(可选,但建议加) git add . git commit -m "prepare for deployment" git push origin main # 2. 执行Angular生产构建 ng build --prod # 3. 上传server目录到Droplet,替换成你的服务器信息 scp -r ./server your_username@your_droplet_ip:/var/www/your-project # 4. 远程安装生产依赖并重启pm2 ssh your_username@your_droplet_ip "cd /var/www/your-project/server && npm install --production && pm2 restart express-app"
如果你是团队协作/项目规模较大
优先选方案1,配合CI/CD工具(比如BitBucket Pipelines)实现完全自动化,彻底避免人为操作失误:
- 在仓库的
.gitignore里加上server/public/,避免构建产物提交到仓库 - 配置BitBucket Pipelines:当代码推送到主分支时,自动在CI环境中安装依赖、构建Angular,然后把代码部署到Droplet,安装生产依赖并重启pm2
- 服务器上只需要提前装好Node.js、pm2,后续完全不用手动操作,团队成员只需要提交代码就行
额外提醒
不管用哪种方案,都要给package.json里的依赖指定明确的版本范围(比如用^或者固定版本),避免依赖版本漂移导致的问题;另外,服务器上一定要用pm2来管理进程,确保服务崩溃后能自动重启。
内容的提问来源于stack exchange,提问作者kvzhkv
相关产品推荐
相关产品推荐

