Hubzilla 11.4.2 Docker Compose 部署指南

Hubzilla 11.4.2 基于 php:8.3-apache 自建镜像 + MariaDB 11 + mailpit 邮件通道的 Docker Compose 完整部署实录,含 4 步安装向导、ZAR 注册流程、cron 轮询器配置与 6 类实测故障排障

HubzillaHubzillaZot联邦平台PHP 应用Docker ComposeMariaDB2026/11/02

Hubzilla Docker Compose 部署指南

目标:用 Docker Compose 从零部署一套可用的 Hubzilla 11.4.2(Web + MariaDB + 本地邮件通道),走通安装向导、管理员注册、登录与联邦端点验证,并配好官方要求的 poller 定时任务。已在 Ubuntu 24.04 宿主机(Docker 29.x + Compose v2,PHP 8.3.36 + Apache/2.4.69 + MariaDB 11.8.9)实测通过;选型背景见 《Hubzilla 介绍与选型指南》。

一、环境信息

项目实测值
Hubzilla11.4.2(boot.php STD_VERSION 实测 '11.4.2')
Web 镜像hubzilla-11.4.2-web:local(基于 php:8.3-apache 自建,内置 PHP 8.3.36 / Apache/2.4.69 / msmtp)
数据库镜像mariadb:11(实测运行版本 11.8.9-MariaDB-ubu2404)
邮件通道镜像axllent/mailpit:latest(SMTP 1025 / Web UI 8025)
宿主机Ubuntu 24.04,Docker 29.x + Docker Compose v2
端口映射Web 8148:80,Mailpit UI 8149:8025
自定义网络hubzilla-11.4.2-net,子网 10.89.72.0/24(web=10.89.72.10,mail=10.89.72.30)
站点 baseurlhttp://10.89.72.10(compose 内以容器 IP 互访实测;生产应换 HTTPS 域名)
演示账号渠道昵称 admin / 密码 q1w2e3r4(管理员邮箱 root@example.com)
数据库口令hubzilla / q1w2e3r4,root 口令 q1w2e3r4

⚠️ 网络说明:实测期间 Hubzilla 官方源码站 framagit.org 直连与代理均超时不可用,源码包改由 gitlab.com 镜像 https://gitlab.com/fork/hubzilla/core/-/archive/11.4.2/core-11.4.2.tar.gz(代理 192.168.1.72:7897)下载,包体 74.7 MB / 14560 个文件;mariadb:11、php:8.3-apache、axllent/mailpit 三个基础镜像官方源直连拉取正常。

二、镜像选型说明

Hubzilla 官方文档 doc/en/Installation_using_docker.md(实测原文)推荐的 Docker 途径是社区镜像 ghcr.io/skprg/hubzilla-docker,核心包本身不提供官方 Dockerfile。

方案优点缺点本文选择
社区镜像 ghcr.io/skprg/hubzilla-docker开箱即用、含 cron 入口非官方维护、版本跟进有滞后风险、黑盒运行时备用
自建镜像(php:8.3-apache)版本可控、依赖透明、可定制 MTA需自备 Dockerfile✅ 本文

选择自建的关键实测理由:Hubzilla 注册流程硬依赖邮件发送成功(见 FAQ 11.1),php:8.3-apache 默认无 MTA,必须在镜像内补 msmtp-mta 并指向本地 SMTP——这一层定制在社区镜像上不可控,自建镜像把邮件通道做进部署基座最稳妥。

三、前置条件

  1. 宿主机已安装 Docker 20.10+ 与 Docker Compose v2(docker compose version 实测输出 Docker Compose version v2.x);
  2. 宿主机端口 8148、8149 空闲(ss -ltn | grep -E '8148|8149' 无输出);
  3. 已下载 Hubzilla 11.4.2 源码包并解压(见 4.1,含网络降级说明);
  4. 磁盘余量 ≥ 2 GB(MariaDB 数据 + 源码 + 镜像)。

四、部署步骤

4.1 目录布局与源码就位

实验目录约定(宿主侧):compose 文件、Dockerfile 等放 tmp/hubzilla/compose/,解压后的 Hubzilla 源码放 tmp/hubzilla/web/(以 bind mount 挂进容器),MariaDB 数据落 tmp/hubzilla/db/。

cd tmp/hubzilla
# 源码包(实测经 gitlab.com 镜像 + 代理下载,74.7MB)
curl -x http://192.168.1.72:7897 -LO https://gitlab.com/fork/hubzilla/core/-/archive/11.4.2/core-11.4.2.tar.gz
tar xzf core-11.4.2.tar.gz
mv core-11.4.2 web

4.2 Dockerfile(自建 Web 镜像)

tmp/hubzilla/compose/Dockerfile 实测全文:

FROM php:8.3-apache

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        libicu-dev libpng-dev libjpeg-dev libfreetype6-dev \
        libzip-dev libgmp-dev git unzip msmtp-mta \
    && docker-php-ext-configure gd --with-jpeg --with-freetype \
    && docker-php-ext-install intl gd mysqli pdo_mysql zip gmp \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

RUN a2enmod rewrite expires headers

COPY msmtp.conf /etc/msmtprc
COPY php.ini /usr/local/etc/php/conf.d/99-hubzilla.ini

逐项说明:

  • libicu-dev libpng-dev libjpeg-dev libfreetype6-dev libzip-dev libgmp-dev:intl、gd、zip、gmp 扩展的编译依赖;
  • docker-php-ext-install intl gd mysqli pdo_mysql zip gmp:安装向导环境检查的必装扩展(实测 step1 全绿,见 4.5);
  • msmtp-mta:提供 /usr/sbin/sendmail,让 PHP mail() 有真实投递通道(Hubzilla Mailer 实测调用 PHP mail());
  • a2enmod rewrite:Hubzilla 路由依赖 .htaccess rewrite(step1 检查项之一);
  • COPY msmtp.conf /etc/msmtprc:msmtp 全局配置,把邮件转发给 mailpit 服务。

msmtp.conf(落盘为容器内 /etc/msmtprc)实测全文:

defaults
auth           off
tls            off
auto_from      on
maildomain     10.89.72.10

account        default
host           mail
port           1025
  • host mail / port 1025:指向 compose 中 mail 服务(mailpit 的 SMTP 端口);
  • auto_from on + maildomain:本地发信(如 root)自动拼成 root@10.89.72.10 合法信封地址——不加这两行会触发 mailpit 553 5.1.3 拒收(实测,见 FAQ 11.2)。

php.ini(容器内 /usr/local/etc/php/conf.d/99-hubzilla.ini)实测全文:

upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 512M
max_execution_time = 120
date.timezone = Asia/Shanghai

安装向导 step1 实测读取该配置并显示 "Your max allowed total upload size is set to 64 MB"。

4.3 docker-compose.yml

实测全文:

name: hubzilla-11.4.2-stack

services:
  web:
    build: ./
    image: hubzilla-11.4.2-web:local
    container_name: hubzilla-11.4.2-web
    restart: unless-stopped
    depends_on:
      - db
      - mail
    ports:
      - "8148:80"
    volumes:
      - ../web:/var/www/html
    networks:
      default:
        ipv4_address: 10.89.72.10
    environment:
      - HUBZILLA_DB_HOST=db

  db:
    image: mariadb:11
    container_name: hubzilla-11.4.2-db
    restart: unless-stopped
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ../db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=q1w2e3r4
      - MYSQL_DATABASE=hubzilla
      - MYSQL_USER=hubzilla
      - MYSQL_PASSWORD=q1w2e3r4

  mail:
    image: axllent/mailpit:latest
    container_name: hubzilla-11.4.2-mail
    restart: unless-stopped
    ports:
      - "8149:8025"
    networks:
      default:
        ipv4_address: 10.89.72.30

networks:
  default:
    name: hubzilla-11.4.2-net
    ipam:
      config:
        - subnet: 10.89.72.0/24

要点解读:

  • web.volumes: ../web:/var/www/html——源码目录直接挂载而非 COPY 进镜像,升级 Hubzilla 只需替换宿主目录;该目录必须可写,安装向导要生成 .htconfig.php(step1 检查 .htconfig.php is writable);
  • db.command 强制 utf8mb4,与 Hubzilla 建表字符集一致;
  • mail 服务无 SMTP 认证、仅供内网测试投递,生产环境务必换成真实 SMTP(经 addon 插件或 msmtp 凭据配置);
  • 固定 IP 便于把 baseurl 写死为 http://10.89.72.10 复现实测。

4.4 构建与启动

cd tmp/hubzilla/compose
docker compose up -d --build

实测回显(节选,构建层已缓存时更快):

#11 naming to docker.io/library/hubzilla-11.4.2-web:local done
#11 unpacking to docker.io/library/hubzilla-11.4.2-web:local done
 Image hubzilla-11.4.2-web:local Built
 Network hubzilla-11.4.2-net Creating
 Network hubzilla-11.4.2-net Created
 Container hubzilla-11.4.2-mail Creating
 Container hubzilla-11.4.2-db Creating
 Container hubzilla-11.4.2-mail Created
 Container hubzilla-11.4.2-db Created
 Container hubzilla-11.4.2-web Creating
 Container hubzilla-11.4.2-web Created
 Container hubzilla-11.4.2-mail Starting
 Container hubzilla-11.4.2-db Starting
 Container hubzilla-11.4.2-mail Started
 Container hubzilla-11.4.2-db Started
 Container hubzilla-11.4.2-web Starting
 Container hubzilla-11.4.2-web Started

状态验证:

$ docker compose ps
NAME                   IMAGE                       COMMAND                  SERVICE   CREATED        STATUS                                     PORTS
hubzilla-11.4.2-db     mariadb:11                  "docker-entrypoint.s…"   db        1 second ago   Up Less than a second                      3306/tcp
hubzilla-11.4.2-mail   axllent/mailpit:latest      "/mailpit"               mail      1 second ago   Up Less than a second (health: starting)   1025/tcp, 1110/tcp, 0.0.0.0:8149->8025/tcp
hubzilla-11.4.2-web    hubzilla-11.4.2-web:local   "docker-php-entrypoi…"   web       1 second ago   Up Less than a second                      0.0.0.0:8148->80/tcp

等待约 15 秒后核对组件版本(docker compose logs db web 实测关键行):

hubzilla-11.4.2-db  | Version: '11.8.9-MariaDB-ubu2404'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
hubzilla-11.4.2-db  | mariadbd: ready for connections.
hubzilla-11.4.2-web | [Mon Nov 02 05:35:03 2026] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.69 (Debian) PHP/8.3.36 configured -- resuming normal operations

ready for connections 与 Apache resuming normal operations 即底座就绪。

4.5 安装向导(4 步)

Hubzilla 安装向导路由为 /setup(Zotlabs/Module/Setup.php),curl 可全程驱动。

Step 1 —— 环境检查:

$ curl -s -c w_ck.txt -o w1.html -w "%{http_code} %{size_download}\n" http://10.89.72.10/setup
200 9550

页面实测检查清单(18 项,全绿方可 Next):

System check
  libCurl / GD graphics / OpenSSL / PDO database / mb_string / xml / zip / intl / gmp PHP module (required)
  Apache mod_rewrite module (required)
  exec / shell_exec (required)
  .htconfig.php is writable (required)
  store is writable (required)
  store/[data]/smarty3 is writable (required)
  Generate encryption keys / Generate ed25519 encryption keys (required)
  Command line PHP ( /usr/local/bin/php )
  PHP register_argc_argv (required)
  PHP upload limits: total 64 MB, one file 64 MB, up to 20 files
  Url rewrite is working (required)

Step 2 —— 提交环境检查页(表单 pass=2,返回数据库表单页):

$ curl -s -b w_ck.txt -c w_ck.txt -o w2.html -w "%{http_code} %{size_download}\n" \
  -d "pass=2&phpath=/usr/local/bin/php" http://10.89.72.10/setup
200 9083

Step 3 —— 数据库连接验证(pass=3,返回站点设置页):

$ curl -s -b w_ck.txt -c w_ck.txt -o w3.html -w "%{http_code} %{size_download}\n" \
  -d "pass=3&dbhost=db&dbport=0&dbuser=hubzilla&dbpass=q1w2e3r4&dbdata=hubzilla&dbtype=0&phpath=/usr/local/bin/php&adminmail=root@example.com&siteurl=http://10.89.72.10" \
  http://10.89.72.10/setup
200 32102

页面标题实测 "Site settings",含管理员邮箱、站点 URL、时区选择(约 400 项)等字段。

Step 4 —— 写入配置并建表(pass=4):

$ curl -s -b w_ck.txt -c w_ck.txt -o w4.html -w "%{http_code} %{size_download}\n" \
  -d "pass=4&dbhost=db&dbport=0&dbuser=hubzilla&dbpass=q1w2e3r4&dbdata=hubzilla&dbtype=0&phpath=/usr/local/bin/php&timezone=Asia/Shanghai&adminmail=root@example.com&siteurl=http://10.89.72.10" \
  http://10.89.72.10/setup
200 7115

成功页实测原文:

Installation succeeded! Your site database has been installed.
What next?
IMPORTANT: You will need to [manually] setup a scheduled task for the poller.
Please see the file "install/INSTALL.txt".
Go to your new hub registration page and register as new member.
Remember to use the same email you have entered as administrator email.
This will allow you to enter the site admin panel.

验证产物:

$ ls -la ../web/.htconfig.php
-rw-r--r-- 1 www-data www-data 4721 Nov  2 13:37 ../web/.htconfig.php

$ docker exec hubzilla-11.4.2-db mariadb -uhubzilla -pq1w2e3r4 hubzilla -N \
  -e "select count(*) from information_schema.tables where table_schema='hubzilla';"
83

.htconfig.php 实测关键行(完整参数详解见 《Hubzilla 11.4.2 配置参数详解》):

$db_host = 'db';
$db_user = 'hubzilla';
$db_data = 'hubzilla';
App::$config['system']['timezone'] = 'Asia/Shanghai';
App::$config['system']['baseurl'] = 'http://10.89.72.10';
App::$config['system']['admin_email'] = 'root@example.com';
App::$config['system']['register_policy'] = REGISTER_OPEN;
App::$config['system']['access_policy'] = ACCESS_PRIVATE;
App::$config['system']['directory_mode']  = DIRECTORY_MODE_NORMAL;
App::$config['system']['theme'] = 'redbasic';

4.6 注册管理员渠道(ZAR 流程)

向导只建了站点与 sys 系统渠道,管理员账号必须走注册流程,且注册邮箱必须等于 admin_email(实测成功页明示,代码 check_account_admin() 按此授予 ADMIN 角色)。

提交注册表单(先 GET /register 取 form_security_token):

$ curl -s -c r_ck.txt -o r1.html -w "%{http_code} %{size_download}\n" http://10.89.72.10/register
200 19268

$ curl -s -b r_ck.txt -c r_ck.txt -w "%{http_code} -> %{redirect_url}\n" \
  -d "form_security_token=$TOK&name=admin&nickname=admin&email=root@example.com&password=q1w2e3r4&password2=q1w2e3r4&tos=1" \
  http://10.89.72.10/register
302 -> http://10.89.72.10/regate/726f6f74406578616d706c652e636f6de

注意:表单要求 password 与 password2 双字段(实测只传 password 时返回 200 重显表单并提示 "Please re-enter your password");redirect 路径末段是注册邮箱的 hex 编码 + 类型位 e。

从邮件取验证 token:确认邮件实测正文(经 mailpit API http://localhost:8149/api/v1/message/<id>/raw 拉取解码):

Thank you for registering at Hubzilla.

Site Location:	http://10.89.72.10
Login Name:	root@example.com

Your verification token is

a55d87cc3c0b7af868443568

This token is valid from 2026-11-02 05:38:27 UTC until 2026-11-05 05:38:27 UTC

提交 regate 确认(token 即 register 表 reg_hash):

$ curl -s -b r_ck.txt -c r_ck.txt -w "%{http_code} -> %{redirect_url}\n" \
  -d "form_security_token=$TOK&acpin=a55d87cc3c0b7af868443568&submit=Submit" \
  http://10.89.72.10/regate/726f6f74406578616d706c652e636f6de
302 -> http://10.89.72.10/profiles

302 到 /profiles 表示账号创建成功且会话已自动登录。数据库验证:

+------------+------------------+---------------+---------------+
| account_id | account_email    | account_roles | account_flags |
+------------+------------------+---------------+---------------+
|          1 | root@example.com |          4096 |             0 |
+------------+------------------+---------------+---------------+
+------------+-----------------+--------------------+
| channel_id | channel_address | channel_account_id |
+------------+-----------------+--------------------+
|          1 | sys             |                  0 |
|          2 | admin           |                  1 |
+------------+-----------------+--------------------+

account_roles=4096 即 ACCOUNT_ROLE_ADMIN 位;util/admins 实测输出 1 root@example.com *(* 标记管理员)。

4.7 登录与站点验证

新会话登录(表单字段实测为 main_login_username/main_login_password,登录名用渠道昵称 admin):

$ curl -s -b l_ck.txt -c l_ck.txt -w "%{http_code} -> %{redirect_url}\n" \
  -d "form_security_token=$TOK&auth-params=login&main_login_username=admin&main_login_password=q1w2e3r4" \
  http://10.89.72.10/login
302 -> http://10.89.72.10/

$ curl -s -b l_ck.txt -o /dev/null -w "%{http_code} %{size_download}\n" http://10.89.72.10/channel/admin
200 117260

API 与联邦发现端点实测:

$ curl -s http://10.89.72.10/api/z/1.0/version
"11.4.2"

$ curl -s http://10.89.72.10/.well-known/host-meta
<?xml version='1.0' encoding='UTF-8'?>
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0' xmlns:hm='http://host-meta.net/xrd/1.0'>
	<hm:Host>10.89.72.10</hm:Host>
	<Link rel='lrdd' type="application/xrd+xml" template='http://10.89.72.10/xrd/?uri={uri}' />
	<Link rel="http://oexchange.org/spec/0.8/rel/resident-target" type="application/xrd+xml" href="http://10.89.72.10/oexchange/xrd" />
</XRD>

$ curl -s "http://10.89.72.10/xrd/?uri=acct%3Aadmin%4010.89.72.10"
<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
	<Subject>acct:admin@10.89.72.10</Subject>
	<Alias>http://10.89.72.10/channel/admin</Alias>
	<Alias>http://10.89.72.10/~admin</Alias>
	<Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="http://10.89.72.10/ofeed/admin" />
	<Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="http://10.89.72.10/channel/admin" />
	<Link rel="http://portablecontacts.net/spec/1.0" href="http://10.89.72.10/poco/admin" />
	<Link rel="http://webfinger.net/rel/avatar" type="image/jpeg" href="http://10.89.72.10/photo/profile/l/2" />
	<Link rel="http://microformats.org/profile/hcard" type="text/html" href="http://10.89.72.10/hcard/admin" />
	<Link rel="http://ostatus.org/schema/1.0/subscribe" template="http://10.89.72.10/follow?f=&amp;url={uri}" />

(xrd 回显节选:末尾还有 magic-public-key 一条超长 base64 RSA 公钥 Link,此处省略。)WebFinger(XRD 形式)返回渠道别名、Atom feed、POCO 与关注端点,联邦身份就绪。

4.8 配置 poller 定时任务(必做)

安装成功页明示 poller 需手工挂定时任务。Hubzilla 的守护入口是 Zotlabs/Daemon/Master.php,实测直接执行:

$ docker exec -w /var/www/html hubzilla-11.4.2-web php Zotlabs/Daemon/Master.php Cron
$ echo $?
0

静默 rc=0 即正常(任务状态写入 DB:实测 config[system][lastcron] 随之刷新)。宿主机 crontab 推荐配置(每分钟,经 docker exec 触发):

* * * * * docker exec -w /var/www/html hubzilla-11.4.2-web php Zotlabs/Daemon/Master.php Cron >/dev/null 2>&1

⚠️ 注意:不配 cron 时站内收信、投递队列补投、内容过期清理全部停摆,表现为「能发不能收」,是 Compose 部署 Hubzilla 最常见的遗漏项。

五、数据持久化说明

数据宿主路径容器路径说明
MariaDBtmp/hubzilla/db//var/lib/mysqlbind mount,docker compose down 不删除
Hubzilla 源码+配置tmp/hubzilla/web//var/www/html.htconfig.php、store/(照片/附件)都在此目录内
邮件mailpit 内存态—测试通道,重启即清空,生产换真实 SMTP

实测重启验证:docker compose restart web 后管理会话与数据无损(/admin 200、account/channel 表行数不变);重建 db/ 目录才会回到未安装态(本文 4.4-4.6 即一次全新重建实录)。

六、环境变量表

变量服务实测值说明
MYSQL_ROOT_PASSWORDdbq1w2e3r4MariaDB root 口令
MYSQL_DATABASEdbhubzilla业务库名(向导 dbdata 填同名)
MYSQL_USER / MYSQL_PASSWORDdbhubzilla / q1w2e3r4业务账号,写入 .htconfig.php
HUBZILLA_DB_HOSTwebdb自定义提示变量;Hubzilla 本体不读该环境变量,实际以向导写入 .htconfig.php 的 db_host='db' 为准(实测)

💡 说明:与 Friendica/Mastodon 等「环境变量直接驱动配置」的项目不同,Hubzilla 11.x 的运行时配置入口是 .htconfig.php + 数据库 config 表两层(DB 覆盖文件),compose 环境变量只用于初始化 MariaDB——这是官方镜像文档未提供 web 侧 env 清单的根本原因。

七、配置参数说明

安装后生效的核心配置(实测值):

键值载体
system.baseurlhttp://10.89.72.10.htconfig.php
system.timezoneAsia/Shanghai.htconfig.php
system.register_policyREGISTER_OPEN.htconfig.php
system.access_policyACCESS_PRIVATE.htconfig.php
system.verify_email1.htconfig.php
system.directory_mode0(NORMAL)DB config(向导后实测)
system.directory_serverhttps://zotsite.netDB config(实测由代码从 fallback 列表随机选定)
system.db_version1265DB config

directory_server 的随机性来自 Zotlabs/Lib/Libzotdir.php(实测代码:DIRECTORY_MODE_NORMAL 时从 hub.netzgemeinde.eu / zotsite.net 列表 mt_rand 选一写入 DB)。隔离网络部署时该值会导致联邦探测/目录请求外发挂起,改法见 FAQ 11.6。全部参数逐项详解见 《Hubzilla 11.4.2 配置参数详解》。

八、配置文件挂载

本文采用「源码目录整体 bind mount + 镜像内 COPY 配置文件」的混合形态:

  • /var/www/html(源码+.htconfig.php+store/):宿主 ../web 挂载,改配置不需要重建镜像;
  • /etc/msmtprc、/usr/local/etc/php/conf.d/99-hubzilla.ini:Dockerfile COPY 进镜像,改动需 docker compose up -d --build 重建(实测重建仅 0.x 秒,层缓存生效)。

若希望 PHP/MTA 配置也热改,可把两文件改为 volumes 挂载:

    volumes:
      - ../web:/var/www/html
      - ./msmtp.conf:/etc/msmtprc:ro
      - ./php.ini:/usr/local/etc/php/conf.d/99-hubzilla.ini:ro

九、等价 docker run(理解编排等价形态)

将编排拆成手工命令的等价形态(用于理解映射关系,实际部署以 compose 为准;需先 docker network create --subnet 10.89.72.0/24 hubzilla-11.4.2-net):

# 数据库
docker run -d --name hubzilla-11.4.2-db --network hubzilla-11.4.2-net \
  -e MYSQL_ROOT_PASSWORD=q1w2e3r4 -e MYSQL_DATABASE=hubzilla \
  -e MYSQL_USER=hubzilla -e MYSQL_PASSWORD=q1w2e3r4 \
  -v $(pwd)/../db:/var/lib/mysql \
  mariadb:11 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

# 邮件通道
docker run -d --name hubzilla-11.4.2-mail --network hubzilla-11.4.2-net --ip 10.89.72.30 \
  -p 8149:8025 axllent/mailpit:latest

# Web(自建镜像需先 docker build -t hubzilla-11.4.2-web:local .)
docker run -d --name hubzilla-11.4.2-web --network hubzilla-11.4.2-net --ip 10.89.72.10 \
  -p 8148:80 -v $(pwd)/../web:/var/www/html \
  hubzilla-11.4.2-web:local

十、常用运维命令

# 状态与日志
docker compose ps
docker compose logs -f web
docker compose logs db | grep "ready for connections"

# 进入容器 / 执行 CLI(Hubzilla 的 util 工具必须在 Web 根目录运行)
docker compose exec web bash
docker compose exec -w /var/www/html web php util/config system
docker compose exec -w /var/www/html web php util/update_db

# 数据库
docker compose exec db mariadb -uhubzilla -pq1w2e3r4 hubzilla -e "select count(*) from account;"

# 手动触发一轮轮询/定时任务
docker compose exec -w /var/www/html web php Zotlabs/Daemon/Master.php Cron

# 升级 Hubzilla:替换 ../web 源码目录(保留 .htconfig.php 与 store/)后跑 DB 升级
docker compose exec -w /var/www/html web php util/update_db

util/ 工具逐条实测详解见 《Hubzilla 11.4.2 常用 CLI 命令与工具详解》。

十一、常见问题

11.1 注册提交后账号始终不创建(最严重卡点)

现象:POST /regate/<hex>a 返回 302 但 account 表仍空,站点无法完成初始化管理员。

定位(实测链路):开注册日志 php util/config system register_logfile 1 后,zar.log 实录以 ZAR1238E Account creation error 开头的回写行(rid:1 指向注册请求)。追代码 include/account.php::create_account_from_register():账号创建事务要求 send_reg_confirmation_email_from_register() 返回 true,确认邮件发不出去就整体回滚。php:8.3-apache 默认无 MTA,PHP mail() 必然失败。

解决:本文 4.2 方案——镜像内装 msmtp-mta + /etc/msmtprc 指向可用 SMTP(测试环境 mailpit)。验证邮件链可通:

$ docker exec hubzilla-11.4.2-web sh -c "printf 'To: t@10.89.72.10\nSubject: t\n\nbody\n' | /usr/sbin/sendmail -t"; echo rc=$?
rc=0

11.2 sendmail 报 553 5.1.3 / 451 4.3.5

现象(mailpit 日志实测):

[smtpd] response (10.89.72.10) 553 5.1.3 The address is not a valid RFC 5321 address
[smtpd] error parsing message: malformed header line: "test body"
[smtpd] response (10.89.72.10) 451 4.3.5 Unable to process mail

原因与解决:553 是信封发件人 root 无域名——/etc/msmtprc 加 auto_from on + maildomain <本机IP或域名>(本文 4.2 已含);451 是测试邮件缺 To:/Subject: 头,正文构造带完整头即可。

11.3 管理面板 /admin 打开挂起 25-60 秒

现象:登录态 GET /admin 实测 60.02 秒才返回 200。

定位:容器内 /proc/net/tcp 观察到对 176.9.183.75:443(及 framagit.org 方向)的 SYN_SENT 长挂;/admin 摘要页实测调用 include/network.php::get_repository_version(),硬编码抓取 https://framagit.org/hubzilla/core/raw/<branch>/boot.php 两次(master/dev),且默认 curl_connecttimeout=30。

解决(实测生效):

$ docker compose exec -w /var/www/html web php util/config system curl_connecttimeout 3
config[system][curl_connecttimeout] = 3
$ docker compose exec -w /var/www/html web php util/config system curl_timeout 5
config[system][curl_timeout] = 5
$ curl -m 30 -b l_ck.txt -o /dev/null -w "%{http_code} %{time_total}s\n" http://10.89.72.10/admin
200 6.017704s

挂起降至 6 秒(两次失败探测各 3s),页面正常显示,Repository version (master/dev) 显示 ?.?(探测失败的合法回退值)。彻底消除则需放行出网或改代码屏蔽版本探测。

11.4 向导 step1 报 "Url rewrite in .htaccess is not working"

实测为假阴性:容器内自测 URL 走了不可达的 https 端口导致探测失败。验证 rewrite 真实状态:

$ curl -s http://10.89.72.10/setup/testrewrite
ok

返回 ok(Setup.php 实测路由)即 rewrite 正常,可继续安装。

11.5 用注册邮箱登录失败(302 → /login?retry=1)

实测登录名优先用渠道昵称(本文 admin)。include/auth.php 逻辑:登录名不含 @ 走 channelx_by_nick() 按昵称查渠道;含 @ 则按 account_email 精确匹配——而 account_email 在开启邮件验证的流程中可能存内部标识而非真实邮箱,导致邮箱登录失败、昵称登录成功。

11.6 隔离网络中 directory_server 指向外部站点

实测 NORMAL 模式下代码会随机把 directory_server 写成 hub.netzgemeinde.eu 或 zotsite.net(本次实测落点 https://zotsite.net),隔离环境会引发目录探测外发挂起。私有部署改 STANDALONE 并本地化目录地址:

$ docker compose exec -w /var/www/html web php util/config system directory_mode 256
config[system][directory_mode] = 256
$ docker compose exec -w /var/www/html web php util/config system directory_server http://10.89.72.10
config[system][directory_server] = http://10.89.72.10

(256 = DIRECTORY_MODE_STANDALONE,boot.php 实测 0x0100。)

十二、参考链接

Hubzilla 11.4.2 Docker Compose 部署指南 - Quzuo