前置
- 一台 VPS(你 51testgame.com 在香港的那台)
- 装好 Node 22 LTS、Nginx、git
- 域名解析到服务器 IP
- HTTPS 证书(你已经有)
流程概览
本地 git push → 服务器 git pull → npm ci + npm run build → systemctl reload
↓
Nginx 反代 :3000
第一次部署
1. 服务器装环境(CentOS)
# Node 22
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo dnf install -y nodejs
# git / nginx 应该已经有
node -v # v22.x
nginx -v
2. 拉代码
sudo mkdir -p /var/www
sudo chown $USER:$USER /var/www
cd /var/www
git clone git@github.com:you/my-site.git
cd my-site
3. 装依赖 + 构建
npm ci # 干净安装(用 package-lock.json)
npm run build # 生成 .next/ 生产构建
4. 用 systemd 跑
sudo vim /etc/systemd/system/my-site.service
[Unit]
Description=My Site (Next.js)
After=network.target
[Service]
Type=simple
User=wadely
WorkingDirectory=/var/www/my-site
ExecStart=/usr/bin/npm run start
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now my-site
sudo systemctl status my-site
确认监听 :3000:
ss -tlnp | grep 3000
curl http://localhost:3000
5. Nginx 反代
/etc/nginx/conf.d/my-site.conf:
server {
listen 80;
server_name 51testgame.com www.51testgame.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name 51testgame.com www.51testgame.com;
ssl_certificate /etc/letsencrypt/live/51testgame.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/51testgame.com/privkey.pem;
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
# 静态资源长缓存
location /_next/static/ {
proxy_pass http://127.0.0.1:3000;
add_header Cache-Control "public, max-age=31536000, immutable";
}
location /static/ {
proxy_pass http://127.0.0.1:3000;
add_header Cache-Control "public, max-age=31536000, immutable";
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo nginx -t && sudo systemctl reload nginx
打开 https://51testgame.com 看到 Next.js 站点 = 成功。
后续部署(更新代码)
写一个 deploy.sh 放在服务器:
#!/bin/bash
set -e
cd /var/www/my-site
git pull
npm ci --omit=dev # 生产装依赖(不装 devDeps)
npm install --no-save --include=dev # 装构建用的 devDeps
npm run build
sudo systemctl restart my-site
echo "✓ Deployed at $(date)"
chmod +x deploy.sh
之后:
ssh wadely@51testgame.com '/var/www/my-site/deploy.sh'
用 GitHub Actions 自动部署
.github/workflows/deploy.yml:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.DEPLOY_KEY }}
- name: Deploy
run: |
ssh -o StrictHostKeyChecking=no wadely@${{ secrets.SERVER_IP }} \
'/var/www/my-site/deploy.sh'
仓库 Settings → Secrets and variables → Actions 加:
DEPLOY_KEY:服务器的 deploy 私钥SERVER_IP:51testgame.com 的 IP
之后 git push 自动部署。
环境变量
.env.production(不进 git):
DATABASE_URL=postgresql://...
NEXTAUTH_SECRET=xxx
或 systemd unit 里:
Environment=DATABASE_URL=postgresql://...
EnvironmentFile=/etc/my-site/env
/etc/my-site/env:
DATABASE_URL=postgresql://...
sudo chmod 600 /etc/my-site/env # 限制权限
sudo chown wadely:wadely /etc/my-site/env
用 PM2 替代 systemd
如果觉得 systemd 麻烦:
npm install -g pm2
cd /var/www/my-site
pm2 start npm --name my-site -- start
pm2 save
pm2 startup # 配开机自启(按提示一行命令)
更新部署:
git pull
npm ci && npm run build
pm2 reload my-site # 零停机重启
性能优化
1. 启用 Next.js standalone 输出
next.config.ts:
const config = {
output: 'standalone',
};
npm run build 后生成 .next/standalone/ —— 只包含必要文件,部署体积减半。
启动改成:
node .next/standalone/server.js
2. 多实例(cluster)
pm2 start npm --name my-site -i max -- start # 按 CPU 核数起
或 systemd 多 unit + Nginx upstream 负载均衡。
3. CDN 加速
国内访问:
- 静态资源(
/_next/static/*)放到对象存储 + CDN(阿里 OSS / 腾讯 COS) - 改
next.config.ts的assetPrefix:
const config = {
assetPrefix: process.env.NODE_ENV === 'production' ? 'https://cdn.51testgame.com' : '',
};
监控
# 看日志
sudo journalctl -u my-site -f # systemd
pm2 logs my-site # pm2
# 看资源
sudo systemctl status my-site
top -p $(pgrep -f "next start")
坑
- 内存不够大的 VPS(1G)build 时 OOM——加 swap 或在本地 build 再 rsync
npm ci --omit=dev不装 devDeps 但 build 需要——分两步装- Server Action 提交大 body → Nginx 配置
client_max_body_size 50M - 改了
.env后必须重启服务——Next.js 启动期读取
至此 17 篇 react-quick 完成。下一步去 react-advanced 系列深入 React。