问题描述

在使用 Docker Compose 部署 Halo 博客后,虽然已经在 docker-compose.yml 中配置了正确的 halo.external-url 参数,但是在友链页面仍然显示:

本站友链信息:
名称:charoneo's blog
地址:http://localhost:8090  ← 错误的地址
图标:https://blog.mhmh.cc/upload/wxavatar.JPEG
描述:欢迎互换友链,有问题请及时联系~
订阅:https://blog.mhmh.cc/rss.xml

同时,网站的 HTML 元数据中也包含错误的地址:

<meta name="site" content="http://localhost:8090">
<meta property="og:url" content="http://localhost:8090">

问题原因

Halo 的配置优先级为:数据库配置 > 启动参数

虽然 docker-compose.yml 中的 --halo.external-url 参数已经正确配置,但是:

  1. 首次安装时,如果使用了默认的 http://localhost:8090,这个配置会被写入数据库

  2. 修改启动参数后,Halo 仍然会优先读取数据库中已存在的旧配置

  3. 数据库中的配置不会因为修改启动参数而自动更新

因此,即使容器启动参数正确,数据库中存储的旧配置仍会导致网站显示错误的地址。

解决方案

方法一:修改数据库配置(推荐)

这是最直接有效的解决方法。

1. 连接到 MySQL 数据库

# 查看容器名称
docker ps | grep mysql

# 连接数据库(替换容器名)
docker exec -it <MySQL容器名> mysql -u<数据库用户> -p<数据库密码> <数据库名>

2. 执行 SQL 更新

这里因为是原数据是BLOB内容,所以要用CAST转换

USE halo;

-- 查看有多少条记录包含 localhost:8090
SELECT COUNT(*) FROM extensions WHERE CAST(data AS CHAR) LIKE '%localhost:8090%';

-- 列出包含 localhost:8090 的记录名称
SELECT name FROM extensions WHERE CAST(data AS CHAR) LIKE '%localhost:8090%';

-- 全局替换所有 localhost:8090 为实际域名
UPDATE extensions 
SET data = REPLACE(CAST(data AS CHAR(50000)), 'http://localhost:8090', 'https://blog.mhmh.cc')
WHERE CAST(data AS CHAR) LIKE '%localhost:8090%';

-- 确认修改(应该返回 0 表示已全部替换)
SELECT COUNT(*) FROM extensions WHERE CAST(data AS CHAR) LIKE '%localhost:8090%';

EXIT;

3. 重启 Halo 容器

cd /opt/1panel/apps/halo/halo
docker compose restart

4. 清除浏览器缓存并验证

  • Ctrl + Shift + Delete 清除浏览器缓存

  • 或使用无痕模式访问

  • 或按 Ctrl + F5 强制刷新

  • 访问友链页面验证地址是否正确

方法二:通过 Halo 后台修改

如果不想直接操作数据库,可以尝试通过后台修改:

  1. 登录 Halo 后台:https://你的域名/console

  2. 进入 设置基本系统

  3. 查找 "站点地址" 或 "外部访问地址" 配置项

  4. 修改为正确的域名

  5. 保存设置并重启

注意:某些版本的 Halo 后台可能没有直接修改此配置的选项,此时需要使用方法一。

方法三:检查主题配置

如果是主题(如 Dream2 Plus)中配置了站点地址:

  1. 进入 外观主题主题设置

  2. 查找所有包含 URL 的配置项(特别是"友链页面"相关配置)

  3. 将所有 localhost:8090 改为实际域名

  4. 保存设置

注意:某些版本的主题可能没有直接修改此配置的选项,此时需要使用方法一。

正确的初始配置方法

为了避免此问题,在首次部署 Halo 时就应该正确配置:

1. 编辑 docker-compose.yml

services:
  halo:
    image: halohub/halo-pro:2.21.10
    command:
      - --spring.r2dbc.url=r2dbc:pool:mysql://halodb:3306/halo
      - --spring.r2dbc.username=root
      - --spring.r2dbc.password=your_password
      - --spring.sql.init.platform=mysql
      - --halo.external-url=https://blog.yourdomain.com/  # 注意末尾的斜杠
    # ... 其他配置

重要提示

  • external-url 应该填写实际的域名,而不是 localhost

  • URL 末尾建议加上 斜杠 /(根据官方文档)

  • 使用 HTTPS 时填写 https://,HTTP 则填写 http://

2. 启动容器

docker compose up -d

3. 配置反向代理和域名解析

先配置好反向代理和域名解析,再进行 Halo 的初始化,这样可以避免后续修改的麻烦。

验证配置是否生效

1. 检查容器启动参数

docker inspect <Halo容器名> | grep external-url

应该输出:

"--halo.external-url=https://blog.yourdomain.com/"

2. 检查网站 HTML

访问网站,查看页面源代码:

<meta name="site" content="https://blog.yourdomain.com">
<meta property="og:url" content="https://blog.yourdomain.com">

3. 检查友链页面

访问 /links 页面,查看本站友链信息中的地址是否正确。

4. 检查 RSS 和 Sitemap

  • RSS: /rss.xml

  • Sitemap: /sitemap.xml

确认其中的链接使用的是正确的域名。

常见误区

❌ 误区 1:以为修改 docker-compose.yml 后会自动更新

错误认知:修改了 docker-compose.yml 中的 external-url 并重启容器,配置就会生效。

实际情况:数据库中的旧配置优先级更高,需要手动更新数据库。

❌ 误区 2:以为 external-url 会影响访问

错误认知external-url 类似于网络监听地址,会限制访问权限。

实际情况external-url 仅用于生成链接(如 RSS、Sitemap、邮件通知等),不影响访问逻辑。

❌ 误区 3:以为只改后台设置就够了

错误认知:在 Halo 后台修改了相关设置,就能解决问题。

实际情况:某些版本的 Halo 后台可能没有提供修改 external-url 的界面,需要直接修改数据库。

相关参考

总结

Halo 的 external-url 配置问题本质上是数据库持久化配置优先级高于启动参数导致的。解决方法很简单:

  1. 直接修改数据库:用 SQL 替换所有 localhost:8090 为实际域名

  2. 首次部署时就配置正确:避免后续修改的麻烦

  3. 记住末尾加斜杠https://blog.yourdomain.com/

希望这篇文章能帮助遇到同样问题的 Halo 用户!