Halo 2.x 博客系统实战部署指南:Docker 编排、宿主机数据库复用与 Caddy 自动化反代
Halo 是一款现代、强大且易用的开源建站与博客工具。在 2.x 版本中,Halo 全面重构为微内核架构,采用 Spring Boot 3 + 响应式 R2DBC + Java 21 虚拟线程,性能和扩展性相比旧版本有了质的飞跃。
本文基于生产实战环境,详细记录如何在拥有现有基础设施(宿主机已运行 PostgreSQL、Caddy Web 服务器)的 Linux VPS 上,通过 Docker 优雅部署 Halo 2 并实现资源极致复用。
一、架构设计与资源规划
在小型 VPS(例如 2~4GB 内存环境)上部署应用时,避免为每一个服务都额外启动一个独立的数据库容器是节约内存的关键策略。
本次部署的拓扑架构如下:
[ 外部请求 HTTPS ]
│
▼
[ Caddy Web Server ] :443 (自动申请与续签 Let's Encrypt 证书)
│
▼ (反向代理至 127.0.0.1:8090)
[ Halo 2.20 Docker 容器 ]
│
▼ (通过 host.docker.internal 连回宿主机)
[ 宿主机 PostgreSQL 18.x ] :5432
二、底层准备:宿主机 PostgreSQL 配置
Halo 2 官方推荐使用 PostgreSQL(支持 MySQL 8.0)。如果宿主机上已经安装了 PostgreSQL 实例,我们可以通过独立数据库与独立用户进行权限隔离。
1. 创建专属用户与数据库
登录 PostgreSQL 控制台:
# 1. 创建独立角色 halo
sudo -u postgres psql -c "CREATE USER halo WITH PASSWORD 'your_strong_password';"
# 2. 创建独立数据库 halo 并指定所有者
sudo -u postgres psql -c "CREATE DATABASE halo WITH OWNER halo ENCODING 'UTF8';"
# 3. 授权 public 架构权限
sudo -u postgres psql -d halo -c "GRANT ALL ON SCHEMA public TO halo;"
2. 配置白名单访问规则 (pg_hba.conf)
Docker 容器默认处于 Bridge 网段(通常在 172.16.0.0/12 范围内)。需要确保宿主机的 PostgreSQL 允许来自该网段的密码认证。
编辑 /etc/postgresql/18/main/pg_hba.conf,追加允许规则:
# 允许 Halo 容器与本地通信
host halo halo 172.16.0.0/12 scram-sha-256
host halo halo 127.0.0.1/32 scram-sha-256
执行平滑重载生效:
sudo -u postgres psql -c "SELECT pg_reload_conf();"
三、Halo Docker Compose 容器编排
在宿主机建立规划目录 /opt/halo:
mkdir -p /opt/halo/data
cd /opt/halo
编写 docker-compose.yaml:
version: '3'
services:
halo:
image: halohub/halo:2.20
container_name: halo
restart: always
extra_hosts:
# 将宿主机 IP 映射为 host.docker.internal
- "host.docker.internal:host-gateway"
ports:
# 仅绑定本地环回接口,避免未加密端口暴露公网
- "127.0.0.1:8090:8090"
volumes:
# 核心持久化目录(保存上传附件、主题、插件、快照)
- /opt/halo/data:/root/.halo2
environment:
# 限制 JVM 内存,适合 2G-4G 服务器,避免发生 OOM
- JVM_OPTS=-Xms256m -Xmx512m
command:
# R2DBC 连接宿主机 PostgreSQL
- --spring.r2dbc.url=r2dbc:pool:postgresql://host.docker.internal:5432/halo
- --spring.r2dbc.username=halo
- --spring.r2dbc.password=your_strong_password
- --spring.sql.init.platform=postgresql
- --halo.external-url=https://blog.inovix.cn/
启动服务
docker compose up -d
查看实时启动日志:
docker compose logs -f halo
当出现 Netty started on port 8090 (http) 与 Started Application in ... seconds 时,代表服务已正常就绪。
四、Caddy 反向代理与自动 HTTPS
Caddy 相比传统的 Nginx 具有极为简洁的配置语法,且默认内置全自动的 ACME 证书申请与续签机制。
在 /etc/caddy/sites/blog.inovix.cn.conf 中添加站点配置:
blog.inovix.cn:443 {
reverse_proxy localhost:8090
log {
output file /var/log/caddy/blog_inovix.log
}
}
测试配置并重启 Caddy:
caddy validate --config /etc/caddy/Caddyfile
systemctl restart caddy
只要域名的 A 记录已解析至该服务器公网 IP,Caddy 将在几秒内自动申请好 Let's Encrypt / ZeroSSL 证书并开启 HTTP/2 与 HTTP/3 支持。
五、持久化与数据备份策略
Halo 系统的核心数据由两部分组成:
- 数据库数据: 保存在 PostgreSQL 中,包含所有文章元数据、扩展配置、系统设置、菜单等。
- 备份方式:
bash sudo -u postgres pg_dump -d halo > /opt/halo/halo_backup_$(date +%F).sql - 上传附件与插件:
保存在挂载的宿主机物理路径
/opt/halo/data中。 - 备份方式:直接打包该目录:
bash tar -czvf /opt/halo/halo_data_backup_$(date +%F).tar.gz /opt/halo/data
六、进阶:利用个人令牌(PAT)实现自动化
Halo 2 拥有完善的 OpenAPI 体系。在后台 【个人中心】->【个人访问令牌(Personal Access Token)】 中创建令牌后,我们可以编写轻量自动化脚本或接入 AI Agent 工具,实现: - 本地 Markdown 文档一键同步发布 - 定时抓取与文章更新 - 分类标签的自动创建与维护
至此,一个高效、安全、低资源消耗且具备全自动 HTTPS 的现代独立博客系统正式搭建完成!