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

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
量子位
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
博客园 - 聂微东
博客园_首页
D
Docker
博客园 - 叶小钗
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
F
Fortinet All Blogs
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
腾讯CDC
罗磊的独立博客
雷峰网
雷峰网
博客园 - Franky

蛋蛋之家

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 又拍云文件管理插件修改版使用指南:新增自定义目录结构功能
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 自动发现功能