◆ 静态博客与动态博客
静态博客的页面在本地由静态网站生成器生成,产物为 html、css 与 js 文件,托管到 GitHub Pages、Vercel 与 Cloudflare Pages 一类平台、对象存储或 Nginx 上;访问时服务器直接返回文件,不运行后端程序,也没有数据库。常用生成器有 Hexo、Hugo、Jekyll 与 Astro,GitBook、VitePress 一类文档工具同属静态路线。静态方案不需要常驻的服务端进程,可托管在免费平台;更新内容时需要在本地重新生成并上传,评论与搜索一类功能依赖第三方服务。
动态博客由服务端程序渲染页面,文章、评论与配置存于数据库,附带网页后台与主题、插件生态。常用程序有 WordPress、Halo、Typecho 与 Ghost。动态方案把写作、评论与检索都收进站内;代价是需要一台持续运行的服务器与数据库,资源占用高于静态方案。
选择依据:更新频率低、结构固定的站点用静态方案,开销更小;需要在网页后台在线写作、评论互动与更换主题的站点选动态方案。
◆ 整体思路
本文在一台已安装 1Panel 的服务器上搭建动态博客,程序选用 Halo。
Halo 为开源建站工具,服务端由 Java 编写,官方发布 Docker 镜像,带主题与插件的应用市场,数据库支持 PostgreSQL、MySQL 与内嵌 H2。1Panel 的应用商店把应用封装为 Docker 容器统一安装,Halo 的安装、启停与更新均在面板中完成。
◆ 安装前准备
数据库
数据库先于 Halo 安装。Halo 的文章、用户与配置存于数据库,支持 MySQL 与 PostgreSQL,官方推荐 PostgreSQL。
在 1Panel 的应用商店中安装其中一种,安装时设置 root 密码,端口保持默认。1Panel 创建的应用容器处于同一 Docker 网络,Halo 按应用名访问数据库,数据库端口无需对外放行。
安装 Halo 时面板会在所选数据库中自动创建库与用户,并写入连接配置,库名与账号在 Halo 的安装表单中指定。
端口
Halo 默认使用 8090 端口,下文示例统一使用 8090。
服务器防火墙需放行该端口,1Panel 的防火墙页面可直接添加规则;服务器在云上时,还需在云厂商的安全组放行同一端口,两处任缺一处,外部访问均不通。
◆ 安装 Halo
进入 1Panel 的应用商店,搜索 Halo 并安装。
等待应用状态变为已启动,容器列表中出现 Halo 对应容器。
正常结果:浏览器打开外部访问地址进入初始化页面。
常见问题:应用启动后立即停止或反复重启,查看容器日志,常见原因为数据库连接失败与端口被占用,前者检查库名、用户名与密码,后者更换端口后重新安装。
◆ 初始化与后台访问
容器运行后数据库中没有站点数据,首次访问进入初始化页面。
浏览器打开 http://192.168.1.50:8090,填写站点名称、管理员用户名、邮箱与密码,提交后页面跳转到博客前台。
后台地址为 http://192.168.1.50:8090/console,用初始化时设置的管理员账号登录;前台地址为 http://192.168.1.50:8090。初始化页面只在数据库中没有管理员账号时出现,此后访问直接进入前台。
◆ 主题
主题在后台的主题页面管理,可以从主题商店在线安装,或上传主题压缩包。
◆ 站点设置
站点信息在设置的基本设置中修改,含站点名称、副标题、logo 与页脚信息。
附件默认存于服务器本地,图片较多时可在附件的存储策略中新增 S3 协议对象存储,上传的图片直接写入对象存储,不再写入服务器磁盘。
文章在文章菜单中新建,编辑器内完成标题、正文与封面等设置,发布后在博客前台可见。
◆ 验证与排错
Halo 容器启动后先在服务器本机用 curl 确认端口响应。
curl -I http://127.0.0.1:8090
返回 200 表示容器已在监听并正常响应;连接被拒绝时按以下顺序排查:先看 1Panel 中应用与容器的状态,再看容器日志中的报错,最后确认端口映射与防火墙放行。
浏览器访问 http://192.168.1.50:8090 进入博客前台,访问 http://192.168.1.50:8090/console 进入登录页,两个地址均可用即表示搭建完成。
局域网外的访问需要公网地址,本文服务器处于内网,对外链路见另外一篇博客。