惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
U
Unit 42
W
WeLiveSecurity
博客园 - Franky
Recent Announcements
Recent Announcements
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
月光博客
月光博客
The Cloudflare Blog
Spread Privacy
Spread Privacy
腾讯CDC
P
Privacy International News Feed
N
News and Events Feed by Topic
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
T
Troy Hunt's Blog
小众软件
小众软件
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
量子位
P
Palo Alto Networks Blog
N
News and Events Feed by Topic
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
IT之家
IT之家
T
Threat Research - Cisco Blogs
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
G
Google Developers Blog
S
Secure Thoughts

蛋蛋之家

SUMIFS和LET函数——让 Excel 自己动起来 Halo 博客晚间卡顿排查记:从"玄学卡顿"到"真凶落网" 我用这个开源项目,把 AI 绘画提示词变成了"代码"——awesome-gpt-image-2 深度体验报告 群晖部署 LX Music Server:浏览器就是你的音乐播放器【详细版】 500道Word题库太痛苦?于是我写了个智能学习平台 别用一个人的奔跑,耗尽两个人的余生——《你凭什么认为我会一直喜欢你呢》 博客评论自动填充新方案:兼容 Vue/React 响应式绑定与跨架构填充逻辑 从 Typecho 转向 Halo 2.x:全能型 Nginx 架构与 SEO 无损迁移指南 Typecho 迁移 Halo 完整教程:数据库视图解决表前缀 + 自动提取封面图 + 去重检测 我的 CodeBuddy 装备库:218个技能全公开 + 使用心得 为博客添加自定义评论表情 Comment2Bark:Typecho评论推送到Bark插件 又拍云插件 UpyunFile v1.2 更新:修复 Typecho 1.3.0 兼容性问题 手把手修复RSS 403:从PHP警告到Cloudflare拦截的全链路排查 网站被镜像怎么办?2026年反镜像攻防实战指南 VLESS + Reality + Vision:2026 极致隐蔽节点搭建全解析 给OpenList和Alist加上液态玻璃效果,颜值直接拉满! 网页截图瞬间“赛博飞升”?手把手教你根治 Windows HDR 截图发白 群晖 NAS 影音终极方案:Docker Rclone + OpenList 完美挂载 Plex 全攻略 一个简洁高效的SVG图标库 告别重复劳动!一键填充评论的神奇书签脚本 - 蛋蛋之家 解锁思源笔记的隐藏力量:siyuan-patch 深度体验与技术实现 Oracle Cloud 自救指南:旧手机丢失后如何绕过 MFA 重新登录【更新2026年最新政策】 本站已加入“萌国ICP备案”联萌!😄 Excel 月报自动化指南:告别重复劳动,让数据主动为你服务 梦呓:为异地女友准备的2周年惊喜礼物 Typecho 多吉云插件优化:更灵活的存储目录配置 甲骨文云硬盘扩容指南:从50G到200G的“免费午餐”怎么吃? ⏰ 时间同步:当你的服务器开始“穿越”时,如何优雅地把它拉回现实 Typecho 又拍云文件管理插件修改版使用指南:新增自定义目录结构功能 华为鸿蒙6.0回退4.2记录 最近小公主情绪不佳 劳动节的家乡景色 烟台山公园一游 群晖搭建ChatGPT Web 推荐脚本:ChatGPT - 提示选择器 Activation Method for JetBrains Products (English version) JetBrains 系列产品激活方法 疫情三年后再进校园 修复searchEngineJump在谷歌搜索页面不生效问题 事情既然发生了,可以是遗憾,不要去后悔。 侄女的试唱会比赛 新一代图片编码格式测试 省科技馆之行 Typora Windows版破解补丁及主题推荐 在Typora中使用PicList上传图片 域名ICP备案之变更网站 Ubuntu 系统如何使用 root 用户登录 中国联通——让一切自由连不通 如何选购适合的口罩? 今天移动营业厅遇到一个小姐姐,真的好美 它不乐意 如何解决Typecho文章不是Markdown语法创建问题 探手抓住这一天的尾巴,为自己庆生 收到腾讯云自媒体分享计划2月份礼品 尝试百度Spider抓取异常问题 甲骨文DD重装系统及失联救砖教程 终于MrDoc升级v0.8.7成功了 Windows 端口查询及杀死进程 甲骨文实例开通与X-UI安装 国艺花鸟市场的悠闲 在思源笔记中使用群晖Synology C2对象存储服务 MrDoc升级v0.8.7失败 居居的手工作品 Linux系统时间同步命令小结 AList安装指南 宝塔面板降级 v7.7.0 及解除强制绑定手机、免费安装专业版插件的方法 修复群晖Synology Drive client右键菜单缺失问题 Windows11 展开折叠的右键菜单为传统模式 在 Windows 下批量将 Markdown 文档转为 Word 文档 Typecho的一些修改记录 Markdown语法——Mermaid 有两种新方案—CloudFlare官方免费CNAME接入教程 居居的新冠历程 群辉安装Transmission套件、增强汉化WebUI并备份做种列表 群晖 docker 部署思源笔记 Office for Mac 2019 License Installer 公众号通过api发送小程序消息 Windows 10下 iTunes 备份默认存储路径修改 Excel查找返回多个值,并将返回的值放在同一个单元格里面 七牛云测试域名失效后如何下载空间中的文件 入手三星860 evo 500g SSD固态硬盘 分享一套耐看的鼠标指针 如何重置OmniFocus数据库 Office for Mac 2016 License Installer Mac下配置终端+iTerm 2主题 如何制作苹果系统安装U盘 LNMP部署typecho,开启SSL、强制开启https Stylish样式如何设置为特定网址不生效? Typecho插件错误号:42S01的解决方法 电动车被偷了 热火 R150 上手开箱 UltraMon 3.3.0 汉化+注册机 如何用 MWeb 发布 Typecho 文章 测试 Mweb 发布到印象笔记功能 忘记了iPhone访问限制的密码该怎么办? 新玩具KAREE电子烟,先试试 Mac mini 2011 开启Handoff方法 见微知著 浅谈手游创新 PhoneClean Pro授权注册激活码
2026 生产级指南:Halo 2.x + PostgreSQL 自动化部署与性能优化手册
吴蛋蛋 · 2026-04-25 · via 蛋蛋之家

本手册旨在帮助管理员理解并快速部署基于 Docker Compose 的 Halo 博客系统。该配置针对 24G 内存服务器 进行了性能优化,并采用了环境变量解耦的安全策略。


🏗️ 1. 核心架构说明

该配置采用典型的 App-DB(应用 - 数据库)分层架构

  • Halo 容器 (halo_app):博客主程序,处理业务逻辑、渲染网页。

  • PostgreSQL 容器 (halo_db_server):关系型数据库,存储文章内容、设置、用户信息。

  • 虚拟网桥 (halo_internal_net):创建一个受保护的局域网,使两个容器可以通过名称(如 halodb)互相访问,而不受外部网络干扰。


🛠️ 2. 环境准备(部署前必做)

在宝塔面板或 SSH 终端执行以下步骤,确保基础环境就绪:

① 创建目录并授权

由于 Docker 以 root 权限运行,但内部程序(如 Postgres)有特定的用户 UID,建议预先创建目录并开放读写权限:

# 创建存储数据的根目录
mkdir -p /www/wwwroot/halo/data /www/wwwroot/halo/db

# 赋予最高权限以防止数据库启动失败 (Permission Denied)
chmod -R 777 /www/wwwroot/halo/

② 防火墙放行

在宝塔【安全】或云服务器【安全组】中开放以下端口:

  • 8090:博客访问入口。

  • 5432:数据库管理入口(若不需要远程连接数据库,可不开放)。


⚙️ 3. 关键配置项深度解析

🔋 性能调优:JVM 内存

- JVM_OPTS=-Xmx2048m -Xms512m
  • Xmx (最大堆内存):2G。在 24G 内存的服务器上,这能确保博客在高并发、处理大量图片插件时依然丝滑,且不会造成系统内存拥堵。

  • Xms (初始内存):512M。启动时即分配,减少初始运行时的内存申请开销。

🛡️ 自愈机制:健康检查 (Healthcheck)

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8090/..."]
  start_period: 60s
  • 逻辑:Docker 每 30 秒“问”一次 Halo 是否活着。

  • start_period:因为 Java 程序(Spring Boot)冷启动较慢,如果前 60 秒内报错,Docker 会忽略,不会误以为程序崩溃而不断重启。

🌐 域名依赖:External URL

- HALO_EXTERNAL_URL=http://localhost:8090/
  • 重要性这是小白最容易出错的地方。Halo 后台登录需要校验这个地址。如果你绑定了域名(如 https://blog.com),请务必在此处同步修改。


🚀 4. 部署与维护手册

启动命令

/www/wwwroot/halo 目录下运行:

docker-compose up -d

状态检查

# 查看容器是否都在运行
docker ps

# 实时查看启动日志(排查报错神器)
docker logs -f halo

如何修改数据库密码?

  1. 停止容器:docker-compose down

  2. 修改 YAML 中 两个服务 的密码项(必须保持一致)。

  3. 注意:如果数据库已经初始化,直接改配置可能无效,建议在首次部署前就确定好强密码。


❓ 5. 常见问题 (FAQ)

Q: 为什么状态显示 StartingUnhealthy

A: Java 应用启动通常需要 30-60 秒。请使用 docker logs -f halo 查看日志。如果一直卡住,请检查是否为 /www/wwwroot/halo/db 权限不足导致数据库崩溃。

Q: 我可以用 Navicat 连接数据库吗?

A: 可以。使用服务器公网 IP,端口 5432,用户名 halo,密码使用你在配置中设置的值。

Q: 如何更新 Halo 版本?

A: 修改 image 标签中的版本号(如 2.24.1 改为 2.25.0),然后重新运行 docker-compose up -d,Docker 会自动拉取新镜像并平滑更新。如果要保持2.x 最新版,版本号改为2即可。


🌰 6. 完整版配置示例

# ==============================================================================
# 🚀 HALO 2.X 博客系统 - 自动化部署母版 (2026 生产级标准)
# ==============================================================================
# 💡 使用说明:
# 1. 本文件已移除所有隐私(路径、密码、IP),直接复制即可安全分享。
# 2. 采用了 ${变量:-默认值} 格式,即使不配置外部变量也能按默认路径运行。
# 3. 适配宝塔面板、大内存服务器(如 Oracle Cloud 24G 实例)。
# ==============================================================================

services:
  # ----------------------------------------------------------------------------
  # [模块 A] Halo 博客主程序
  # ----------------------------------------------------------------------------
  halo:
    # 镜像地址:官方推荐的稳定版,建议锁定版本号以防自动更新导致数据不兼容
    image: registry.fit2cloud.com/halo/halo:2.24.1
    container_name: halo_app
    restart: always                                 # 策略:服务器重启或程序崩溃时,自动尝试无限次重启
    
    # 启动顺序:必须等下方的 [halodb] 数据库通过健康检查后,博客程序才开始引导
    depends_on:
      halodb:
        condition: service_healthy 

    networks:
      - halo_internal_net                           # 网络:加入内部隔离网络,不与外部无关容器混用

    volumes:
      # 【持久化挂载】:[服务器实际路径] : [容器内部路径]
      # 作用:把你上传的图片、安装的主题、插件存放在服务器硬盘上,容器删了数据还在
      - ${BASE_PATH:-/www/wwwroot/halo}/data:/root/.halo2

    ports:
      # 【端口映射】:[服务器对外端口] : [容器内部端口]
      # 作用:让你通过 http://IP:8090 能够访问到博客
      - "${WEB_PORT:-8090}:8090"

    healthcheck:
      # 【自愈检查】:每 30 秒探测一次后台接口,确保 Java 程序没有假死
      test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
      interval: 30s                                 # 检查频率
      timeout: 5s                                   # 响应超时
      retries: 5                                    # 连续失败 5 次则标记为“不健康”并尝试重启
      start_period: 60s                             # 启动缓冲:Java 启动较慢,前 1 分钟不进行强制判定

    environment:
      # 【JVM 调优】:针对 24G 内存机器,分配 2G 运行内存给博客,保证极致流畅
      - JVM_OPTS=-Xmx2048m -Xms512m
      
      # --- 数据库底层连接环境变量 (强制覆盖模式,比 command 更稳) ---
      # 格式:协议://数据库容器名:端口/数据库名
      - SPRING_R2DBC_URL=r2dbc:pool:postgresql://halodb:5432/${DB_NAME:-halo_db}
      - SPRING_R2DBC_USERNAME=${DB_USER:-halo_user}
      - SPRING_R2DBC_PASSWORD=${DB_PASS:-your_strong_password} # 【脱敏:此处填写你的数据库密码】
      - SPRING_SQL_INIT_PLATFORM=postgresql
      
      # 【访问域名】:请在此处填写你的真实访问地址(带 http/https),否则后台无法正常登录
      - HALO_EXTERNAL_URL=${SITE_URL:-http://localhost:8090/}
    
    # 💡 关键:清空默认指令,防止干扰上述 SPRING 环境变量的生效
    command: [] 

  # ----------------------------------------------------------------------------
  # [模块 B] PostgreSQL 数据库引擎
  # ----------------------------------------------------------------------------
  halodb:
    # 镜像地址:使用 alpine 版,不仅体积小(仅约 1/4),且安全性更高
    image: postgres:15-alpine
    container_name: halo_db_server
    restart: always

    networks:
      - halo_internal_net                           # 数据库仅在内部网桥运行,确保公网无法通过容器名攻击

    volumes:
      # 【持久化挂载】:存储所有的文章文字、用户信息、设置项
      - ${BASE_PATH:-/www/wwwroot/halo}/db:/var/lib/postgresql/data

    ports:
      # 【数据库映射】:方便你用 Navicat 或 DBeaver 在电脑本地远程管理数据库
      # 💡 安全建议:如果不需要远程连接,可以将这一行删掉或在防火墙限制 IP
      - "${DB_PORT:-5432}:5432"

    healthcheck:
      # 【就绪判定】:使用官方工具 pg_isready 确保数据库不仅在运行,且可以接受新连接
      test: [ "CMD-SHELL", "pg_isready -U ${DB_USER:-halo_user} -d ${DB_NAME:-halo_db}" ]
      interval: 10s
      timeout: 5s
      retries: 5

    environment:
      # 数据库初始化参数:这些参数必须与上面 [halo] 模块中的配置一一对应
      - POSTGRES_PASSWORD=${DB_PASS:-your_strong_password} # 数据库超级密钥
      - POSTGRES_USER=${DB_USER:-halo_user}               # 数据库登录用户名
      - POSTGRES_DB=${DB_NAME:-halo_db}                   # 默认创建的数据库库名
      - PGUSER=${DB_USER:-halo_user}                      # 指定健康检查所用的用户

# ------------------------------------------------------------------------------
# [模块 C] 网络隔离定义
# ------------------------------------------------------------------------------
networks:
  # 创建一个名为 halo_internal_net 的独立虚拟局域网
  halo_internal_net:
    driver: bridge                                  # 驱动:桥接模式,提供容器间 DNS 自动发现功能