VanBlog 源码搭建与前后端分离部署指南
2026-07-21
安装搭建
00
请注意,本文编写于 56 天前,最后修改于 56 天前,其中某些信息可能已经过时。

目录

一、项目结构(源码)
二、环境准备
三、从源码构建
1. 后端 Server
2. 管理后台 Admin
3. 前台 Website
四、推荐的拆分部署方式
拓扑示意
公网 Nginx(前台)示意
内网 Nginx(后台)示意
五、systemd 守护(示例)
六、初始化与登录
七、常见问题
1. /api/admin/meta 返回 401
2. 登录提示密码错误
3. 前台发文后看不到更新
4. 忘记管理员密码
八、参考链接

VanBlog 是一款开源的个人博客系统(GPL-3.0),仓库地址:

https://github.com/mereithhh/van-blog

官方提供 Docker / 一键脚本部署。本文记录的是 从 GitHub 源码本地构建,并拆分前后端部署 的完整流程,适合需要前后端分离、内网托管管理后台的场景。

本站当前架构大致如下:

角色说明
前台 WebsiteNext.js 静态站,对外提供访客页面
后端 ServerNestJS API + MongoDB + Waline 评论
后台 AdminUmi 管理面板,建议仅内网访问
隧道内网后端通过 SSH 反向隧道把 API 暴露给公网前台

一、项目结构(源码)

克隆仓库后,核心在 packages/

text
vanblog/ ├── packages/ │ ├── server/ # NestJS 后端(默认 :3000) │ ├── website/ # Next.js 前台(默认 :3001) │ ├── admin/ # 管理后台(构建为静态资源) │ ├── waline/ # 评论服务(由 server 拉起) │ └── cli/ ├── docs/ └── package.json # pnpm monorepo

运行关系可以简化为:

text
浏览器 ──► Website(:3001) ── /api ──► Server(:3000) ──► MongoDB 浏览器 ──► Admin(静态) ── /api ──► Server(:3000) Server ──► Waline(:8360)

二、环境准备

建议环境:

  • Node.js 18 LTS
  • pnpm(仓库自带 pnpm-lock.yaml
  • MongoDB 4.4+ / 5.x / 6.x
  • Nginx(反代静态与 API)
  • (可选)autossh / systemd,用于隧道与进程守护
bash
# 示例:启用 pnpm corepack enable corepack prepare pnpm@8 --activate git clone https://github.com/mereithhh/van-blog.git cd van-blog pnpm install

构建时若遇到 OpenSSL / 内存问题,可设置:

export NODE_OPTIONS='--max_old_space_size=4096 --openssl-legacy-provider'


三、从源码构建

1. 后端 Server

bash
pnpm --filter server build # 产物:packages/server/dist

生产启动示例环境变量:

bash
export NODE_ENV=production export VAN_BLOG_DATABASE_URL='mongodb://127.0.0.1:27017/vanBlog?authSource=admin' export VAN_BLOG_STATIC_PATH=/opt/vanblog/data/static export VAN_BLOG_LOG=/opt/vanblog/log # 前后端分离、本机不跑 website 时: export VANBLOG_DISABLE_WEBSITE=true node packages/server/dist/src/main.js

Server 默认监听 3000,并会按配置拉起 Waline(默认 8360)。

2. 管理后台 Admin

Admin 以子路径 /admin/ 部署时,需要生产构建:

bash
export EEE=production pnpm build:admin # 产物:packages/admin/dist # base / publicPath 均为 /admin/

用 Nginx 托管 dist,并把 /api/static 反代到 Server。

3. 前台 Website

bash
pnpm --filter website build # 使用 standalone 产物更利于部署

前台需要能访问到后端 API,例如:

bash
export VAN_BLOG_SERVER_URL=http://127.0.0.1:3000 export PORT=3001 node packages/website/server.js # standalone 路径以实际产物为准

四、推荐的拆分部署方式

拓扑示意

text
公网机器 A(前台) 内网机器 B(后端 + 后台) ┌─────────────────────┐ ┌──────────────────────────┐ │ Nginx :80 │ │ Nginx :80 → Admin 静态 │ │ Website :3001 │◄─SSH隧道─│ Server :3000 │ │ 反代 /api → :3000 │ │ MongoDB │ └─────────────────────┘ │ Waline :8360 │ └──────────────────────────┘

要点:

  1. 前台放公网:只暴露 Website + 必要的 /api/static
  2. 后台放内网:Admin 不要映射到公网,降低爆破风险。
  3. SSH 反向隧道:由内网机器主动连公网,把本机 3000/8360 映射到公网机的 127.0.0.1:3000/8360,供前台 Nginx / Website 访问。
  4. 隧道建议做成 systemd 服务,并可用 timer 在每天凌晨做一次重连保活。

公网 Nginx(前台)示意

nginx
server { listen 80; server_name your.domain; location / { proxy_pass http://127.0.0.1:3001; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /api/ { proxy_pass http://127.0.0.1:3000/api/; client_max_body_size 50m; } location /static/ { proxy_pass http://127.0.0.1:3000/static/; } # 不建议对公网开放 /admin }

内网 Nginx(后台)示意

nginx
server { listen 80; root /var/www; location = / { return 302 /admin/; } location /admin/ { try_files $uri $uri/ /admin/index.html; } location /api/ { proxy_pass http://127.0.0.1:3000/api/; client_max_body_size 50m; } location /static/ { proxy_pass http://127.0.0.1:3000/static/; } }

packages/admin/dist 软链到 /var/www/admin 即可。


五、systemd 守护(示例)

MongoDB / Server / Website / 隧道 都可以写成 service。Server 示例:

ini
[Unit] Description=VanBlog NestJS API Server After=network.target [Service] Type=simple WorkingDirectory=/opt/vanblog/packages/server Environment=NODE_ENV=production Environment=VANBLOG_DISABLE_WEBSITE=true Environment=VAN_BLOG_DATABASE_URL=mongodb://127.0.0.1:27017/vanBlog?authSource=admin Environment=VAN_BLOG_STATIC_PATH=/opt/vanblog/data/static Environment=VAN_BLOG_LOG=/opt/vanblog/log ExecStart=/usr/local/bin/node dist/src/main.js Restart=always [Install] WantedBy=multi-user.target

隧道(示意,按实际用户与端口调整):

bash
autossh -M 0 -N \ -o ServerAliveInterval=30 -o ServerAliveCountMax=3 \ -R 3000:127.0.0.1:3000 \ -R 8360:127.0.0.1:8360 \ user@公网机器

六、初始化与登录

  1. 浏览器访问内网 Admin:http://<内网IP>/admin/
  2. 首次未初始化时,会进入初始化向导(创建管理员、站点信息)
  3. 初始化完成后,用管理员账号登录后台发文、改站点设置

站点「网站 URL」请填写完整协议,例如:https://www.example.com,否则 RSS、部分跳转可能异常。

图床本地模式下,图片一般落在 VAN_BLOG_STATIC_PATH,通过 /static/img/... 访问;前后端分离时请保证公网也能反代到 /static


七、常见问题

1. /api/admin/meta 返回 401

站点已初始化后,该接口需要登录。未登录时返回 401 是正常现象,后台会跳到登录页。带上有效 token 请求头后应返回 200。

2. 登录提示密码错误

VanBlog 密码不是明文传输:

  1. 前端先用 encryptPwd(username, password) 做浏览器侧哈希
  2. 后端再用盐 encryptPassword(username, hash, salt) 校验

因此用接口调试时,不能直接把明文密码塞进 password 字段。

3. 前台发文后看不到更新

拆分部署且 VANBLOG_DISABLE_WEBSITE=true 时,Server 不会自动触发本机 ISR。需要:

  • 给 Website 配置可达的 API,并依赖 ISR / revalidate 时间;或
  • 手动请求前台:/api/revalidate?path=/(以及文章、分类等路径)

4. 忘记管理员密码

Server 启动日志会打印恢复密钥;也可写入日志目录下的 restore.key。在后台「忘记密码」页用该密钥重置。


八、参考链接


以上即为本站采用的 VanBlog 源码搭建与拆分部署流程,后续文章会继续补充运维与使用笔记。

ai协作,人工编辑

本文作者:张老板

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!