CircleCI通过SSH部署Node.js至多服务器的技术问题咨询
CircleCI部署Node.js后端的优化问题
原CircleCI配置
version: 2.1 jobs: build: docker: - image: cimg/node:16.13.2 steps: - checkout - run: command: npm install name: npm install - run: command: npm run build name: npm build - persist_to_workspace: root: ~/ paths: - . deploy: docker: - image: cimg/base:2021.04 steps: - attach_workspace: at: ~/ - add_ssh_keys: fingerprints: - "$SSH_FINGERPRINT" - run: name: ssh command: scp -o StrictHostKeyChecking=no -r dist/* "$SSH_USER@$SSH_HOST:/var/www" workflows: build-and-deploy: jobs: - build - deploy: requires: - build
问题解答
1. 构建机执行npm install后scpnode_modules到目标服务器,vs 目标服务器git pull后执行npm install,哪种方案更快、成本更低且更安全?
(注:无静态页面,无需npm run build)
方案对比&结论:
- scp复制
node_modules的可行性:仅当构建机和目标服务器的操作系统、CPU架构完全一致时可行。因为部分npm包会编译二进制文件(如node-sass、bcrypt),跨架构/系统复制会导致包无法运行;纯JS包场景下虽能运行,但实际项目很难完全规避二进制依赖。 - 速度层面:
- 首次部署:
git pull+本地npm install更快,仅需拉取代码,node_modules从npm源下载(目标服务器带宽充足时优势明显);scp需传输整个node_modules,体积大、耗时久。 - 后续部署:
git pull+本地install可利用npm缓存,仅更新变更包;scp除非做增量同步,否则每次都要传完整node_modules,速度劣势明显。
- 首次部署:
- 成本层面:
CircleCI按构建机运行时间计费,scp传输大文件会占用更多构建时间,增加CI成本;目标服务器本地install仅需CI传输代码,构建时间更短,CI成本更低(目标服务器资源为自有Droplet,成本固定)。 - 安全层面:
- scp方案:构建机需拥有目标服务器的SSH权限,一旦构建机泄露,目标服务器直接暴露;若
node_modules包含恶意包,会直接同步到服务器,风险不可控。 git pull+本地install方案:目标服务器可配置只读SSH密钥拉取代码,权限范围更小;npm install时可通过npm audit自动检测恶意包,风险可控性更高。
- scp方案:构建机需拥有目标服务器的SSH权限,一旦构建机泄露,目标服务器直接暴露;若
最终结论:优先选择**目标服务器git pull后执行npm install**的方案,更稳定、成本更低且更安全。若担心目标服务器安装速度,可配置国内npm镜像源(如淘宝镜像),或用pnpm替代npm提升安装效率。
2. 如何实现同时部署到多台服务器?
两种可行实现方式:
方式一:在deploy job中遍历服务器列表
适合服务器数量较少的场景,操作简单直接:- 在CircleCI项目环境变量中配置
SSH_HOSTS,值为空格分隔的服务器地址,如server1.yourdomain.com server2.yourdomain.com - 修改deploy job的run步骤:
- run: name: Deploy to multiple servers command: | for host in $SSH_HOSTS; do # 拉取最新代码 ssh -o StrictHostKeyChecking=no $SSH_USER@$host "cd /var/www && git pull origin main" # 安装生产环境依赖 ssh -o StrictHostKeyChecking=no $SSH_USER@$host "cd /var/www && npm install --production" # 重启服务(以pm2为例,可替换为你的服务管理命令) ssh -o StrictHostKeyChecking=no $SSH_USER@$host "pm2 restart your-app-name" done- 在CircleCI项目环境变量中配置
方式二:使用CircleCI矩阵(matrix)功能并行部署
适合服务器数量较多的场景,可并行执行部署,速度更快且单台服务器部署状态独立:- 修改workflow和deploy job配置:
workflows: build-and-deploy: jobs: - build - deploy: requires: - build matrix: parameters: ssh_host: - "server1.yourdomain.com" - "server2.yourdomain.com" - "server3.yourdomain.com" deploy: docker: - image: cimg/base:2021.04 parameters: ssh_host: type: string steps: - add_ssh_keys: fingerprints: - "$SSH_FINGERPRINT" - run: name: Deploy to << parameters.ssh_host >> command: | ssh -o StrictHostKeyChecking=no $SSH_USER@<< parameters.ssh_host >> "cd /var/www && git pull origin main && npm install --production && pm2 restart your-app-name"配置后,CircleCI会为每台服务器启动独立的deploy job,并行执行部署操作。
内容的提问来源于stack exchange,提问作者Sam Leurs
相关产品推荐
相关产品推荐

