Keyen's Wiki

Keyen's Wiki

Halo博客部署教程

42
2026-08-27

Halo 博客 / Wiki 部署教程(完全自托管)

从零到上线,在 Ubuntu 服务器上用 Docker 部署 Halo 博客系统。
适合想要一个「在线可视化编辑、完全自托管、数据掌握在自己手里」的个人博客 / Wiki 的你。

环境信息

项目
服务器 阿里云 ECS
操作系统 Ubuntu 24.04 LTS
架构 x86_64
域名 keyenzhou.wiki
博客系统 Halo 2.26(社区版,免费开源)
数据库 PostgreSQL 15.4
反向代理 Nginx

一、安装 Docker

⚠️ 关键点:国内服务器无法访问 Docker 官方源(download.docker.com 被墙),
必须使用阿里云镜像源,否则会报 docker-ce has no installation candidate

1. 更新软件源并安装依赖

sudo apt update
sudo apt install -y ca-certificates curl

2. 添加阿里云 Docker 源

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble stable" | sudo tee /etc/apt/sources.list.d/docker.list

验证仓库是否写入成功:

cat /etc/apt/sources.list.d/docker.list

3. 安装 Docker 全家桶

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

4. 验证

docker --version
docker compose version

两条都能输出版本号即成功。


二、配置镜像加速器

⚠️ 关键点:Docker Hub 在国内被封锁,阿里云官方加速器也已失效(返回 not found)。
目前可用的公共加速器如下,多配几个以防单个失效。

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors":
    [
      "https://docker.m.daocloud.io",
      "https://docker.xuanyuan.me",
      "https://docker.1ms.run"
    ]
}
EOF

重启 Docker 并验证:

sudo systemctl daemon-reload && sudo systemctl restart docker
sudo docker info | grep -A 5 "Registry Mirrors"

说明:镜像加速器只在「拉取镜像」时生效,不影响容器运行时网络和服务器正常网络。


三、部署 Halo + PostgreSQL

1. 创建工作目录

mkdir -p ~/halo && cd ~/halo

2. 创建配置文件

nano docker-compose.yaml

粘贴以下内容(修改两处external-url 换成你的域名、数据库密码可选改):

services:
  halo:
    image: registry.fit2cloud.com/halo/halo:2.26
    restart: on-failure:3
    depends_on:
      halodb:
        condition: service_healthy
    networks:
      halo_network:
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8090:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    environment:
      - JVM_OPTS=-Xmx256m -Xms256m
    command:
      - --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo
      - --spring.r2dbc.username=halo
      - --spring.r2dbc.password=openpostgresql
      - --spring.sql.init.platform=postgresql
      - --halo.external-url=http://keyenzhou.wiki/
  halodb:
    image: postgres:15.4
    restart: on-failure:3
    networks:
      halo_network:
    volumes:
      - ./db:/var/lib/postgresql/data
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_PASSWORD=openpostgresql
      - POSTGRES_USER=halo
      - POSTGRES_DB=halo
      - PGUSER=halo

networks:
  halo_network:

说明:

  • halo 镜像走 registry.fit2cloud.com(飞致云国内仓库),无需翻墙
  • postgres:15.4 走上一步配置的镜像加速器拉取
  • 数据库密码 openpostgresql 若修改,需保证 --spring.r2dbc.passwordPOSTGRES_PASSWORD 两处一致
  • postgres 容器未映射端口,仅 Halo 通过内网访问,外部无法连接,安全

3. 启动

sudo docker compose up -d

查看状态:

sudo docker compose ps

看到 halohalodb 都是 Up (healthy) 即成功。


四、配置 Nginx 反向代理

1. 编辑站点配置

sudo nano /etc/nginx/sites-available/default

清空原内容,替换为:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name keyenzhou.wiki www.keyenzhou.wiki;

    client_max_body_size 1024m;

    location / {
        proxy_pass http://127.0.0.1:8090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
    }
}

2. 测试并重载

sudo nginx -t
sudo systemctl reload nginx

五、初始化站点

  1. 浏览器打开 http://keyenzhou.wiki
  2. 按引导完成初始化:设置站点标题、创建管理员账号
  3. 登录后台:http://keyenzhou.wiki/console

六、安装主题

  1. 后台左侧「外观」→「主题」
  2. 点「安装」→ 应用市场搜索 joe(或 solitude
  3. 安装后点「启用」,再进主题「设置」自定义配色、头像等

七、日常使用

  • 写文章:后台「文章」→「新建」,使用块编辑器(所见即所得,支持 Markdown 快捷输入)
  • 管理:评论、附件、用户、插件都在后台 console 完成
  • 备份:后台「系统」→「备份」可整站备份;数据目录在服务器 ~/halo

八、升级、迁移与切换专业版

8.1 升级 Halo 版本

  1. (可选)先备份,见 8.4 日常备份

  2. 修改 docker-compose.yaml 中的镜像版本号,例如 2.262.27

    image: registry.fit2cloud.com/halo/halo:2.27
    
  3. 重新启动:

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

数据、主题、配置全部保留,无需重新初始化。

8.2 迁移到新服务器

第一步:旧服务器打包数据

cd ~
sudo tar -czf halo-backup.tar.gz halo

这会打包整个 ~/halo 目录(包含 Halo 数据和 PostgreSQL 数据)。
必须加 sudodb 目录下的 PostgreSQL 数据文件属主是容器内 postgres 用户(uid 999),不加 root 权限会读不全。

第二步:下载到本地

在本机 Windows PowerShell 执行:

scp keyenzhou@旧服务器IP:/home/keyenzhou/halo-backup.tar.gz D:\

第三步:上传到新服务器

scp D:\halo-backup.tar.gz keyenzhou@新服务器IP:/home/keyenzhou/

第四步:新服务器准备环境

在新服务器上完成「一、安装 Docker」和「二、配置镜像加速器」。

第五步:解压并启动

cd ~
sudo tar -xzf halo-backup.tar.gz
cd ~/halo
sudo docker compose up -d

解压同样用 sudo,确保 PostgreSQL 数据文件的属主(uid 999)被正确恢复。

第六步:切换域名解析

在域名解析控制台,把 A 记录指向新服务器 IP,等待解析生效即可。

注意:若新服务器没有配置镜像加速器,postgres:15.4 会拉取失败,务必先完成第二节。

8.3 切换到专业版(社区版 → 专业版)

前提:已在 凌霞软件 购买专业版许可证。

第一步:修改镜像

编辑 docker-compose.yaml,把 halo 改为 halo-pro

image: registry.fit2cloud.com/halo/halo-pro:2.26

第二步:重新启动

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

第三步:激活许可证

  1. 登录后台 http://keyenzhou.wiki/console
  2. 进入「系统」或「激活」页面,输入许可证
  3. 激活成功后即可使用专业版功能(移动端 App、专享主题/插件、SEO 工具等)

社区版与专业版数据完全互通,切换后文章、主题、配置原样保留,无需重新部署或迁移。

8.4 日常备份

方式一:后台整站备份

后台「系统」→「备份」→「创建备份」,可导出整站数据。

方式二:手动备份数据目录

cd ~
sudo tar -czf halo-backup-$(date +%F).tar.gz halo

建议配合 crontab 定时备份(root 用户下执行 crontab -e):

# 每天凌晨 3 点备份
0 3 * * * cd ~ && tar -czf halo-backup-$(date +%F).tar.gz halo

常见问题(FAQ)

Q1:docker-ce has no installation candidate

Docker 官方源被墙,改用阿里云源(见「一、安装 Docker」)。

Q2:镜像拉取 i/o timeoutnot found

Docker Hub 被封锁,加速器可能失效。多配几个加速器(见「二、配置镜像加速器」),或保留当前可用的那个。

Q3:镜像加速器会影响服务器正常网络吗?

不会。它只在拉取镜像时生效,不影响容器运行时和服务器其他网络。

Q4:后期想升级到 Halo 专业版,需要重新部署吗?

不需要。社区版与专业版数据互通,只需把镜像从 halo 换成 halo-pro 并激活许可证,数据原样保留。

Q5:如何升级 Halo 版本?

修改 docker-compose.yaml 里的镜像版本号,重新 sudo docker compose up -d 即可,数据不动。

Q6:如何备份和迁移?

整站数据都在 ~/halo 目录。备份时打包该目录即可;迁移到新服务器时,拷贝该目录到新机器、装好 Docker 后重新 docker compose up -d,数据完整恢复。