avatar

蜗牛札记

记录技术、生活与一点点折腾

  • 首页
  • Halo
  • 关于
主页 从零搭建 Halo 博客:Docker + Caddy + PostgreSQL 完整指南
文章

从零搭建 Halo 博客:Docker + Caddy + PostgreSQL 完整指南

发表于 最近 更新于 最近
作者 Snailszzy
22~28 分钟 阅读

前言

本文记录了从零在 VPS 上搭建 Halo 博客的完整过程。技术栈:

  • Halo 2.24.1 — 开源博客系统
  • Docker + Docker Compose — 容器化部署
  • Caddy — 反向代理,自动申请 HTTPS 证书(注意:不是 Nginx)
  • PostgreSQL 16 — 生产级数据库

一、环境要求

  • 一台 VPS(本文使用 Oracle Cloud Ubuntu 22.04)
  • 已解析到 VPS 的域名(通过 Cloudflare 关联)
  • SSH 访问权限

二、安装 Docker

# 一键安装 Docker
curl -fsSL https://get.docker.com | sudo sh

# 将当前用户加入 docker 组(之后免 sudo)
sudo usermod -aG docker $USER

重新登录 SSH 后生效。


三、目录结构

所有文件统一放在 ~/halo-blog/ 下:

~/halo-blog/
├── docker-compose.yml    # 服务编排文件
├── Caddyfile             # 反向代理配置
├── halo-data/            # Halo 数据(文章、主题、附件等)
├── pg-data/              # PostgreSQL 数据
├── caddy-data/           # Caddy 证书数据
└── caddy-config/         # Caddy 配置缓存

四、docker-compose.yml 完整配置

services:
  db:
    image: postgres:16-alpine
    container_name: halo-db
    restart: unless-stopped
    volumes:
      - ./pg-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=halo
      - POSTGRES_USER=halo
      - POSTGRES_PASSWORD=your_strong_password
    networks:
      - halo-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U halo -d halo"]
      interval: 10s
      timeout: 5s
      retries: 5

  halo:
    image: halohub/halo:2.24.1
    container_name: halo
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - ./halo-data:/root/.halo2
    environment:
      - HALO_WORK_DIR=/root/.halo2
      - SPRING_R2DBC_URL=r2dbc:pool:postgresql://db:5432/halo
      - SPRING_R2DBC_USERNAME=halo
      - SPRING_R2DBC_PASSWORD=your_strong_password
      - SPRING_SQL_INIT_PLATFORM=postgresql
    networks:
      - halo-net

  caddy:
    image: caddy:2-alpine
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy-data:/data
      - ./caddy-config:/config
    networks:
      - halo-net

networks:
  halo-net:
    driver: bridge

将 your_strong_password 替换为你自己的强密码,两处保持一致。


五、Caddyfile 配置

blog.yourdomain.com {
    reverse_proxy halo:8090
    encode gzip
}

Caddy 反向代理原理

用户浏览器
    │  HTTPS 443
    ▼
┌─────────────┐
│    Caddy    │  ← 监听宿主机 80/443,自动管理 SSL 证书
└──────┬──────┘
       │  HTTP 8090(Docker 内部网络)
       ▼
┌─────────────┐
│    Halo     │  ← 只在内部网络,外部无法直接访问
└──────┬──────┘
       │
┌─────────────┐
│ PostgreSQL  │  ← 只在内部网络,不对外暴露
└─────────────┘

关键点:
1. 只有 Caddy 暴露了 80/443 端口到宿主机
2. Halo 和 PostgreSQL 仅在 Docker 内部网络 halo-net 中可见
3. 容器间通过容器名互相访问(halo、db 相当于内部 DNS)
4. Caddy 会自动向 Let's Encrypt 申请并续期 SSL 证书,无需手动操作

与 Nginx 的区别:Nginx 需要手动配置证书(certbot),Caddy 全自动,配置文件极简。


六、首次启动

cd ~/halo-blog
sudo docker compose up -d

等待约 1 分钟(首次需拉取镜像),然后访问 https://yourdomain.com/system/setup 完成初始化向导,设置管理员账号。


七、Docker 常用管理命令

查看运行状态

cd ~/halo-blog
sudo docker compose ps

查看实时日志

# 所有服务日志
sudo docker compose logs -f

# 只看 Halo
sudo docker logs halo -f

# 只看最近 50 行
sudo docker logs halo --tail=50

进入容器内部

# 进入 Halo 容器(精简镜像用 sh)
sudo docker exec -it halo sh

# 进入 PostgreSQL 并打开数据库终端
sudo docker exec -it halo-db psql -U halo -d halo

# 在 psql 中常用命令
# \dt          查看所有表
# \q           退出
# SELECT name FROM extensions LIMIT 10;  查看数据

查看容器资源占用

sudo docker stats

启停服务

sudo docker compose stop halo       # 停止 Halo(不删除容器)
sudo docker compose start halo      # 启动 Halo
sudo docker compose restart halo    # 重启 Halo
sudo docker compose down            # 停止并删除所有容器(数据不会丢失)
sudo docker compose up -d           # 重新创建并启动

八、更新 Halo 版本

Halo 支持平滑升级,数据库迁移自动完成。

cd ~/halo-blog

# 第一步:修改 docker-compose.yml 中的版本号
# 将 halohub/halo:2.24.1 改为新版本,例如 halohub/halo:2.25.0

# 第二步:拉取新镜像
sudo docker compose pull halo

# 第三步:重新启动
sudo docker compose up -d halo

# 验证版本
sudo docker logs halo 2>&1 | grep "Version:"

建议:更新前先备份数据(见下节)。


九、数据备份

方法一:Halo 后台一键备份(推荐)

登录 https://yourdomain.com/console/ → 系统 → 备份 → 点击「创建备份」。

备份为 zip 文件,包含所有文章、附件、主题设置,可直接用于恢复或迁移。

方法二:手动备份

# 停止 Halo(避免数据不一致)
sudo docker compose stop halo

# 备份 Halo 文件数据(主题、附件等)
tar -czf ~/halo-data-$(date +%Y%m%d).tar.gz -C ~/halo-blog halo-data/

# 备份 PostgreSQL 数据库
sudo docker exec halo-db pg_dump -U halo halo > ~/halo-db-$(date +%Y%m%d).sql

# 重新启动
sudo docker compose start halo

方法三:定时自动备份

# 创建备份目录
mkdir -p ~/backups

# 编辑 crontab
crontab -e

# 添加:每天凌晨 3 点自动备份
0 3 * * * cd ~/halo-blog && sudo docker exec halo-db pg_dump -U halo halo > ~/backups/db-$(date +\%Y\%m\%d).sql && tar -czf ~/backups/data-$(date +\%Y\%m\%d).tar.gz -C ~/halo-blog halo-data/ 2>/dev/null

# 查看 crontab 是否生效
crontab -l

十、迁移到新 VPS

所有数据都在 ~/halo-blog/ 目录中,迁移非常简单。

步骤一:旧 VPS 打包数据

cd ~/halo-blog

# 停止所有服务
sudo docker compose down

# 打包整个目录
tar -czf ~/halo-blog-migration.tar.gz -C ~/ halo-blog/

步骤二:传输到新 VPS

# 在本地机器执行
scp user@old-vps:~/halo-blog-migration.tar.gz user@new-vps:~/

# 或使用 rsync(支持断点续传)
rsync -avz --progress user@old-vps:~/halo-blog/ user@new-vps:~/halo-blog/

步骤三:新 VPS 恢复

# 安装 Docker
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

# 解压数据
tar -xzf ~/halo-blog-migration.tar.gz -C ~/

# 将域名 DNS 解析指向新 VPS IP
# (Cloudflare 中修改 A 记录)

# 启动服务
cd ~/halo-blog
sudo docker compose up -d

等待约 1 分钟后访问博客,所有数据完整保留,Caddy 会自动为新 IP 重新申请证书。

提示:如果域名不变,也可以直接复制 caddy-data/ 目录,省去重新申请证书的等待时间。


十一、常用操作速查表

操作 命令
启动全部服务 sudo docker compose up -d
停止全部服务 sudo docker compose down
查看运行状态 sudo docker compose ps
查看 Halo 日志 sudo docker logs halo -f
进入 Halo 容器 sudo docker exec -it halo sh
进入数据库 sudo docker exec -it halo-db psql -U halo -d halo
更新版本 改版本号 → pull → up -d
手动备份 DB sudo docker exec halo-db pg_dump -U halo halo > backup.sql
迁移博客 打包 halo-blog/ → 新机器解压 → up -d

总结

这套架构的核心优势是容器化部署,所有数据文件化。无论备份、恢复还是迁移,都只需要操作文件目录,没有复杂的环境依赖。整个博客只需要 Docker 就能完整运行。

许可协议:  CC BY 4.0
分享

相关文章

下一篇

上一篇

[折腾日记5] 用RustDesk远程桌面走自建服务器,配合Zerotier内网IP访问,实现低延迟流畅操控远程桌面——ZeroTier篇

最近更新

  • 从零搭建 Halo 博客:Docker + Caddy + PostgreSQL 完整指南
  • [折腾日记5] 用RustDesk远程桌面走自建服务器,配合Zerotier内网IP访问,实现低延迟流畅操控远程桌面——ZeroTier篇
  • [折腾日记4] 用RustDesk远程桌面走自建服务器,配合Zerotier内网IP访问,实现低延迟流畅操控远程桌面——RustDesk篇
  • 观看4K电影到底要用多大的宽带才够?
  • [Nas折腾] 如何优化群晖NAS上的Video Station以支持DTS和AC3解码

热门标签

Halo

目录

©2026 蜗牛札记. 保留部分权利。

使用 Halo 主题 Chirpy