Ubuntu Node.js应用自动化部署实现指南
自动化部署是Node.js应用生产化的关键环节,能显著提升效率、减少人为错误。以下是基于Ubuntu系统的具体实现方案,涵盖环境准备、进程管理、反向代理及常用自动化工具(CI/CD/Ansible)的配置。
直接通过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)
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 # 保存当前进程列表,确保开机恢复
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
通过Shell脚本封装git pull、npm install、pm2 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
GitHub Actions与GitHub仓库深度集成,可实现“代码推送→自动构建→自动部署”的全流程自动化。
# 在项目根目录创建.github/workflows/deploy.yml
nano .github/workflows/deploy.yml
添加以下配置(替换your-user、your-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
说明:
Settings->Secrets中添加SSH_PRIVATE_KEY(服务器的私钥,用于SSH连接);npm run build步骤;DEPLOY_PATH)需与服务器上的项目目录一致。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 }}"
说明:
/etc/ansible/hosts中定义服务器组(webservers),例如:[webservers]
your-server-ip ansible_user=your-user ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible-playbook -i /etc/ansible/hosts deploy.yml
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:
https://github.com/your-username/your-node-app.git);Jenkinsfile(项目根目录下的流水线脚本);编写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.'
}
}
}
说明:
package.json中的engines字段指定Node.js版本(如"engines": { "node": ">=16.0.0" }),避免环境差异;cluster mode(集群模式)或多服务器负载均衡,实现无缝升级;logs命令(pm2 logs my-app)查看实时日志,或集成Prometheus+Grafana监控应用性能。通过以上方案,可实现Ubuntu系统上Node.js应用的自动化部署,覆盖从环境准备到生产上线的完整流程。根据团队规模和项目需求,选择合适的工具组合(如Shell脚本+GitHub Actions适合小型项目,Ansible+Jenkins适合中大型项目),即可提升部署效率,保障应用稳定性。