简介:本文详细介绍如何将Node.js项目部署到云服务器,涵盖环境准备、安全配置、自动化部署等关键环节,帮助开发者快速构建稳定的生产环境。
主流云服务商(如阿里云、腾讯云、AWS等)均提供多种实例类型:
建议根据项目QPS和内存占用选择实例,初期可选择2核4G配置,后续通过弹性伸缩横向扩展。
推荐使用Ubuntu 22.04 LTS或CentOS 8:
通过SSH连接服务器后,首先执行系统更新:
# Ubuntu系统sudo apt update && sudo apt upgrade -y# CentOS系统sudo yum update -y
推荐使用nvm进行多版本管理:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bashsource ~/.bashrcnvm install --ltsnvm use --lts
验证安装:
node -v # 应输出类似v18.16.0npm -v # 应输出类似9.5.1
将项目代码克隆至服务器后,需注意:
--production参数跳过devDependencies
# 配置淘宝镜像npm config set registry https://registry.npmmirror.com# 安装生产依赖npm install --production
推荐使用PM2进行进程管理:
npm install pm2 -gpm2 startup # 生成开机自启脚本pm2 save # 保存当前进程列表
启动配置示例(ecosystem.config.js):
module.exports = {apps: [{name: 'api-service',script: './dist/main.js',instances: 'max', // 自动根据CPU核心数启动exec_mode: 'cluster',env: {NODE_ENV: 'production',PORT: 3000},error_file: '/var/log/pm2/api-error.log',out_file: '/var/log/pm2/api-out.log'}]};
使用Nginx作为反向代理:
server {listen 80;server_name api.example.com;location / {proxy_pass http://127.0.0.1:3000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 静态资源缓存location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {expires 30d;access_log off;}}
使用ufw(Ubuntu)或firewalld(CentOS)限制访问:
# Ubuntu系统sudo ufw allow 22/tcp # SSH端口sudo ufw allow 80/tcp # HTTP端口sudo ufw allow 443/tcp # HTTPS端口sudo ufw enable# CentOS系统sudo firewall-cmd --permanent --add-port=22/tcpsudo firewall-cmd --permanent --add-port=80/tcpsudo firewall-cmd --reload
/etc/ssh/sshd_config)
PermitRootLogin no
# 客户端生成密钥对ssh-keygen -t rsa -b 4096# 上传公钥到服务器ssh-copy-id -i ~/.ssh/id_rsa.pub user@server_ip
在项目根目录创建.git/hooks/post-receive:
#!/bin/bashTARGET="/var/www/api"GIT_DIR="/var/repo/api.git"BRANCH="main"while read oldrev newrev refdoif [[ $ref = refs/heads/$BRANCH ]];thenecho "Ref $ref received. Deploying ${BRANCH} branch to production..."git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCHcd $TARGETnpm install --productionpm2 reload ecosystem.config.jselseecho "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."fidone
以GitHub Actions为例:
name: Deploy to Productionon:push:branches: [ main ]jobs:deploy:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v3- name: Install Node.jsuses: actions/setup-node@v3with:node-version: '18'- name: Install dependenciesrun: npm ci --production- name: Deploy to serveruses: appleboy/ssh-action@masterwith:host: ${{ secrets.SERVER_IP }}username: ${{ secrets.SERVER_USER }}key: ${{ secrets.SSH_PRIVATE_KEY }}script: |cd /var/www/apigit pull origin mainnpm ci --productionpm2 reload ecosystem.config.js
推荐使用winston+logstash组合:
const winston = require('winston');const { combine, timestamp, json } = winston.format;const logger = winston.createLogger({level: 'info',format: combine(timestamp(),json()),transports: [new winston.transports.File({filename: '/var/log/api/error.log',level: 'error'}),new winston.transports.File({filename: '/var/log/api/combined.log'})]});
pm2 monit
# 查找占用端口的进程sudo lsof -i :3000# 终止指定进程sudo kill -9 <PID>
pm2 list查看内存占用pm2 logs检查错误日志
npm cache clean --force
yarn替代npm通过以上系统化的部署方案,开发者可以构建出高可用、易维护的Node.js生产环境。实际部署时建议先在测试环境验证所有流程,再逐步推广到生产环境。