ubuntu

Ubuntu Node.js应用如何实现自动化部署

小樊
47
2025-10-25 03:24:05
栏目: 编程语言

Ubuntu Node.js应用自动化部署实现指南

自动化部署是Node.js应用生产化的关键环节,能显著提升效率、减少人为错误。以下是基于Ubuntu系统的具体实现方案,涵盖环境准备、进程管理、反向代理及常用自动化工具(CI/CD/Ansible)的配置。

一、前置准备:环境与工具配置

1. 安装Node.js:使用NVM管理版本

直接通过apt安装的Node.js版本通常较旧,建议使用**NVM(Node Version Manager)**管理多版本,确保生产环境使用LTS(长期支持)版本。

# 安装NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc  # 激活NVM

# 安装最新LTS版本(如v20.x.x)
nvm install --lts
node -v  # 验证安装(应显示v20.x.x)

2. 安装PM2:进程管理与守护

PM2是Node.js应用的“守护进程”,可实现后台运行、崩溃自启、负载均衡等功能。

# 全局安装PM2
sudo npm install -g pm2

# 启动应用(假设入口文件为app.js,进程名为"my-app")
pm2 start app.js --name "my-app"

# 设置开机自启(生成systemd服务)
pm2 startup systemd  # 按提示执行生成的命令(如sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u deploy --hp /home/deploy)
pm2 save  # 保存当前进程列表,确保开机恢复

3. 配置Nginx:反向代理与HTTPS

Nginx作为反向代理,可将外部请求转发至Node.js应用(默认运行在3000端口),并提供HTTPS加密、静态资源缓存等功能。

# 安装Nginx
sudo apt install nginx

# 编辑配置文件(以域名my-domain.com为例)
sudo nano /etc/nginx/sites-available/my-domain.com

添加以下内容(替换your-domain.com/opt/my-app为实际值):

server {
    listen 80;
    server_name your-domain.com;
    location / {
        proxy_pass http://localhost:3000;  # 转发至Node.js应用
        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:

sudo ln -s /etc/nginx/sites-available/my-domain.com /etc/nginx/sites-enabled/
sudo nginx -t  # 测试配置语法
sudo systemctl reload nginx

二、自动化部署实现方案

1. 使用Shell脚本:简单直接的自动化

通过Shell脚本封装git pullnpm installpm2 restart等命令,实现一键部署。

# 创建deploy.sh脚本
nano deploy.sh

添加以下内容(替换/opt/my-app为项目路径):

#!/bin/bash
cd /opt/my-app || exit  # 进入项目目录
git pull origin main    # 拉取最新代码(假设分支为main)
npm install --production  # 安装生产依赖(跳过devDependencies)
pm2 restart my-app      # 重启PM2进程
echo "Deployment completed at $(date)"  # 记录部署时间

赋予执行权限:

chmod +x deploy.sh

每次部署时运行:

./deploy.sh

2. 使用GitHub Actions:云端CI/CD集成

GitHub Actions与GitHub仓库深度集成,可实现“代码推送→自动构建→自动部署”的全流程自动化。

# 在项目根目录创建.github/workflows/deploy.yml
nano .github/workflows/deploy.yml

添加以下配置(替换your-useryour-server-ip/var/www/html为实际值):

name: Deploy Node.js App to Ubuntu
on:
  push:
    branches:
      - main  # 当main分支有推送时触发

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      # 1. 检出代码
      - name: Checkout code
        uses: actions/checkout@v3
      
      # 2. 设置Node.js环境(使用LTS版本)
      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '16'
      
      # 3. 安装依赖并构建
      - name: Install dependencies and build
        run: |
          npm install
          npm run build  # 假设有build脚本(如生成dist目录)
      
      # 4. 部署到Ubuntu服务器(通过SCP)
      - name: Deploy to server
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}  # 在GitHub仓库Settings->Secrets中配置
          SERVER_USER: "your-user"
          SERVER_HOST: "your-server-ip"
          DEPLOY_PATH: "/var/www/html"
        run: |
          scp -o StrictHostKeyChecking=no -r ./dist ${SERVER_USER}@${SERVER_HOST}:${DEPLOY_PATH}
          ssh -o StrictHostKeyChecking=no ${SERVER_USER}@${SERVER_HOST} << 'EOF'
            cd ${DEPLOY_PATH}
            pm2 restart my-app  # 重启PM2进程
          EOF

说明

3. 使用Ansible:基础设施即代码(IaC)

Ansible通过YAML格式的Playbook定义部署流程,支持批量管理多台服务器,适合复杂环境。

# 在控制节点(如本地电脑)安装Ansible
sudo apt install ansible

# 创建Playbook文件(deploy.yml)
nano deploy.yml

添加以下内容(替换webservers为服务器组名,your-user/opt/my-app为实际值):

- hosts: webservers
  become: yes  # 以sudo权限执行
  vars:
    app_name: "my-app"
    app_dir: "/opt/{{ app_name }}"
  
  tasks:
    # 1. 安装Node.js(使用NodeSource仓库)
    - name: Add NodeSource repository
      apt_repository:
        repo: "deb https://deb.nodesource.com/node_16.x focal main"
        state: present
        filename: nodejs
      when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '20.04'
    
    - name: Install Node.js and npm
      apt:
        name:
          - nodejs
          - npm
        state: present
        update_cache: yes
    
    # 2. 安装PM2
    - name: Install PM2 globally
      npm:
        name: pm2
        global: yes
        state: present
    
    # 3. 创建项目目录
    - name: Create application directory
      file:
        path: "{{ app_dir }}"
        state: directory
        owner: "{{ ansible_user }}"
        group: "{{ ansible_user }}"
    
    # 4. 克隆代码仓库(若未克隆)
    - name: Clone Git repository
      git:
        repo: "https://github.com/your-username/your-node-app.git"
        dest: "{{ app_dir }}"
        version: main  # 分支名
    
    # 5. 安装依赖
    - name: Install production dependencies
      command: npm install --production
      args:
        chdir: "{{ app_dir }}"
    
    # 6. 重启PM2进程
    - name: Restart PM2 process
      command: pm2 restart {{ app_name }}
      args:
        chdir: "{{ app_dir }}"
      ignore_errors: yes  # 若进程未运行,忽略错误
    
    # 7. 保存PM2进程列表(确保开机自启)
    - name: Save PM2 process list
      command: pm2 save
      args:
        chdir: "{{ app_dir }}"

说明

4. 使用Jenkins:自定义CI/CD流水线

Jenkins是开源的CI/CD工具,适合需要高度自定义的场景(如多环境部署、手动审批)。

# 在Ubuntu服务器上安装Jenkins
sudo apt update
sudo apt install openjdk-11-jdk  # Jenkins依赖Java
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update
sudo apt install jenkins

# 启动Jenkins并设置开机自启
sudo systemctl start jenkins
sudo systemctl enable jenkins

访问http://your-server-ip:8080,按提示完成初始配置(解锁密码在/var/lib/jenkins/secrets/initialAdminPassword中)。

创建Jenkins Job

  1. 点击“New Item”,选择“Pipeline”,输入名称(如“Node.js Deploy”);
  2. 在“Pipeline”选项卡中,选择“Pipeline script from SCM”,SCM选择“Git”,填写仓库URL(如https://github.com/your-username/your-node-app.git);
  3. 在“Script Path”中填写Jenkinsfile(项目根目录下的流水线脚本);
  4. 点击“Save”。

编写Jenkinsfile(项目根目录下):

pipeline {
    agent any
    
    environment {
        NODE_ENV = 'production'
        DEPLOY_PATH = '/opt/my-app'
        SSH_USER = 'your-user'
        SSH_HOST = 'your-server-ip'
    }
    
    stages {
        // 1. 拉取代码
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-username/your-node-app.git'
            }
        }
        
        // 2. 安装依赖
        stage('Install Dependencies') {
            steps {
                sh 'npm install --production'
            }
        }
        
        // 3. 运行测试(若有)
        stage('Run Tests') {
            steps {
                sh 'npm test'
            }
        }
        
        // 4. 部署到服务器
        stage('Deploy') {
            steps {
                sh """
                    scp -o StrictHostKeyChecking=no -r . ${SSH_USER}@${SSH_HOST}:${DEPLOY_PATH}
                    ssh -o StrictHostKeyChecking=no ${SSH_USER}@${SSH_HOST} << 'EOF'
                        cd ${DEPLOY_PATH}
                        pm2 restart my-app
                    EOF
                """
            }
        }
    }
    
    post {
        always {
            echo 'Deployment pipeline completed.'
        }
        success {
            echo 'Deployment succeeded!'
        }
        failure {
            echo 'Deployment failed. Check logs for details.'
        }
    }
}

说明

三、注意事项

  1. 权限管理:确保部署脚本、Playbook或Jenkins Job有足够的权限访问项目目录和服务器;
  2. 环境一致性:使用package.json中的engines字段指定Node.js版本(如"engines": { "node": ">=16.0.0" }),避免环境差异;
  3. 零停机部署:对于高可用应用,可使用PM2的cluster mode(集群模式)或多服务器负载均衡,实现无缝升级;
  4. 日志与监控:通过PM2的logs命令(pm2 logs my-app)查看实时日志,或集成Prometheus+Grafana监控应用性能。

通过以上方案,可实现Ubuntu系统上Node.js应用的自动化部署,覆盖从环境准备到生产上线的完整流程。根据团队规模和项目需求,选择合适的工具组合(如Shell脚本+GitHub Actions适合小型项目,Ansible+Jenkins适合中大型项目),即可提升部署效率,保障应用稳定性。

0
看了该问题的人还看了