这篇文章记录一次 Halo 博客系统的部署过程。整体思路是:先准备服务器环境,再用 Docker Compose 启动 Halo 和数据库,确认本机服务正常后,通过反向代理、域名解析和 HTTPS 把站点开放到公网。
为什么选择 Halo
Halo 是一个开源的现代化建站系统,适合用来搭建个人博客、项目主页和内容站点。它的后台编辑体验比较完整,支持主题、插件、分类标签和评论等常见功能。对于个人站点来说,用 Docker 部署 Halo 的维护成本相对低,后续升级和迁移也比较清晰。
第一步:准备服务器
部署前先准备一台 Linux 服务器。推荐至少 1 核 1G 内存,如果站点访问量较大,可以适当提高配置。系统可以选择 Ubuntu、Debian、CentOS 或其他常见发行版。
先更新系统软件包,并安装基础工具:
sudo apt update
sudo apt install -y curl wget vim git ca-certificates gnupg
同时确认服务器防火墙和云厂商安全组已经放行必要端口:
22:SSH 登录。80:HTTP 访问和证书验证。443:HTTPS 访问。
第二步:安装 Docker 和 Compose
Halo 官方推荐使用容器方式部署。Docker 的好处是环境隔离清晰,数据库、应用和后续升级都更容易管理。
curl -fsSL https://get.docker.com | sudo bash
sudo systemctl enable docker
sudo systemctl start docker
docker --version
docker compose version
如果当前用户需要直接执行 Docker 命令,可以加入 docker 用户组:
sudo usermod -aG docker $USER
执行后重新登录 SSH,让用户组变更生效。
第三步:编写 Docker Compose 配置
创建一个专门的部署目录,用来保存 Halo 的配置和数据:
mkdir -p /opt/halo
cd /opt/halo
然后创建 docker-compose.yml。下面是一个常见的部署示例,包含 Halo 和 PostgreSQL:
services:
halo:
image: halohub/halo:2
container_name: halo
restart: unless-stopped
depends_on:
- postgres
ports:
- "127.0.0.1:8090:8090"
volumes:
- ./halo2:/root/.halo2
command:
- --spring.r2dbc.url=r2dbc:pool:postgresql://postgres:5432/halo
- --spring.r2dbc.username=halo
- --spring.r2dbc.password=请替换成强密码
- --spring.sql.init.platform=postgresql
- --halo.external-url=https://你的域名
postgres:
image: postgres:15
container_name: halo-postgres
restart: unless-stopped
environment:
POSTGRES_DB: halo
POSTGRES_USER: halo
POSTGRES_PASSWORD: 请替换成强密码
volumes:
- ./postgres:/var/lib/postgresql/data
这里有几个关键点:
127.0.0.1:8090:8090表示 Halo 只监听本机,公网访问交给 Nginx 或 Caddy。./halo2保存 Halo 应用数据。./postgres保存数据库数据。--halo.external-url要填写最终访问域名,建议直接使用 HTTPS 地址。
第四步:启动 Halo
配置文件写好后,在部署目录执行:
docker compose up -d
查看容器状态:
docker compose ps
docker compose logs -f halo
如果日志里没有明显报错,可以在服务器本机检查 Halo 是否启动:
curl -I http://127.0.0.1:8090
能返回 HTTP 响应,说明 Halo 应用本身已经跑起来了。
第五步:配置反向代理
为了让外部用户通过域名访问,需要在服务器上配置反向代理。以 Nginx 为例:
server {
listen 80;
server_name example.com www.example.com;
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;
}
}
保存后检查并重载 Nginx:
sudo nginx -t
sudo systemctl reload nginx
此时访问 http://example.com 应该可以看到 Halo 初始化页面或站点首页。
第六步:绑定域名并启用 HTTPS
在域名服务商处添加 DNS 解析记录,将域名 A 记录指向服务器公网 IP。解析生效后,可以使用 Certbot 申请 HTTPS 证书:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot 会自动完成证书申请、Nginx 443 配置以及 HTTP 到 HTTPS 的跳转。完成后用下面的命令检查:
curl -I https://example.com
sudo certbot renew --dry-run
renew --dry-run 成功,说明自动续期流程也没有问题。
第七步:完成 Halo 初始化
首次打开站点时,Halo 会进入初始化流程。通常需要设置管理员账号、站点标题、访问地址等信息。初始化完成后,就可以进入后台创建文章、安装主题和配置插件。
后台入口一般是:
https://你的域名/console如果登录后台后发现站点链接仍然生成 HTTP 地址,优先检查两个地方:
Docker Compose 中的
--halo.external-url是否已经设置为 HTTPS 域名。反向代理是否传递了
X-Forwarded-Proto请求头。
第八步:日常维护和备份
Halo 部署完成后,最重要的是备份。至少要备份两个目录:
/opt/halo/halo2:Halo 应用数据、主题、插件等。/opt/halo/postgres:数据库数据。
升级前建议先备份,再拉取新镜像并重启:
cd /opt/halo
docker compose pull
docker compose up -d如果升级后出现问题,可以根据备份恢复数据,或者先回退到旧镜像版本。
常见问题
容器启动失败:查看
docker compose logs -f halo,重点检查数据库连接地址、账号和密码。域名访问不到:检查 DNS 是否解析到服务器 IP,80/443 端口是否放行。
后台资源加载异常:检查
external-url是否和实际访问域名一致。HTTPS 正常但站内链接是 HTTP:检查反向代理的
X-Forwarded-Proto,并确认站点外部地址使用 HTTPS。数据库数据丢失:确认 Compose 的 volume 是否挂载到了宿主机目录,不要让数据库只保存在临时容器层里。
总结
Halo 的部署重点不只是把容器跑起来,而是把“应用、数据库、反向代理、域名、HTTPS、备份”这几个环节连成一个稳定链路。建议按顺序推进:先让本机服务正常,再开放 HTTP,最后启用 HTTPS 和自动续期。这样出现问题时,每一步都能单独验证,排查会简单很多。