先把“部署”拆成四个真实问题

这套方案首先处理的不是“怎么把代码上传到服务器”,而是让前端应用、数据库、反向代理和后台进程在 Linux 上各自就位,并且能按生产方式协同工作。实际部署时,Next.js 通常承担页面渲染、接口转发和静态资源服务;MySQL 负责持久化数据;Nginx 负责统一入口、静态文件与动态请求分流;PM2 则维持 Node.js 进程,降低服务退出后无人重启的问题。把边界看清后,排查端口不通、页面打不开、接口返回异常等情况,才不会把所有请求都笼统归因于应用本身。

资料线索按顺序覆盖服务器初始化、Node.js 运行环境、Next.js 构建与生成产物、MySQL 连接、Nginx 反向代理、PM2 进程管理以及域名解析等环节。它值得看的不是某个命令,而是这些环节之间的依赖:Next.js 必须先能构建,MySQL 必须先能被应用访问,Nginx 代理地址还必须与 Next.js 实际监听地址一致。任何一步提前假设完成,后面出现错误时往往很难判断责任边界,所以按阶段推进比一次性运行全部操作更稳妥。

适合什么基础,以及哪些环节最容易被忽略

适合先掌握 HTML、CSS、JavaScript 基础,能够读懂 Next.js 路由、组件以及 API 路由的基本结构,并在本地完成一次 Next.js 构建的人。服务器部分不要求已经熟练编写复杂的 Nginx 配置,但至少能使用 SSH、终端、文本编辑器,理解域名、IP、端口和 HTTP 请求之间的关系。若从未接触过 Linux,仍可使用这套资料,不过应把“操作系统初始化、Node.js 安装、SSH 登录、文件权限”当作额外基础内容,不宜一开始就追求生产级效果。

比较值得精看的是 Next.js 的构建阶段。生产构建会决定哪些页面可以静态生成、哪些内容需要运行时处理,以及构建结果最终放在哪里;如果只完成安装和启动,却不检查构建产物,很容易出现首页正常、动态页面异常,或接口路径与代理规则不匹配。MySQL 连接部分同样需要细看,重点不是记住密码写法,而是确认环境变量只在服务端读取、数据库主机地址没有误写成公网地址、连接失败时能区分网络、账号权限和应用配置问题。

Nginx 部分建议先理解请求如何进入应用:浏览器访问域名后,Nginx 如何把普通页面、静态资源、API 请求和 Next.js 后端请求分别处理,以及反向代理需要补全哪些响应头。PM2 部分则要看清进程名称、启动命令、监听端口和自动重启条件,否则服务看似已启动,却可能在构建替换、进程崩溃或端口冲突后仍然不可用。最后还要检查域名是否确实指向当前服务器,以及证书签发所依赖的访问路径是否被正确放行。

建议先看哪几块,不必按表面顺序机械执行

正式动手前,先读服务器初始化、Node.js 运行环境和域名相关段落。初始化部分重点核对操作系统版本、基础软件更新、SSH 登录、防火墙以及用户权限;Node.js 部分重点确认版本是否稳定、命令是否已写入正确的 shell 环境,以及安装后是否真正验证成功。域名部分不必过早纠结证书细节,但至少要先确定准备使用的域名、服务器 IP 和最终访问入口,避免后面配置反向代理时反复返工。

接下来看 Next.js 构建与启动,再进入 MySQL、Nginx 和 PM2。构建与启动阶段要确认项目依赖、构建命令、输出目录和监听端口;数据库阶段要确认应用能够连接、查询,并明确数据库账号只访问必要库表;Nginx 阶段要对照实际端口和路径写代理规则;PM2 阶段则要把启动命令与环境变量和前面确认的结果对齐。最后再处理证书、域名解析和整体连通性检查,这样更容易定位错误发生在哪一层。

如果环境是全新服务器,资料中的初始化、Node.js、Next.js 构建和数据库连接可以先看;如果项目已经完成构建,只是上线失败,则应优先看 Next.js 输出位置、Nginx 代理规则、PM2 进程状态和域名解析。资料线索没有提供具体工具扩展或额外服务,因此阅读时不要自行假设存在其他平台能力,也不要把它理解成一键式托管方案。真正需要掌握的是每一步为什么存在、前后步骤依赖什么,以及失败时如何缩小排查范围。

学完能独立做什么,以及资料如何配合练习

按资料完成并理解后,可以独立完成一个基于 Next.js 和 MySQL 的 Web 应用在 Ubuntu 服务器上的基础生产部署:准备服务器和 Node.js 环境,构建并启动应用,配置数据库连接,用 Nginx 统一接收访问,用 PM2 管理进程,再处理域名和 HTTPS 入口。这里的“独立完成”指能够根据日志、端口状态和请求路径定位常见故障,而不是只看一遍命令就认为系统已经稳定。数据库表结构、应用业务逻辑和复杂高可用架构并不在这套资料的核心范围内。

练习时可以把资料拆成“环境准备、应用构建、数据库连通、代理配置、进程维护”五组,而不是一次性照抄全部操作。每组完成后都留一个可验证结果:Node.js 能输出版本,Next.js 能生成生产构建,应用能通过指定端口访问,MySQL 能执行一次查询,Nginx 能返回正确页面,PM2 能显示目标进程处于运行状态。每完成一组就记录修改过的文件、端口、环境变量和报错信息,后续复查会快很多。

练习过程中应主动制造并检查几类典型故障:修改 Nginx 代理端口后观察请求是否失败,停止 PM2 进程后确认服务不可用,修改数据库连接信息后区分配置错误与网络错误,再恢复配置并重新验证。这样的练习比单纯记录成功步骤更能检验理解。资料包的价值正在于把服务器初始化、应用构建、数据库连接、反向代理和进程管理连成一条可验证的链路,适合用“先读依赖关系、再分组操作、最后逐项排错”的方式拆开使用。

f1b9fe6a-c497-49c1-bdde-b526a8d1fbbe.png

# ============================================
# Next.js + Nginx 生产部署完整步骤
# 操作系统:Ubuntu 22.04/24.04 (Linux 6.8.0-90-generic)
# ============================================

# ============ 第一阶段:服务器初始化 ============

# 1.1 系统更新
sudo apt update && sudo apt upgrade -y

# 1.2 安装 Node.js 20.x LTS (推荐稳定版本)
curl -fsSL  | sudo -E bash -
sudo apt install -y nodejs

# 验证安装
node --version  # 应该显示 v20.x.x
npm --version   # 显示对应 npm 版本

# 1.3 安装 Nginx
sudo apt install -y nginx

# 1.4 安装 PM2 (进程管理)
sudo npm install -g pm2

# 1.5 配置防火墙
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'  # 开放 HTTP(80) 和 HTTPS(443)
sudo ufw --force enable
sudo ufw status

# ============ 第二阶段:上传项目并构建 ============

# 2.1 在服务器创建项目目录
sudo mkdir -p /var/www/my-nextjs-app
sudo chown -R $USER:$USER /var/www/my-nextjs-app

# 2.2 【在您本地电脑】上传项目文件到服务器
# 假设您本地项目目录是 ~/projects/my-nextjs-app
# 请替换 username 和 your-server-ip 为您的实际信息
# 本地终端执行:
# rsync -avz --exclude='node_modules' --exclude='.next' --exclude='.git' ~/projects/my-nextjs-app/ username@your-server-ip:/var/www/my-nextjs-app/

# 2.3 SSH登录服务器并进入项目目录
ssh username@your-server-ip
cd /var/www/my-nextjs-app

# 2.4 安装项目依赖并构建
npm ci  # 或 npm install

# 2.5 创建生产环境变量 (根据您的项目需要)
cat > .env.production << EOF
NODE_ENV=production
# 添加您的生产环境变量,例如:
# DATABASE_URL=your_production_db_url
# NEXT_PUBLIC_API_URL=
EOF

# 2.6 构建 Next.js 应用
npm run build

# 注意:如果构建失败,请查看具体错误信息并修复
# 常见问题:内存不足、TypeScript错误、依赖缺失等

# ============ 第三阶段:配置 PM2 进程守护 ============

# 3.1 创建 PM2 配置文件
cat > ecosystem.config.js << 'EOF'
module.exports = {
  apps: [{
    name: 'my-nextjs-app',
    script: 'npm',
    args: 'start',
    cwd: '/var/www/my-nextjs-app',
    instances: 1,
    exec_mode: 'fork',
    autorestart: true,
    watch: false,
    max_memory_restart: '1G',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: '/var/log/pm2/my-nextjs-app-error.log',
    out_file: '/var/log/pm2/my-nextjs-app-out.log',
    log_file: '/var/log/pm2/my-nextjs-app-combined.log',
    time: true
  }]
}
EOF

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

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

# 3.4 设置 PM2 开机自启
pm2 startup
# 执行上述命令后,会显示一条需要以root身份运行的命令,复制并执行它
# 示例:sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u username --hp /home/username

# 3.5 保存当前进程列表
pm2 save

# 3.6 查看应用状态
pm2 status
pm2 logs my-nextjs-app --lines 50  # 查看最近50行日志

# ============ 第四阶段:配置 Nginx 反向代理 ============

# 4.1 创建 Nginx 站点配置文件
sudo vim /etc/nginx/sites-available/my-nextjs-app

# 将以下配置粘贴到文件中(按 i 进入插入模式,粘贴后按 Esc,输入 :wq 保存)
# --------------------------------------------------
server {
    listen 80;
    listen [::]:80;
    
    # 您的域名(如果没有域名,用服务器IP地址)
    server_name your-domain.com www.your-domain.com;
    # 或 server_name 123.123.123.123; # 您的服务器IP
    
    # 日志文件
    access_log /var/log/nginx/my-nextjs-app.access.log;
    error_log /var/log/nginx/my-nextjs-app.error.log;
    
    # 反向代理配置
    location / {
        proxy_pass 
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        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;
    }
    
    # 可选:静态资源缓存(提升性能)
    location /_next/static {
        proxy_cache STATIC;
        proxy_ignore_headers Cache-Control;
        proxy_cache_valid 200 60d;
        proxy_pass 
    }
}
# --------------------------------------------------

# 4.2 启用站点配置
sudo ln -s /etc/nginx/sites-available/my-nextjs-app /etc/nginx/sites-enabled/

# 4.3 移除默认配置(如果存在)
sudo rm -f /etc/nginx/sites-enabled/default

# 4.4 测试 Nginx 配置语法
sudo nginx -t
# 应该显示:nginx: configuration file /etc/nginx/nginx.conf test is successful

# 4.5 重启 Nginx
sudo systemctl restart nginx

# ============ 第五阶段:验证部署 ============

# 5.1 检查所有服务状态
sudo systemctl status nginx
pm2 status

# 5.2 测试应用是否运行
curl -I 
curl -I 

# 5.3 查看实时日志
# 在一个终端窗口查看 PM2 日志
pm2 logs my-nextjs-app --lines 100

# 在另一个终端窗口查看 Nginx 日志
sudo tail -f /var/log/nginx/my-nextjs-app.access.log
# 或错误日志
sudo tail -f /var/log/nginx/my-nextjs-app.error.log

# 5.4 测试公网访问
# 打开浏览器访问: 或 

# ============ 第六阶段:HTTPS 配置(可选但推荐) ============

# 6.1 安装 Certbot (用于获取免费 SSL 证书)
sudo apt install -y certbot python3-certbot-nginx

# 6.2 获取 SSL 证书(需要有已解析到服务器的域名)
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

# 按照提示操作,Certbot 会自动配置 Nginx 支持 HTTPS

# 6.3 设置证书自动续期
sudo certbot renew --dry-run

# ============ 第七阶段:故障排除 ============

# 7.1 如果遇到 502 Bad Gateway
# 检查 Next.js 是否在运行
pm2 status
# 检查端口占用
sudo netstat -tulpn | grep :3000
sudo netstat -tulpn | grep :80

# 7.2 如果遇到权限问题
sudo chown -R www-data:www-data /var/log/nginx/
sudo chmod -R 755 /var/www/my-nextjs-app

# 7.3 重启所有服务
pm2 restart my-nextjs-app
sudo systemctl restart nginx

# 7.4 查看系统资源
htop
free -h
df -h

# ============ 第八阶段:创建部署脚本(简化后续更新) ============

# 8.1 创建部署脚本
cat > /var/www/my-nextjs-app/deploy.sh << 'EOF'
#!/bin/bash
echo "🚀 开始部署 Next.js 应用..."

cd /var/www/my-nextjs-app

echo "1. 拉取最新代码..."
git pull origin main

echo "2. 安装依赖..."
npm ci

echo "3. 构建应用..."
npm run build

echo "4. 重启应用..."
pm2 restart my-nextjs-app

echo "5. 检查状态..."
pm2 status

echo "✅ 部署完成!"
EOF

# 8.2 给脚本执行权限
chmod +x /var/www/my-nextjs-app/deploy.sh

# 以后更新应用只需运行:
# cd /var/www/my-nextjs-app && ./deploy.sh

# ============ 完成! ============
echo "========================================"
echo "部署完成!请访问您的服务器IP地址或域名"
echo "========================================"
echo "PM2 管理命令:"
echo "  pm2 status                 # 查看状态"
echo "  pm2 logs my-nextjs-app     # 查看日志"
echo "  pm2 restart my-nextjs-app  # 重启应用"
echo "  pm2 stop my-nextjs-app     # 停止应用"
echo ""
echo "Nginx 管理命令:"
echo "  sudo systemctl status nginx"
echo "  sudo systemctl restart nginx"
echo "  sudo nginx -t              # 测试配置"