Skip to main content

Nginx 直接部署指南

本指南说明如何在 Linux 服务器上使用 Nginx + PM2 直接部署 Next.js 应用。

📋 系统要求

  • 操作系统: Ubuntu 20.04+ / CentOS 7+ / Debian 10+
  • Node.js: >= 18.17.0
  • Nginx: >= 1.18
  • PM2: >= 5.0
  • 内存: 2GB+
  • 磁盘: 5GB+

🚀 快速开始

1. 安装必需软件

安装 Node.js (Ubuntu/Debian)

# 使用 NodeSource 仓库安装 Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# 验证安装
node --version
npm --version

安装 Node.js (CentOS/RHEL)

curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo yum install -y nodejs

# 验证安装
node --version
npm --version

安装 Nginx (Ubuntu/Debian)

sudo apt update
sudo apt install -y nginx

# 启动 Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# 验证安装
nginx -v

安装 Nginx (CentOS/RHEL)

sudo yum install -y epel-release
sudo yum install -y nginx

# 启动 Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# 验证安装
nginx -v

安装 PM2

sudo npm install -g pm2

# 验证安装
pm2 --version

2. 准备项目

# 创建项目目录
sudo mkdir -p /var/www/pay-unify-frontend
sudo chown -R $USER:$USER /var/www/pay-unify-frontend

# 克隆或上传项目
cd /var/www/pay-unify-frontend
git clone <your-repo-url> .

# 或使用 rsync 上传
# rsync -avz --progress ./frontend/ user@server:/var/www/pay-unify-frontend/

3. 配置环境变量

cd /var/www/pay-unify-frontend

# 创建生产环境配置
cat > .env.production << 'EOF'
NODE_ENV=production
NEXT_PUBLIC_API_URL=http://124.222.202.16:8080
EOF

4. 安装依赖并构建

# 安装依赖
npm install --production=false

# 构建项目
npm run build

# 验证构建
ls -la .next/

5. 配置 PM2

创建 PM2 配置文件 ecosystem.config.js

cat > ecosystem.config.js << 'EOF'
module.exports = {
apps: [{
name: 'pay-unify-frontend',
script: 'node_modules/next/dist/bin/next',
args: 'start',
cwd: '/var/www/pay-unify-frontend',
instances: 2,
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3000
},
error_file: '/var/log/pm2/pay-unify-frontend-error.log',
out_file: '/var/log/pm2/pay-unify-frontend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
max_memory_restart: '500M',
autorestart: true,
watch: false
}]
}
EOF

# 创建日志目录
sudo mkdir -p /var/log/pm2
sudo chown -R $USER:$USER /var/log/pm2

6. 启动应用

# 启动应用
pm2 start ecosystem.config.js

# 查看状态
pm2 status

# 查看日志
pm2 logs pay-unify-frontend

# 保存 PM2 配置
pm2 save

# 设置开机自启
pm2 startup
# 执行上述命令输出的命令

7. 配置 Nginx

# 创建 Nginx 配置文件
sudo tee /etc/nginx/sites-available/pay-unify-frontend << 'EOF'
# Upstream Next.js 服务
upstream nextjs_backend {
server 127.0.0.1:3000;
keepalive 64;
}

# HTTP 服务器
server {
listen 80;
listen [::]:80;
server_name _; # 替换为你的域名

# 日志文件
access_log /var/log/nginx/pay-unify-access.log;
error_log /var/log/nginx/pay-unify-error.log;

# 客户端上传大小限制
client_max_body_size 20M;

# Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss;

# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

# 代理到 Next.js
location / {
proxy_pass http://nextjs_backend;
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;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}

# Next.js 静态文件缓存
location /_next/static {
proxy_pass http://nextjs_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
add_header Cache-Control "public, max-age=31536000, immutable";
}

# 图片缓存
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
proxy_pass http://nextjs_backend;
add_header Cache-Control "public, max-age=2592000";
}

# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
EOF

# 启用站点
sudo ln -sf /etc/nginx/sites-available/pay-unify-frontend /etc/nginx/sites-enabled/

# 删除默认站点(可选)
sudo rm -f /etc/nginx/sites-enabled/default

# 测试 Nginx 配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx

8. 配置防火墙

# UFW (Ubuntu/Debian)
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable

# Firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

9. 验证部署

# 检查 PM2 状态
pm2 status

# 检查 Nginx 状态
sudo systemctl status nginx

# 测试应用
curl http://localhost
curl http://your-server-ip

🔄 更新部署

标准更新流程

# 1. 拉取最新代码
cd /var/www/pay-unify-frontend
git pull

# 2. 安装新依赖
npm install

# 3. 重新构建
npm run build

# 4. 重启 PM2
pm2 restart pay-unify-frontend

# 5. 查看日志确认
pm2 logs pay-unify-frontend --lines 50

零停机更新(推荐)

# 使用 PM2 的重载功能
pm2 reload ecosystem.config.js

# 或单独重载应用
pm2 reload pay-unify-frontend

自动化更新脚本

创建 deploy-update.sh

cat > deploy-update.sh << 'EOF'
#!/bin/bash
set -e

APP_DIR="/var/www/pay-unify-frontend"
APP_NAME="pay-unify-frontend"

echo "🚀 开始更新部署..."

# 切换到项目目录
cd $APP_DIR

# 拉取最新代码
echo "📥 拉取最新代码..."
git pull

# 安装依赖
echo "📦 安装依赖..."
npm install

# 构建项目
echo "🔨 构建项目..."
npm run build

# 重载应用(零停机)
echo "♻️ 重载应用..."
pm2 reload $APP_NAME

# 保存 PM2 配置
pm2 save

echo "✅ 更新完成!"

# 显示状态
pm2 status
EOF

chmod +x deploy-update.sh

使用脚本更新:

./deploy-update.sh

🔧 常用命令

PM2 管理命令

# 查看所有应用状态
pm2 status

# 查看特定应用状态
pm2 show pay-unify-frontend

# 启动应用
pm2 start ecosystem.config.js

# 停止应用
pm2 stop pay-unify-frontend

# 重启应用
pm2 restart pay-unify-frontend

# 重载应用(零停机)
pm2 reload pay-unify-frontend

# 删除应用
pm2 delete pay-unify-frontend

# 查看日志
pm2 logs pay-unify-frontend

# 查看实时日志
pm2 logs pay-unify-frontend --lines 100

# 清空日志
pm2 flush

# 监控
pm2 monit

Nginx 管理命令

# 测试配置
sudo nginx -t

# 重新加载配置(不中断服务)
sudo nginx -s reload

# 重启 Nginx
sudo systemctl restart nginx

# 查看状态
sudo systemctl status nginx

# 查看访问日志
sudo tail -f /var/log/nginx/pay-unify-access.log

# 查看错误日志
sudo tail -f /var/log/nginx/pay-unify-error.log

🐛 故障排查

问题 1: 应用无法启动

检查 PM2 日志

pm2 logs pay-unify-frontend --err

常见原因

  • 端口被占用:lsof -i :3000
  • 构建失败:检查 .next 目录
  • 环境变量问题:检查 .env.production

问题 2: Nginx 502 Bad Gateway

原因:无法连接到 Next.js 应用

解决方案

# 检查 PM2 应用是否运行
pm2 status

# 检查端口监听
netstat -tlnp | grep 3000

# 测试 Next.js 应用
curl http://localhost:3000

# 检查 Nginx 配置
sudo nginx -t

问题 3: 内存泄漏

症状:应用不断重启

解决方案

# 查看内存使用
pm2 monit

# 增加内存限制(编辑 ecosystem.config.js)
max_memory_restart: '1G'

# 重启应用
pm2 restart pay-unify-frontend

问题 4: 日志文件过大

解决方案

# 安装 PM2 日志轮转
pm2 install pm2-logrotate

# 配置日志轮转
pm2 set pm2-logrotate:max_size 100M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

🔐 HTTPS 配置

使用 Let's Encrypt (推荐)

# 安装 Certbot
sudo apt install certbot python3-certbot-nginx # Ubuntu/Debian
# 或
sudo yum install certbot python3-certbot-nginx # CentOS

# 获取证书并自动配置 Nginx
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

# 测试自动续期
sudo certbot renew --dry-run

手动配置 SSL

如果已有证书:

# 编辑 Nginx 配置
sudo nano /etc/nginx/sites-available/pay-unify-frontend

添加 HTTPS 服务器块:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your-domain.com;

# SSL 证书
ssl_certificate /etc/ssl/certs/your-cert.pem;
ssl_certificate_key /etc/ssl/private/your-key.pem;

# SSL 优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

# HSTS
add_header Strict-Transport-Security "max-age=31536000" always;

# 其他配置同 HTTP...
}

# HTTP 重定向到 HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}

📊 监控和性能

系统监控

# 查看系统资源
htop

# 查看进程
ps aux | grep node

# 查看磁盘使用
df -h

# 查看内存使用
free -h

应用监控

# PM2 监控
pm2 monit

# 查看详细指标
pm2 show pay-unify-frontend

# 安装 PM2 Web 监控
pm2 install pm2-server-monit

Nginx 日志分析

# 访问统计
sudo cat /var/log/nginx/pay-unify-access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

# 状态码统计
sudo cat /var/log/nginx/pay-unify-access.log | awk '{print $9}' | sort | uniq -c | sort -rn

# 最常访问的页面
sudo cat /var/log/nginx/pay-unify-access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -10

🔧 性能优化

1. 启用 PM2 集群模式

已在 ecosystem.config.js 中配置:

instances: 2,  // 或 'max' 使用所有 CPU 核心
exec_mode: 'cluster'

2. 配置 Nginx 缓存

编辑 Nginx 配置:

# 在 http 块中添加
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=nextjs_cache:10m max_size=1g inactive=60m;

# 在 location / 块中添加
location / {
proxy_cache nextjs_cache;
proxy_cache_valid 200 60m;
proxy_cache_use_stale error timeout http_500 http_502 http_503;
# ...
}

创建缓存目录:

sudo mkdir -p /var/cache/nginx
sudo chown -R www-data:www-data /var/cache/nginx

3. 启用 HTTP/2

确保 Nginx 版本 >= 1.9.5,在 SSL 配置中:

listen 443 ssl http2;

🗄️ 备份策略

创建备份脚本

cat > /home/$USER/backup-frontend.sh << 'EOF'
#!/bin/bash

BACKUP_DIR="/backup/pay-unify-frontend"
APP_DIR="/var/www/pay-unify-frontend"
DATE=$(date +%Y%m%d_%H%M%S)

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份代码
tar -czf $BACKUP_DIR/code-$DATE.tar.gz -C $APP_DIR \
--exclude='node_modules' \
--exclude='.next' \
--exclude='.git' \
.

# 备份 PM2 配置
pm2 save

# 保留最近 7 天的备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "✅ 备份完成: $BACKUP_DIR/code-$DATE.tar.gz"
EOF

chmod +x /home/$USER/backup-frontend.sh

设置定时备份

# 编辑 crontab
crontab -e

# 添加每天凌晨 2 点备份
0 2 * * * /home/$USER/backup-frontend.sh

📚 相关资源


最后更新: 2025年11月24日