LHIDC

海外服务器部署Next.js SSR站点,PM2、Nginx反向代理与HTTPS配置如何配合

面向前端开发工程师,梳理Next.js SSR站点部署到海外服务器的关键流程,包括Node.js环境准备、PM2守护、Nginx反向代理、HTTPS证书配置及重启后可用性验证。

海外服务器部署Next.js SSR站点,PM2、Nginx反向代理与HTTPS配置如何配合

目标状态:让 Next.js SSR、PM2、Nginx 与 HTTPS 各司其职

Next.js 项目在本地 npm run build 正常,传到海外服务器后却常见几类问题:关闭 SSH 后站点不可访问;浏览器访问域名返回 502;HTTP 能打开但 HTTPS 证书签发失败;服务器重启后 Node 进程没有自动恢复。这些问题通常不是 Next.js 本身导致的,而是进程管理、反向代理和证书配置没有形成完整链路。

部署 Next.js SSR 站点时,推荐的目标状态是:

  • Next.js SSR 应用只监听服务器本机地址,例如 127.0.0.1:3000
  • PM2 负责守护 Node.js 进程,并配置开机自启;
  • Nginx 对外监听 80/443,通过 Nginx反向代理 转发请求到 Next.js;
  • HTTPS 证书由可信 CA 签发,Nginx 负责 TLS 终止;
  • 服务器重启、Nginx reload、PM2 restart 后,站点仍可访问。

下面示例以 Ubuntu 22.04/24.04 或 Debian 12 为参考。若你的海外服务器使用其他发行版,需要先确认包管理器、服务管理方式和 Nginx 配置路径是否一致。

部署前先核对环境和前置条件

正式操作前,不建议直接复制命令上线。先确认以下条件是否满足:

检查项 要求
域名解析 example.com 已解析到服务器公网 IP
端口开放 安全组、防火墙允许 80443 入站
Node.js 版本 与 Next.js 项目要求一致,建议使用当前 LTS 版本
构建依赖 服务器可访问 npm registry 或已配置可用镜像
证书条件 公网域名可验证;内网域名或未解析域名不能直接申请公网信任证书

先查看系统和基础软件状态:

lsb_release -a
node -v
npm -v
nginx -v
ss -lntp

安装常用依赖:

sudo apt update
sudo apt install -y nginx git curl build-essential

如果服务器启用了 UFW,需要允许 Web 端口:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

Node.js 的安装方式可以使用系统包、NodeSource、nvm、fnm 等。生产环境要注意一点:PM2 开机自启时使用的用户必须能找到同一个 Node.js 路径。若使用 nvm 部署,后续 pm2 startup 和应用启动用户要保持一致,否则重启后可能出现“找不到 node/npm”的问题。

上传项目并完成生产构建

假设应用部署目录为 /var/www/next-ssr,建议使用普通部署用户操作,不要长期使用 root 跑 Node 应用。

sudo mkdir -p /var/www/next-ssr
sudo chown -R $USER:$USER /var/www/next-ssr
cd /var/www/next-ssr
git clone https://your-git-repo.example/next-ssr.git .

准备生产环境变量。常见文件名是 .env.production,但具体以你的项目读取方式为准:

nano .env.production

安装依赖并构建:

npm ci
npm run build

如果这里失败,不要继续配置 Nginx。先看构建报错,例如 Node.js 版本不匹配、缺少环境变量、依赖安装失败、服务端代码访问了浏览器对象等。SSR 站点必须保证服务端构建和运行都正常,Nginx 只能代理请求,不能修复应用构建问题。

确认 package.json 中存在生产启动脚本,例如:

{
  "scripts": {
    "build": "next build",
    "start": "next start"
  }
}

可以先手动启动一次验证:

npm run start -- -p 3000 -H 127.0.0.1

另开一个 SSH 窗口检查本机访问:

curl -I http://127.0.0.1:3000

看到 200301302404 都说明 Next.js 服务有响应;如果是连接失败,说明 Node 服务没有监听成功。验证后按 Ctrl + C 停止手动进程,交给 PM2 管理。

使用 PM2 守护 Next.js SSR 进程

安装 PM2:

sudo npm install -g pm2
pm2 -v

在项目目录创建 ecosystem.config.js,这样比直接敲一长串启动命令更容易维护:

module.exports = {
  apps: [
    {
      name: "next-ssr",
      cwd: "/var/www/next-ssr",
      script: "node_modules/next/dist/bin/next",
      args: "start -p 3000 -H 127.0.0.1",
      env: {
        NODE_ENV: "production"
      },
      instances: 1,
      exec_mode: "fork",
      max_memory_restart: "512M"
    }
  ]
};

启动应用:

cd /var/www/next-ssr
pm2 start ecosystem.config.js
pm2 status
pm2 logs next-ssr --lines 50

保存 PM2 进程列表:

pm2 save

配置开机自启:

pm2 startup systemd

执行后,PM2 会输出一条带 sudo 的命令,例如包含当前用户名和 home 路径。需要复制并执行它,然后再次保存:

pm2 save

如果你使用的是非 root 用户部署,重启后应检查对应的 systemd 服务,例如服务名可能是 pm2-用户名

systemctl status pm2-$USER

这里有一个容易误判的点:pm2 status 显示 online,只代表 Node 进程正在运行,不代表域名能访问。域名访问还依赖 Nginx反向代理、防火墙、DNS 和 HTTPS 配置。

如果项目使用 Next.js standalone 输出,启动方式会不同,通常是运行 .next/standalone/server.js,并通过环境变量指定端口和主机名:

module.exports = {
  apps: [
    {
      name: "next-ssr",
      cwd: "/var/www/next-ssr",
      script: ".next/standalone/server.js",
      env: {
        NODE_ENV: "production",
        PORT: "3000",
        HOSTNAME: "127.0.0.1"
      }
    }
  ]
};

选择哪种方式取决于你的 next.config.js 和构建产物,不要混用。

配置 Nginx 反向代理到本机 Node 服务

Next.js 不建议直接暴露在公网端口上。更稳妥的做法是:Node 只监听 127.0.0.1:3000,Nginx 对外提供 HTTP/HTTPS 服务。

先为 WebSocket/连接升级准备一个 Nginx 变量文件:

sudo nano /etc/nginx/conf.d/connection_upgrade.conf

写入:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

创建站点配置:

sudo nano /etc/nginx/sites-available/next-ssr

先配置 HTTP 反向代理,证书申请前不要急着写死 HTTPS:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    access_log /var/log/nginx/next-ssr.access.log;
    error_log /var/log/nginx/next-ssr.error.log;

    client_max_body_size 20m;

    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 $connection_upgrade;

        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

启用站点:

sudo ln -s /etc/nginx/sites-available/next-ssr /etc/nginx/sites-enabled/next-ssr
sudo nginx -t
sudo systemctl reload nginx

如果 nginx -t 报错,先不要 reload。常见原因包括配置文件分号遗漏、server_name 写错位置、connection_upgrade 变量未定义、重复监听同一域名等。

验证 Nginx 到 Next.js 的代理链路:

curl -I http://127.0.0.1:3000
curl -I -H "Host: example.com" http://127.0.0.1
curl -I http://example.com

如果本机 127.0.0.1:3000 正常,但域名访问 502,优先查看:

pm2 logs next-ssr --lines 100
sudo tail -n 100 /var/log/nginx/next-ssr.error.log

502 多半是 Nginx 连接不到上游 Node 服务,例如 PM2 进程未运行、端口不一致、Next.js 监听到 0.0.0.0 以外的错误地址、应用启动后立即崩溃等。

配置 HTTPS:证书签发方式要匹配实际环境

HTTPS 的配置不能只看 Nginx 示例,还要看证书能否被签发。公网用户访问的站点,应使用受信任 CA 证书,例如 Let’s Encrypt、商业证书或云平台证书。自签名证书只适合内部测试,不适合正式公网业务。

使用 Let’s Encrypt 时,通常有两种验证方式:

  • HTTP-01:域名已解析到当前服务器,且公网可访问 80 端口;
  • DNS-01:适合通配符证书、服务器 80 端口不可访问、域名暂未切流等场景,但需要操作 DNS 解析记录或接入 DNS API。

如果你的域名已经指向这台海外服务器,并且 80 端口可访问,可以使用 Certbot 的 Nginx 插件:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

执行过程中,Certbot 会检查域名、申请证书,并可自动修改 Nginx 配置。完成后建议重新检查配置:

sudo nginx -t
sudo systemctl reload nginx

证书自动续期通常由 systemd timer 或 cron 管理,可用以下命令验证续期流程:

sudo certbot renew --dry-run

如果证书签发失败,不要反复盲目重试。先确认:

  • 域名 A/AAAA 记录是否指向当前服务器;
  • 服务器安全组和系统防火墙是否允许 80 端口;
  • Nginx 的 server_name 是否与申请证书的域名一致;
  • 是否存在 CDN、WAF、反向代理导致验证请求没有到达源站;
  • 是否申请了通配符证书,通配符通常需要 DNS-01 验证。

一个常见的 HTTPS Nginx 配置大致如下,证书路径以实际签发结果为准:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    access_log /var/log/nginx/next-ssr.access.log;
    error_log /var/log/nginx/next-ssr.error.log;

    client_max_body_size 20m;

    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 https;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

HSTS 可以提升 HTTPS 强制访问效果,但不建议刚上线就直接开启长周期 HSTS。若证书、子域名或回源链路还未稳定,错误的 HSTS 配置会让浏览器在一段时间内强制访问 HTTPS,增加回滚难度。

上线后验证:不仅看首页,还要验证重启恢复

部署完成后,至少从三个层面检查。

先看应用进程:

pm2 status
pm2 logs next-ssr --lines 50
curl -I http://127.0.0.1:3000

再看 Nginx 和域名:

sudo systemctl status nginx
sudo nginx -t
curl -I http://example.com
curl -I https://example.com

然后从本地浏览器或第三方网络环境访问:

  • 首页是否正常返回;
  • SSR 页面刷新后是否正常;
  • 登录、接口请求、图片和静态资源是否正常;
  • HTTP 是否跳转到 HTTPS;
  • 浏览器证书是否可信,域名是否匹配;
  • Nginx error log 是否持续出现 502、499、504。

最后做一次受控重启验证。建议在低峰期操作,避免影响真实用户:

sudo reboot

服务器恢复后检查:

systemctl status nginx
systemctl status pm2-$USER
pm2 status
ss -lntp | grep -E ':80|:443|:3000'
curl -I https://example.com

如果重启后 Nginx 正常但 PM2 没有恢复,重点检查 pm2 startup 是否按正确用户执行、pm2 save 是否执行、Node.js 路径是否因 nvm/fnm 导致 systemd 找不到。若 PM2 正常但域名不可访问,再回到 Nginx 日志和防火墙层面排查。

回滚条件与保留项

上线前建议至少保留三类可回滚内容:上一版代码提交、上一份 Nginx 配置、当前可用的 PM2 启动配置。修改 Nginx 前可以先备份:

sudo cp /etc/nginx/sites-available/next-ssr /etc/nginx/sites-available/next-ssr.bak-$(date +%F-%H%M)

出现以下情况时,不建议继续追加修改,应先回滚到可用状态:

  • 新版本 npm run build 失败或 PM2 进程反复重启;
  • Nginx 出现持续 502/504,且无法在短时间内定位;
  • HTTPS 证书申请失败导致正式域名不可访问;
  • 重启服务器后 PM2 无法自动恢复;
  • 关键业务页面、登录、支付、接口请求异常。

代码回滚可以切回上一个已验证提交后重新构建并重启 PM2:

cd /var/www/next-ssr
git checkout <last-good-commit>
npm ci
npm run build
pm2 restart next-ssr
pm2 save

Nginx 配置回滚时,先恢复备份,再测试配置,最后 reload:

sudo cp /etc/nginx/sites-available/next-ssr.bak-YYYY-MM-DD-HHMM /etc/nginx/sites-available/next-ssr
sudo nginx -t
sudo systemctl reload nginx

回滚完成后不要只看浏览器缓存页面,应重新执行 curl -I https://example.com、查看 PM2 日志和 Nginx error log。只有 Node.js 进程、Nginx反向代理、HTTPS 证书和重启恢复都验证通过,Next.js SSR 站点在海外服务器上的部署才算进入可维护状态。

上一篇 日本名古屋云服务器和大阪云服务器面向关西用户,延迟与交付如何比较

LHIDC 产品中心

继续查看可购买的海外服务器产品

文章用于辅助选型,最终价格、库存与配置请以产品详情页和下单页面展示为准。

查看产品 查看方案