前言
在个人站长和技术爱好者的世界里,Halo 是一款备受推崇的现代化开源博客系统。而在家庭或小型办公环境中,群晖(Synology)NAS 凭借其强大的功能和易用性,成为了运行各种服务的理想平台。将两者结合,通过 Docker 来部署 Halo,无疑是一种高效且灵活的方案。
Halo 官方文档提供了标准的 Docker Compose
部署方式,在官方推荐的文档大致有三种方式部署,第一:使用内置的 PostgreSQL/MySQL 容器
;第二:使用 Halo 默认的 H2
数据库(个人不推荐);第三:使用外置的 PostgreSQL/MySQL 服务
。对于群晖玩家来说,我们完全可以利用群晖套件中心自带的 MariaDB 10
数据库作为"外部"数据库。这样做不仅能节约系统资源、便于统一管理和备份,还能让整个架构更加清晰。
此文将作为一份粗浅的实战(踩坑)指南,一步步在群晖上完成这个部署方案。
一、准备工作:创建独立的数据库
在开始之前,确保已经在群晖“套件中心”安装了 Container Manager
(旧版名为 Docker)、MariaDB 10
和 phpMyAdmin
。在安装 phpMyAdmin
的时候会自动同步安装从属套件 PHP 8.0
和 Web Station
。
核心原则:最小权限原则
永远不要让应用程序使用数据库默认的 root
账户。应该为每个应用创建独立的、只能访问自己数据库的账户。
操作步骤:
- 打开
MariaDB 10
套件,首次运行时,请务必为其设置一个root
账户的密码,并牢记。 - 打开
phpMyAdmin
套件,使用root
账户和你刚刚设置的密码登录。 - 点击顶部导航栏的 “用户账户” > “新增用户账户”。
-
在弹出的表单中,填写以下信息:
- 用户名:
halo
(或你喜欢的其他名字) - 主机名: 从下拉菜单中选择
任意主机 (%)
。 - 密码: 点击“生成”按钮创建一个强密码,并务必复制并保存好这个密码。
- 勾选:
创建与用户同名的数据库并授予所有权限
。这个选项会一步到位,自动创建名为halo
的数据库并完成授权,非常方便。
- 用户名:
-
点击右下角的“执行”按钮,数据库和用户就创建好了。
二、核心配置:构建 docker-compose.yaml
现在,我们可以开始编写 docker-compose.yaml
文件了。这个文件是部署halo服务的蓝图。
在群晖的 File Station
中,进入 docker
共享文件夹,在里面创建一个新文件夹,例如 Halo
。
三、部署与启动
- 打开群晖的
Container Manager
套件。 - 选择左侧的 “项目” -> “新增”。
- 项目名称:填写
halo
。 - 路径:点击 “设置路径” 选择刚才创建的
/docker/halo
文件夹。 - 来源:选择
创建 docker-compose.yml
。 - 在编辑框中输入如下内容。
version: "3"
services:
halo:
container_name: halo
# 目前官方提供了三个镜像源,根据需要自己选择
image: halohub/halo:2
restart: on-failure:3
networks:
halo_network:
ports:
# 这里根据你想访问的端口进行自定义
- "9980:8090"
volumes:
- ./:/root/.halo2
environment:
# JVM 参数,默认为 -Xmx256m -Xms256m,可以根据实际情况做调整,置空表示不添加 JVM 参数
- JVM_OPTS=-Xmx256m -Xms256m
command:
# 数据库配置区域
# 修改为群晖套件的 MariaDB 配置
- --spring.r2dbc.url=r2dbc:pool:mariadb://{你的群晖ip}:{你安装MariaDB时的端口}/{上一步在数据库中创建的数据库名,这里是halo}
- --spring.r2dbc.username={上一步在数据库中为halo创建的专属用户名}
- --spring.r2dbc.password={上一步在数据库中为halo创建的专属密码}
- --spring.sql.init.platform=mariadb
# Halo独有配置区域
# 外部访问地址,请根据实际需要修改
- --halo.external-url=https://example.com/
- --halo.security.frame-options.disabled=true
# Web框架相关配置区域
# 端口号 默认8090(这里一般不动。halo官方默认访问端口就是8090)
- --server.port=8090
networks:
halo_network:
- 点击“下一步”,然后点击“完成”,系统会自动根据我们写的配置文件去拉取并启动项目。
部署成功后稍等片刻,在浏览器中访问 http://你的群晖IP:9980
,就能看到 Halo 的初始化界面了。
四、深度解析:弄懂背后的网络原理
只知其然,不知其所以然,不是我的风格。下面我来作为初学者浅析一些部署过程中常见的疑惑。
配置文件里 networks
只写了自定义的网络名字,为什么它就是 bridge
桥接模式?
当你在 docker-compose.yaml
中定义一个网络而不指定 driver
时,Docker Compose 默认就会使用 bridge
驱动。官方文档省略了 driver: bridge
,是yaml文件的简洁化实现。
而创建这个自定义网络(halo_network
)的主要目的,是为了实现网络隔离。如果我们的 docker-compose
文件里还有其他服务(比如官方在配置文件中有两个services都使用同一个 networks
),它们就可以通过服务名 halo_network
直接互相通信,非常方便。
# ……
services:
halo:
# ……
networks:
halo_network:
# ……
halodb:
# ……
networks:
halo_network:
networks:
halo_network:
容器在隔离的网络里,如何连接到主机上的 MariaDB 服务?
这是最关键的一步。容器内部是一个隔离的环境,在容器里访问 localhost
或 127.0.0.1
,访问的是容器自己内部的网络,而不是外面的群晖主机。
要让容器“跨越”隔离,访问到主机,在相应的配置部分必须使用一个主机在局域网中的地址。比如这个案例中,需要让docker内部运行的halo访问它外部的数据库,就需要严格定义其具体的IP地址。
- 方案一(最常用):直接使用群晖的内网 IP 地址,如
192.168.1.254
。 - 方案二(更现代):使用 Docker 提供的特殊 DNS 名称
host.docker.internal
。它会自动解析为宿主机的 IP 地址,让配置更具可移植性。
结论:HALO_DATABASE_HOST
必须填写群晖的内网 IP 或 host.docker.internal
,绝对不能是 localhost
,因为在该容器内部网络并无数据库服务在运行。