DEV
从零部署 Next.js:Nginx 反代、HTTPS 与图片优化
2026-02-03
目标与环境
- 目标:把 Next.js 项目稳定部署到 Ubuntu 服务器,公网走 80/443,应用仅监听本机端口。
- 运行环境:Ubuntu 24.04 + Node.js + Nginx + systemd。
- 域名:
aboutme.lyz1010.site+www.aboutme.lyz1010.site(DNS 已解析到服务器公网 IP)。 - 内部端口:
6100(仅本机访问)。
最终架构
- 浏览器 →
https://aboutme.lyz1010.site - Nginx 监听 80/443
- Nginx 反向代理 →
127.0.0.1:6100 - Next.js 由 systemd 常驻运行
1) 基础检查与准备
# 系统信息
cat /etc/os-release
# 查看端口是否占用(确认 6100 可用)
ss -ltnp | rg ':6100\s' || true
备注:HTTPS 需要域名,不能只用 IP 申请证书。
2) 安装 Nginx + Certbot
sudo apt-get update
sudo apt-get install -y nginx certbot python3-certbot-nginx
3) 配置 Nginx 反代
站点配置:/etc/nginx/sites-available/aboutme.lyz1010.site
server {
listen 80;
listen [::]:80;
server_name aboutme.lyz1010.site www.aboutme.lyz1010.site;
location / {
proxy_pass http://127.0.0.1:6100;
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";
proxy_cache_bypass $http_upgrade;
}
}
启用站点并 reload:
sudo ln -s /etc/nginx/sites-available/aboutme.lyz1010.site /etc/nginx/sites-enabled/aboutme.lyz1010.site
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
4) 构建与 systemd 常驻
在项目目录:/home/ubuntu/code/website-lyz
npm ci
npm run build
创建 systemd 服务:/etc/systemd/system/website-lyz.service
[Unit]
Description=website-lyz Next.js app
After=network.target
[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/code/website-lyz
Environment=NODE_ENV=production
Environment=PORT=6100
ExecStart=/usr/bin/npm run start -- -p 6100 -H 127.0.0.1
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
启用并启动:
sudo systemctl daemon-reload
sudo systemctl enable --now website-lyz
systemctl is-active website-lyz
5) 申请 HTTPS 证书
sudo certbot --nginx \
-d aboutme.lyz1010.site \
-d www.aboutme.lyz1010.site \
-m you@example.com \
--agree-tos --no-eff-email
you@example.com换成你自己的邮箱即可(Let’s Encrypt 通知用)。
证书成功后 Nginx 配置会自动追加 SSL 段落。
6) 常见问题:npm 缓存权限报错
若出现 EACCES,可修复 ~/.npm 权限或临时改缓存目录:
# 方案 A:修复权限
sudo chown -R $(id -u):$(id -g) /home/ubuntu/.npm
# 方案 B:临时改缓存目录
npm ci --cache /tmp/.npm-cache
7) 代码更新流程
git pull --ff-only
npm run build
sudo systemctl restart website-lyz
systemctl is-active website-lyz
8) Nginx 压缩(gzip + brotli)
安装 brotli 模块:
sudo apt-get install -y libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
写入配置:/etc/nginx/conf.d/compression.conf
# Compression settings for text-based assets
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_proxied any;
gzip_vary on;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
application/rss+xml
application/atom+xml
image/svg+xml
application/font-woff
application/font-woff2
application/vnd.ms-fontobject
application/x-font-ttf
font/opentype;
brotli on;
brotli_comp_level 5;
brotli_min_length 1024;
brotli_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
application/rss+xml
application/atom+xml
image/svg+xml
application/font-woff
application/font-woff2
application/vnd.ms-fontobject
application/x-font-ttf
font/opentype;
检查并 reload:
sudo nginx -t
sudo systemctl reload nginx
9) 图片优化:JPG 压缩 + AVIF/WebP + picture
9.1 先做 JPG 优化(减少首屏体积)
# 生成优化版本(1600px 上限,质量 75)
mkdir -p public/about-optimized/2026-tibet public/about-optimized/2025-yunnan
for f in public/about/2026-tibet/*.jpg; do
base=$(basename "$f")
convert "$f" -strip -interlace Plane -sampling-factor 4:2:0 -quality 75 \
-resize "1600x1600>" "public/about-optimized/2026-tibet/$base"
done
for f in public/about/2025-yunnan/*.jpg; do
base=$(basename "$f")
convert "$f" -strip -interlace Plane -sampling-factor 4:2:0 -quality 75 \
-resize "1600x1600>" "public/about-optimized/2025-yunnan/$base"
done
9.2 生成 AVIF / WebP
for f in public/about-optimized/*/*.jpg; do
dir=$(dirname "$f")
base=$(basename "$f" .jpg)
convert "$f" -strip -quality 50 "$dir/$base.avif"
convert "$f" -strip -quality 75 -define webp:method=6 -define webp:auto-filter=true \
"$dir/$base.webp"
done
9.3 About 页改为 picture 自动选择
src/app/(site)/[lang]/about/page.tsx 内用 picture 替代 next/image:
<picture>
<source srcSet="/about-optimized/2026-tibet/01.avif" type="image/avif" />
<source srcSet="/about-optimized/2026-tibet/01.webp" type="image/webp" />
<img src="/about-optimized/2026-tibet/01.jpg" alt="游记照片" loading="lazy" />
</picture>
这样浏览器会优先加载 AVIF,其次 WebP,最后回退 JPG。
10) 验证与排错
# 检查本地端口
curl -I http://127.0.0.1:6100 | head -n 5
# 检查站点
curl -I https://aboutme.lyz1010.site | head -n 5
# 查看服务状态与日志
systemctl status website-lyz --no-pager
journalctl -u website-lyz -n 50 --no-pager
11) 当前关键配置位置
- Nginx 站点:
/etc/nginx/sites-available/aboutme.lyz1010.site - Nginx 压缩:
/etc/nginx/conf.d/compression.conf - systemd 服务:
/etc/systemd/system/website-lyz.service - 项目目录:
/home/ubuntu/code/website-lyz
小结
- 反代 + systemd 让 Next.js 线上部署更稳定。
- Let’s Encrypt 自动签发 HTTPS,配合 Nginx 即可完成全站 HTTPS。
- 图片先压缩 JPG,再补 AVIF/WebP,首访体积明显下降。
- 遇到 npm 权限问题,优先修复
.npm权限或临时改缓存目录。