Next.js是React的全栈框架,支持服务端渲染(SSR)、静态生成(SSG)和API路由。在搬瓦工VPS上自建部署Next.js,可以完全控制服务器环境,不受Vercel等平台的限制。本文介绍从构建到上线的完整流程。
# 安装Node.js(使用NVM)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20
# 验证
node -v
npm -v
# 方式一:Git克隆
cd /var/www
git clone https://github.com/your-username/your-nextjs-app.git
cd your-nextjs-app
# 方式二:本地上传(使用rsync)
rsync -avz --exclude='node_modules' --exclude='.next' \
./your-nextjs-app/ root@your-vps-ip:/var/www/your-nextjs-app/
cd /var/www/your-nextjs-app
# 安装依赖
npm install
# 创建环境变量文件
nano .env.production
NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgresql://user:pass@localhost/dbname
# 构建生产版本
npm run build
# 构建完成后会生成 .next 目录
# 包含服务端和客户端的编译产物
Next.js的standalone输出模式可以生成独立的部署包,不依赖node_modules:
// next.config.js
module.exports = {
output: 'standalone',
};
# 重新构建
npm run build
# standalone模式生成的文件在 .next/standalone/
# 复制静态资源
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static
# 启动
node .next/standalone/server.js
# 安装PM2
npm install -g pm2
创建PM2配置文件 ecosystem.config.js:
module.exports = {
apps: [{
name: 'nextjs-app',
script: 'node_modules/.bin/next',
args: 'start',
cwd: '/var/www/your-nextjs-app',
instances: 1,
exec_mode: 'fork',
env: {
NODE_ENV: 'production',
PORT: 3000
},
max_memory_restart: '500M',
error_file: '/var/log/pm2/nextjs-error.log',
out_file: '/var/log/pm2/nextjs-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss'
}]
};
如果使用standalone模式:
module.exports = {
apps: [{
name: 'nextjs-app',
script: '.next/standalone/server.js',
cwd: '/var/www/your-nextjs-app',
instances: 1,
env: {
NODE_ENV: 'production',
PORT: 3000,
HOSTNAME: '127.0.0.1'
},
max_memory_restart: '500M'
}]
};
# 创建日志目录
sudo mkdir -p /var/log/pm2
# 启动应用
pm2 start ecosystem.config.js
# 设置开机自启
pm2 startup
pm2 save
# 查看状态
pm2 status
pm2 logs nextjs-app
sudo nano /etc/nginx/conf.d/nextjs.conf
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Next.js静态资源(_next目录)
location /_next/static/ {
alias /var/www/your-nextjs-app/.next/static/;
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
# 公共静态文件
location /public/ {
alias /var/www/your-nextjs-app/public/;
expires 30d;
access_log off;
}
# favicon等根目录静态文件
location /favicon.ico {
alias /var/www/your-nextjs-app/public/favicon.ico;
expires 30d;
access_log off;
}
# 其他请求代理到Next.js
location / {
proxy_pass http://127.0.0.1:3000;
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_cache_bypass $http_upgrade;
}
}
sudo nginx -t
sudo nginx -s reload
cd /var/www/your-nextjs-app
# 拉取最新代码
git pull origin main
# 安装依赖
npm install
# 重新构建
npm run build
# standalone模式需要重新复制静态文件
# cp -r public .next/standalone/public
# cp -r .next/static .next/standalone/.next/static
# 重启应用
pm2 reload nextjs-app
# 检查状态
pm2 status
如果Next.js应用不需要SSR,可以导出为纯静态文件,直接用Nginx托管:
// next.config.js
module.exports = {
output: 'export',
};
# 构建并导出
npm run build
# 静态文件生成在 out/ 目录
# Nginx直接指向该目录即可
# root /var/www/your-nextjs-app/out;
npm install sharpproxy_read_timeout 值NEXT_PUBLIC_ 前缀的变量在构建时注入,修改后需要重新构建Tip: 更多教程请查看新手教程。