最近接手了一个用 Next.js 开发的官网项目。由于官网更新频率不高,我整理了一套简单可控的部署方案:不依赖 Docker,只需通过 SFTP 上传文件到服务器,配合 Nginx 和 PM2 即可完成部署。
如果想进一步优化,可以考虑添加 GitHub Action 实现自动化部署。本文主要介绍基础部署步骤,同时也会分享前期尝试过的其他方案(Vercel、Docker)供参考。
一、Vercel 部署:简单但国内访问受限
Vercel 是 Next.js 官方推荐的部署平台,支持一键部署,绑定 GitHub 后可以直接上线,还提供免费域名,非常适合初创团队和个人项目。
部署步骤:
-
创建 Vercel 账号
- 访问 Vercel 官网
- 使用 GitHub、GitLab 或 Bitbucket 账号登录
-
导入项目
- 点击"New Project"
- 选择 Git 仓库提供商
- 授权 Vercel 访问仓库
- 选择 Next.js 项目
-
配置部署
- Vercel 会自动识别 Next.js 项目
- 默认构建命令:next build
- 默认输出目录:.next
- 可按需添加环境变量
-
点击"Deploy"完成部署
- Vercel 自动构建并部署应用
- 完成后提供预览 URL
-
配置自定义域名(可选)
- 在项目设置中添加域名
- 按指引设置 DNS
加自定义域名时,它提示:
❌ Invalid Configuration
原因是需要在域名服务商那边添加 CNAME 记录。
这时候忽然想起来,国内访问 Vercel 速度慢,甚至可能无法访问。考虑到这是面向国内用户的官网,我决定转向服务器部署方案,这样可以更好地控制访问速度。
二、Docker 部署:尝试与放弃
最初我也考虑使用 Docker 部署,期望能实现环境统一、一次构建处处运行。但实践中遇到了一些问题:
- 网上大多数 docker方案都是在线上 build,但我这边居然 node 镜像都拉不下来,即使更换镜像源也无法解决
- 换成本地build的方案,但使用 AI 生成的 Dockerfile 运行时出现包版本冲突,加上对AI生成的配置文件缺乏信任,还是放弃了
最终选择了更简单的方案:直接使用 Node 环境 + Nginx + PM2,部署过程更加快捷,维护也更简单。
三、最终部署方案
1. 本地构建测试
部署前,强烈建议先在本地打包并运行一遍,这样可以提前发现依赖缺失、打包失败等问题,避免上传服务器后再来回修 bug、重新上传的麻烦。
bash
pnpm install # 安装依赖
pnpm build # 构建项目
pnpm start # 启动生产环境
如果本地没问题,说明项目准备好了,可以部署上线。
2. 使用 Termius 连接服务器并上传项目
Termius 是一款跨平台的 SSH/SFTP 客户端工具,可以方便地管理服务器连接和文件传输。都可以通过 Termius 完成:
(1) 上传代码(SFTP)
- 在 Termius 中连接服务器,打开 SFTP 面板
- 将本地项目文件夹上传到服务器,如 /var/www/your-project
也可以通过 Git 拉取代码(适合多人协作):
bash
git clone https://github.com/yourname/yourproject.git
cd yourproject
(2) 登录服务器(SSH)并安装环境
- 在 Termius 中点击打开终端
- 确认 Node 和 pnpm 已安装:
bash
node -v
pnpm -v
如需安装,可使用 nvm:
bash
# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 使 nvm 立即生效(将 nvm 的配置加载到当前终端中)
source ~/.bashrc
# 安装 Node.js
nvm install --lts
# 安装 pnpm
npm install -g pnpm
进入项目目录并安装依赖:
bash
cd /var/www/your-project
pnpm install
pnpm build
3. 配置 PM2
PM2 是一个进程管理工具,可以:
- 保持 Node 应用持续运行
- 支持重启、日志查看、开机自启
- 统一管理多个项目
安装与使用:
bash
npm install -g pm2
启动生产服务:
sql
pm2 start "pnpm start" --name "your-app-name"
• --name 用于给这个进程命名,便于后续查看、管理
• pnpm start 会启动生产环境(必须先 pnpm build)
常用命令:
bash
pm2 list # 查看当前所有运行中的服务
pm2 stop <id> # 停止服务,替换 <id> 或 <name>
pm2 logs # 查看日志
pm2 save # 保存当前状态(用于下次重启后自动恢复)
pm2 startup # 设置开机自启(会输出一条命令,复制粘贴执行即可)
4. 配置 SSL 证书
在配置 Nginx 前,需要先准备好 HTTPS 证书:
云厂商申请证书(推荐)
- 在服务器提供商(如阿里云/腾讯云)申请免费的 SSL 证书(PEM 格式)
- 下载并上传证书文件到服务器:
bash
/etc/nginx/ssl/yourdomain.com.pem # 公钥(证书文件)
/etc/nginx/ssl/yourdomain.com.key # 私钥
5. 配置 Nginx 反向代理
Nginx 的作用:
-
浏览器请求的是域名(例如 yourdomain.com) ,但 Next.js 实际运行在本地 localhost:3000,Nginx 充当「反向代理」,将请求转发给 PM2 中运行的服务
-
处理 HTTPS、静态资源、证书等
配置示例:
nginx
# 自动将 HTTP 重定向到 HTTPS
server {
listen 80;
server_name yourdomain.com; # 你的域名
return 301 https://$host$request_uri;
}
# HTTPS 服务
server {
listen 443 ssl;
server_name yourdomain.com; # 你的域名
ssl_certificate /etc/nginx/ssl/yourdomain.com.pem; # 证书
ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key; # 私钥
location / {
proxy_pass http://localhost:3000; # 对应 PM2 中服务的端口
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;
}
# Next.js 静态资源
location /_next/static/ {
alias /var/www/your-project/.next/static/; # 确保路径正确,包含点号,并以斜杠结尾
expires 1y;
access_log off;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# 公共资源
location /public/ {
alias /var/www/your-project/public/; # 使用 alias 并加斜杠
try_files $uri $uri/ =404;
}
# 404 页面
error_page 404 /404.html;
location = /404.html {
internal;
root /var/www/your-project/public;
}
}
启用配置:
bash
# 建立软链接
sudo ln -s /etc/nginx/sites-available/your-app.conf /etc/nginx/sites-enabled/
# 检查语法是否正确
sudo nginx -t
# 应用配置
sudo systemctl reload nginx
完成配置后,通过浏览器访问 yourdomain.com 即可访问应用。如有配置错误,Nginx 会给出提示。
四、部署总结
完整的部署流程:项目构建 → 上传代码 → 启动服务 → 配置 HTTPS → 设置 Nginx。
从此,服务断了会自动重启,系统重启后也能自动上线,浏览器通过域名访问 HTTPS。