VanBlog 是一个用 Node.js 写的轻量个人博客系统,数据存在 MongoDB,前台服务端渲染。它的定位很明确:一条 docker-compose 起站,自带后台、图床、评论、访问统计、暗色模式和自动 HTTPS,不折腾 LNMP。
核心特点与优势:
部署极简:官方 compose 只有两个服务(VanBlog + MongoDB),内置 Caddy 负责证书,域名解析好就能自动上 HTTPS。
自带图床:上传的图片直接存在容器挂载目录里,不依赖第三方对象存储,备份目录就带走了。
后台完整:文章、分类、标签、自定义页面、导航、评论、统计、SEO 设置都在后台,手机浏览器也能写。
导入导出友好:文章可以按 Markdown 批量导出 / 导入,换机器或迁移时不至于被困住。
阅读体验好:默认主题适配移动端,自带暗色模式、目录、代码高亮,开箱就是成品的博客样子。
资源占用可控:一台 1 核 1G 的轻量服务器能跑,配比静态站高,但比 WordPress + 插件轻。
需要提前知道的:
data/ 目录里,备份是硬要求,删容器不等于删数据(但删目录等于删站)。| 维度 | VanBlog | Hugo / Hexo |
|---|---|---|
| 形态 | 动态,Node + MongoDB | 静态,构建出 HTML |
| 写作 | 浏览器后台 | 本地 Markdown + Git |
| 部署 | 服务器 + Docker | 任意静态托管 |
| HTTPS | 内置 Caddy 自动签发 | 自己配 certbot |
| 运维 | 备份数据库与图片、升级镜像 | 几乎为零 |
| 适合 | 想要后台、图床、评论的个人站 | 零成本、纯写作 |
VanBlog 的部署本质是 Docker Compose 起两个容器(VanBlog + MongoDB),域名解析到服务器,Caddy 自动签证书。官网给了两个入口:
curl 命令生成 compose 并启动,适合先跑通再说;下面先讲脚本,再讲手动配置,最后处理「已有 Nginx」的情况。
在服务器上执行(官网提供的原始命令):
bashcurl -L https://vanblog.mereith.com/vanblog.sh -o vanblog.sh && chmod +x vanblog.sh && ./vanblog.sh
脚本交互过程中会问两项:
执行前建议先看一眼脚本内容,确认没有多余动作:
bashless vanblog.sh
按官网脚本的实际逻辑:
/var/vanblog,自动 mkdir -p 创建;/var/vanblog/docker-compose-template.yaml,再生成可编辑的 /var/vanblog/docker-compose.yaml;mereith/van-blog:latest,否则用 registry.cn-beijing.aliyuncs.com/mereith/van-blog:latest;sed 写进 compose;docker-compose down -v,再 docker-compose up -d 启动容器。后续更新再执行一次 ./vanblog.sh 即可(内部会 pull 新镜像再重建)。
| 点 | 说明 |
|---|---|
| 目录固定 | 数据、日志、证书都在 /var/vanblog,备份和迁移要来这里找,不是当前目录 |
| 域名仍要自己配 | 脚本不处理 DNS;必须先解析 A 记录,否则 Caddy 签不到证书 |
| 证书依赖 80/443 | 端口被 Nginx 等占用时,自动 HTTPS 会失败,脚本不会替你解决冲突 |
用的是 docker-compose | 旧版 v1 命令。新系统只装了 Compose v2 插件(docker compose)时可能提示命令不存在,需要额外装兼容包,或直接改用下面的手动 compose |
down -v | 脚本每次会先移除容器;compose 模板用的是宿主机目录挂载,数据一般不受影响,但升级前仍应先备份 /var/vanblog |
版本是 latest | 脚本生成的 compose 不锁版本,长期维护建议改成具体版本号 |
需要写 /var | 用 sudo 执行,生成的文件属主可能是 root,后续编辑注意权限 |
访问 https://域名/admin 完成初始化;确认站点正常后,建议把 /var/vanblog/docker-compose.yaml 里的 latest 固定成当前版本,并把备份脚本指向 /var/vanblog。
想要更可控的结构(自定义目录、前置 Nginx、固定版本),继续看下一节。
bashcurl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable --now docker
docker compose version
Caddy 要靠域名申请证书,解析必须先生效,否则第一次启动会卡在证书签发。
bashdig +short blog.example.com # 必须返回服务器公网 IP
| 服务商 | 入口 | 记录 | 注意点 |
|---|---|---|---|
| Cloudflare | DNS → Records | A blog → 服务器IP | 用 Cloudflare 代理时 SSL/TLS 设 Full (strict);首次签发证书建议先灰云,签发成功再按需开橙云 |
| 阿里云 / 腾讯云 | 云解析 DNS → 添加记录 | A blog → 服务器IP,TTL 600 | 国内服务器先备案 |
| DNSPod | 域名解析 → 添加记录 | A blog → 服务器IP,TTL 600 | 等 TTL 过期再启动容器 |
bashmkdir -p ~/vanblog && cd ~/vanblog
docker-compose.yaml(基于官方模板,只改了邮箱和路径写法):
yamlservices:
vanblog:
image: mereith/van-blog:latest
restart: always
environment:
TZ: Asia/Shanghai
# 邮箱,用于 Caddy 自动申请 HTTPS 证书
EMAIL: someone@example.com
volumes:
# 图床文件
- ./data/static:/app/static
# 日志
- ./log:/var/log
# Caddy 配置
- ./caddy/config:/root/.config/caddy
# Caddy 证书
- ./caddy/data:/root/.local/share/caddy
ports:
- 80:80
- 443:443
mongo:
# 部分机器不支持 AVX,MongoDB 高版本会启动失败,官方默认用 4.4.16
image: mongo:4.4.16
restart: always
environment:
TZ: Asia/Shanghai
volumes:
- ./data/mongo:/data/db
要点:
EMAIL 必须换成真实邮箱,证书到期通知和 ACME 注册都用它。registry.cn-beijing.aliyuncs.com/mereith/van-blog:latest。latest 固定成具体版本号,升级时手动改,避免重启就升级。data/、caddy/、log/ 都在当前目录下,这三个目录就是整站的数据,别放在临时目录。bashdocker compose up -d docker compose logs -f vanblog
日志里能看到 Caddy 为域名申请证书的过程。首次启动通常十几秒到一分钟,取决于 DNS 和网络。
浏览器访问 https://blog.example.com:
http://blog.example.com 或 http://IP,确认站点本身能开,再排查证书(见排错表)。首次访问会进入初始化向导(后台地址 https://blog.example.com/admin):
后台里还可以继续配:站点图标、导航、分类、标签、自定义页面、评论、统计、SEO、自定义 CSS / HTML。官方演示站的 demo / demo 只用于体验,不要在生产环境沿用。
https://IP 一定报错。测试期用 http://IP。备份(建议每周 + 升级前必做):
bashcd ~/vanblog
docker compose stop vanblog
tar -czf ~/vanblog-backup-$(date +%F).tar.gz data/ caddy/ docker-compose.yaml
docker compose start vanblog
data/mongo:全部文章、设置、账号;data/static:图床里的图片;caddy/:证书与 Caddy 配置;用一键脚本部署时,把上面的 ~/vanblog 换成 /var/vanblog;脚本生成的 compose 也在那里。
升级:
bashcd ~/vanblog
docker compose pull
docker compose up -d
docker compose logs -f vanblog
升级前先备份;升级后如果打不开,把镜像 tag 改回旧版本再 up -d 即可回滚(所以生产建议固定版本号)。
dig 解析到正确 IP,且没开 CDN 代理(首次启动)EMAIL 是真实邮箱data/、caddy/、log/ 在持久化目录里,重启容器数据还在https://域名 证书有效,http:// 能自动跳转机器上已经跑着 Nginx 或其它占用 80 / 443 的服务时,两条路:
推荐:把 VanBlog 放到单独服务器 / 单独 IP,让它独占 80 / 443,省心且证书自动。
共存方案:让宿主 Nginx 终止 TLS,VanBlog 只提供 http 端口,证书由宿主管。
yaml ports:
- 127.0.0.1:8080:80
启动后确认 curl -I http://127.0.0.1:8080 返回 200 或 302。
宿主 Nginx 反代(/etc/nginx/sites-available/vanblog.conf):
nginxserver { listen 80; server_name blog.example.com; client_max_body_size 64m; location / { proxy_pass http://127.0.0.1:8080; 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_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
blog.example.com 配 HTTPS。这条路的代价:VanBlog 内置的自动 HTTPS 用不上,证书续期靠宿主;升级时两层配置都要确认没冲突。能用独立机器就别选它。
| 现象 | 原因 | 处理 |
|---|---|---|
一键脚本报 docker-compose: command not found | 系统只有 Compose v2 插件,没有旧版 docker-compose | 装兼容包,或按「有服务器、域名」一节手写 compose 用 docker compose |
启动报 port is already allocated | 80 / 443 被 Nginx 等占用 | 停掉宿主服务,或改端口做前置反代 |
| 证书签发失败 | DNS 未生效、80 被占、Cloudflare 橙云拦截 | 先灰云、确认 80 可达、等解析生效再重启 |
https://IP 打不开 | Caddy 只给域名签证书 | 用域名访问,测试期用 http://IP |
| 访问 http 被强制跳 https 且证书错 | 开启了自动跳转但证书未就绪 | 后台关闭「HTTPS 自动重定向」,或先把证书跑通 |
| mongo 容器反复重启 | CPU 不支持 AVX | 使用 mongo:4.4.16(官方默认值) |
| 图片 404 | data/static 没挂载或权限不对 | 检查 volumes 路径与容器日志 |
| 后台打开空白 / 502 | 容器未就绪或内存不足 | docker compose logs vanblog,加 swap 或升内存 |
| 时间显示不对 | 时区不是东八区 | 两个服务都设 TZ: Asia/Shanghai |
| 磁盘满 | 图片和 MongoDB 增长 | 清理日志、压缩图片,扩容磁盘 |
后台 → 站点设置:站点名称、描述、Logo / favicon、备案号、页脚信息。描述会进首页 meta,是 SEO 里最直接的一项。
VanBlog 的图片存在 data/static,后台编辑器里直接上传或粘贴图片即可:
data/static,只备份数据库会丢图;后台可以开启内置评论与访问统计:
/sitemap.xml 与 /rss.xml 是否可访问(版本不同路径可能不同),有的话提交到搜索平台;后台支持 Markdown 批量导入 / 导出,VanBlog 导出的文章头是这样的:
yaml---
title: 个人博客-hugo
category: 项目分享
tags: HuGo
updatedAt: 2026-05-31T03:52:10.452Z
createdAt: 2025-07-17T15:46:57.722Z
---
# 简介
……
<!-- more -->
三个注意点:
category 是单个值,不要写数组;tags 是逗号分隔的字符串,不是 YAML 数组;Z),摘要分隔符是 <!-- more -->,导入前不要删。从别的系统迁进来时,把 front matter 对齐成上面的格式,能省掉大量手工修正。
内容在数据库,任何浏览器登录后台即可写作。
浏览器打开 https://域名/admin → 新建文章 → 写 → 发布 → MongoDB 保存 + 图片进 data/static → 前台立即可见
本文作者:Weee
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!