Wavelog 3.2.4 Docker Compose 部署指南

目标:在一台 Ubuntu 系 Linux 服务器上用 Docker Compose 从零部署 Wavelog 3.2.4(官方镜像 ghcr.io/wavelog/wavelog:3.2.4 + MariaDB 11.8),完成初始化向导、数据持久化、等价 docker run 验证与备份恢复演练,全部命令与回显均已在真实环境实测通过(2026-11-01)。

WavelogWavelogDocker自托管MariaDB2026/11/01

Wavelog 3.2.4 Docker Compose 部署指南

目标:在一台 Ubuntu 系 Linux 服务器上用 Docker Compose 从零部署 Wavelog 3.2.4(官方镜像 ghcr.io/wavelog/wavelog:3.2.4 + MariaDB 11.8),完成初始化向导、数据持久化、等价 docker run 验证与备份恢复演练,全部命令与回显均已在真实环境实测通过(2026-11-01)。

一、环境信息

本文实测环境的关键可复现信息如下:

  • 宿主操作系统:Ubuntu 系 Linux(x86_64)
  • Docker Engine:29.9.2(build a82e528)
  • Docker Compose:v5.6.1(Compose v2 语法)
  • Wavelog 版本:3.2.4(官方最新稳定版,GitHub Releases 订阅源最后更新 2026-10-14;镜像内环境变量 WAVELOG_GIT_DESCRIBE=3.2.4 可复核)
  • 镜像内技术栈:PHP 8.5.12 / Apache 2.4.69 (Debian) / 数据库 MariaDB 11.8.9
  • 数据库迁移版本:307(安装器 migrate 步骤回显 {"status":"success","version":"307"})
  • ADIF 版本:3.1.8
  • 部署目录:/opt/wavelog(compose 项目名 wavelog-3.2.4-stack,数据目录 /opt/wavelog/data/{config,dbdata,uploads,userdata})
  • Web 端口:宿主 8137 → 服务 80
  • 自建 bridge 网络:10.89.59.0/24(网关 10.89.59.1;数据库 wavelog-324-db 固定 10.89.59.10,应用 wavelog-324-main 固定 10.89.59.20)
  • 演示账号:管理员 root / q1w2e3r4(呼号 BH1ABC,网格 OM89KK,邮箱 root@quzuo.net,台站 Beijing / DXCC 27)
  • 数据库账号:业务用户 wavelog / q1w2e3r4,库名 wavelog;数据库 root 初始口令为镜像随机生成:&|YOKHf_Yw+9&W%}}XMD/~,V_$0FMOR2(见数据库首次启动日志,属演示环境值)

💡 说明:本文以「一台真实服务器上跑 Compose 栈」的视角撰写;wavelog-324-db / wavelog-324-main 是 compose 文件中显式指定的服务实例名(container_name),在栈内网络中即主机名,安装向导的数据库主机名直接填它。Wavelog 的定位、架构与选型论证见站内 《Wavelog 介绍与选型指南》,本文不重复。

二、镜像选型说明

Wavelog 官方发布 OCI 镜像于 GitHub Container Registry(GHCR),数据库官方文档示例采用 MariaDB 镜像。本次实测选型:

组件镜像选型理由
应用ghcr.io/wavelog/wavelog:3.2.4官方镜像;钉住最新稳定版 3.2.4,不用 latest,保证可复现与可回滚
数据库mariadb:11.8官方文档 docker 示例即 MariaDB 11.x;11.8 为当前维护分支,实际运行 11.8.9

本地已拉取镜像的实测大小对照(docker images 回显节选):

mariadb:10.6	440MB	f1c56f035ed2
mariadb:10.11	459MB	d769e3796082
mariadb:11.8	458MB	f16d7a344413
mariadb:10	459MB	0d0945c57f75
mariadb:latest	516MB	0e4bb0f339fe
ghcr.io/wavelog/wavelog:3.2.4	1.12GB	6d02c84188a6

解读:mariadb:11.8(458MB)与 latest(516MB)大小接近但分支语义不同——latest 会随上游漂移,生产应像本例一样钉住 11.8;应用镜像 1.12GB 内含 Apache+PHP+全部 Wavelog 代码,属 LAMP 全家桶的正常体量。

💡 技术拓展:Wavelog 的数据库端选型不止 MariaDB。同为 LAMP 栈的可选关系库对比——

选项特点适用场景
MariaDBGPL 开源、默认 InnoDB、镜像体积小、官方文档首选自托管首选(本文所用)
MySQLOracle 商业背书的同源实现已有 MySQL 运维体系的环境
Percona ServerMySQL 分支、增强性能与工具链需要企业级调优工具

Wavelog 官方文档明确推荐 MariaDB(其 docker 示例即用 mariadb:11),本文遵循官方口径采用 mariadb:11.8; mysqli 驱动对 MySQL 亦兼容,切换只需改 compose 环境变量与向导中的主机名。

三、前置条件

部署前确认宿主的 Docker 组件版本与端口占用。实测回显:

docker --version
docker compose version
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1

前置清单:

  • Docker Engine 与 Compose v2 可用(如上实测);
  • 宿主端口 8137 空闲(本例 Web 入口;被占用时改 compose 的 ports 映射即可,注意避开其他服务已占端口——见十一、11.4 端口冲突实录);
  • 磁盘余量 ≥ 2GB(应用镜像 1.12GB + 数据库镜像 458MB + 数据目录);
  • 已规划好管理员账号信息(呼号、网格 Locator、邮箱、时区、DXCC),初始化向导要逐项填写。

四、部署步骤

本节从创建目录开始,到完成初始化向导并验证登录,构成完整的 0→1 部署主线。

4.1 创建部署目录与数据目录

Compose 栈用 bind mount 持久化四类数据,先在服务器上建好目录:

mkdir -p /opt/wavelog/data/{config,dbdata,uploads,userdata}
cd /opt/wavelog

创建后实测 ls -ln data/(数字 UID/GID 显示属主):

total 16
drwxrwxr-x 2 999 33 4096 Nov  1 17:40 config
drwxr-xr-x 2 999 33 4096 Nov  1 17:40 dbdata
drwxrwxr-x 2 999 33 4096 Nov  1 17:40 uploads
drwxrwxr-x 2 999 33 4096 Nov  1 17:40 userdata

解读:四个目录的属主 UID/GID 为 999:33——999 是 MariaDB 官方镜像内数据库进程的默认运行用户,33 是 Debian 系 www-data 组;服务首次启动时入口脚本会自动把挂载目录调整为镜像内部用户身份,无需手工 chown,只要保证宿主用户对父目录有写权限即可。

4.2 编写 docker-compose.yml

在 /opt/wavelog/docker-compose.yml 写入以下内容(实测使用的原文):

name: wavelog-3.2.4-stack
services:
  wavelog-db:
    image: mariadb:11.8
    container_name: wavelog-324-db
    environment:
      MARIADB_RANDOM_ROOT_PASSWORD: "yes"
      MARIADB_DATABASE: wavelog
      MARIADB_USER: wavelog
      MARIADB_PASSWORD: q1w2e3r4
    volumes:
      - ./data/dbdata:/var/lib/mysql
    restart: unless-stopped
    networks:
      wavelog-net:
        ipv4_address: 10.89.59.10
  wavelog-main:
    container_name: wavelog-324-main
    image: ghcr.io/wavelog/wavelog:3.2.4
    depends_on:
      - wavelog-db
    environment:
      CI_ENV: docker
    volumes:
      - ./data/config:/var/www/html/application/config/docker
      - ./data/uploads:/var/www/html/uploads
      - ./data/userdata:/var/www/html/userdata
    ports:
      - "8137:80"
    restart: unless-stopped
    networks:
      wavelog-net:
        ipv4_address: 10.89.59.20
volumes: {}
networks:
  wavelog-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.59.0/24
          gateway: 10.89.59.1

逐项说明关键配置:

  • name: wavelog-3.2.4-stack:compose 项目名,决定网络名前缀(wavelog-324-stack_wavelog-net);
  • MARIADB_RANDOM_ROOT_PASSWORD: "yes":root 口令随机生成并打印在启动日志(本例实测生成值见一、环境信息),同时用 MARIADB_DATABASE/USER/PASSWORD 预建业务库与业务账号,向导里就不需要 root 凭据;
  • CI_ENV: docker:让 Wavelog 加载 application/config/docker/ 目录下的配置(安装器把生成的 config.php/database.php 写进该目录,恰好落在 bind mount 上,升级镜像不丢配置);
  • depends_on: wavelog-db:保证数据库先起;
  • 固定 ipv4_address:自建子网 10.89.59.0/24 给两个实例钉死 IP,方便防火墙放行与排障定位;
  • restart: unless-stopped:宿主机重启后自动拉起。

💡 技术拓展:数据持久化不止 bind mount 一种形态。Compose 常见挂载方式对比——

方式特点适用场景
bind mount(本文)宿主目录直接映射,路径可控、便于 tar/备份脚本处理单机自托管、备份演练直观
named volume由 Docker 管理生命周期,docker volume 系列命令操作不关心底层路径的环境
tmpfs仅内存,重启即失临时试验

官方文档示例用 named volume;本文改 bind mount 是为了把数据目录纳入常规文件备份体系(见十、10.2 备份演练),两种形态功能等价。

4.3 启动栈

cd /opt/wavelog && docker compose up -d

实测回显:

 Network wavelog-324-stack_wavelog-net Creating 
 Network wavelog-324-stack_wavelog-net Created 
 Container wavelog-324-db Creating 
 Container wavelog-324-db Created 
 Container wavelog-324-main Creating 
 Container wavelog-324-main Created 
 Container wavelog-324-db Starting 
 Container wavelog-324-db Started 
 Container wavelog-324-main Starting 
 Container wavelog-324-main Started

验证服务状态(docker compose ps):

NAME               IMAGE                           COMMAND                  SERVICE        CREATED         STATUS         PORTS
wavelog-324-db     mariadb:11.8                    "docker-entrypoint.s…"   wavelog-db     3 seconds ago   Up 2 seconds   3306/tcp
wavelog-324-main   ghcr.io/wavelog/wavelog:3.2.4   "/usr/local/bin/entr…"   wavelog-main   2 seconds ago   Up 2 seconds   0.0.0.0:8137->80/tcp, [::]:8137->80/tcp

两个服务均 Up,Web 已在宿主 8137 端口监听;数据库 3306/tcp 不对外映射,仅在栈内网络可达——这是刻意的安全设计。

4.4 首次访问与服务日志

首次探测 Web 入口:

curl -s -o /dev/null -w 'first http_code=%{http_code}\n' http://127.0.0.1:8137/
first http_code=302

看响应头确认 302 的去向:

curl -sI http://127.0.0.1:8137/
HTTP/1.1 302 Found
Date: Sun, 01 Nov 2026 09:40:31 GMT
Server: Apache/2.4.69 (Debian)
X-Powered-By: PHP/8.5.12
Location: /install/
Content-Type: text/html; charset=UTF-8

解读:Location: /install/ 说明应用处于「未安装」状态、自动跳转到安装向导——这正是新装实例的预期行为;响应头同时坐实了 Apache/2.4.69 (Debian) 与 PHP/8.5.12 版本线。

服务启动日志(docker compose logs,输出节选(实测首尾)):

wavelog-324-main  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.89.59.20. Set the 'ServerName' directive globally to suppress this message
wavelog-324-main  | [Sun Nov 01 09:40:29.376558 2026] [mpm_prefork:notice] [pid 1:tid 1] AH00163: Apache/2.4.69 (Debian) PHP/8.5.12 configured -- resuming normal operations
wavelog-324-main  | [Sun Nov 01 09:40:29.376588 2026] [core:notice] [pid 1:tid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
wavelog-324-main  | 10.89.59.1 - - [01/Nov/2026:09:40:31 +0000] "GET / HTTP/1.1" 302 197 "-" "curl/8.18.0"
wavelog-324-db    | create_uring failed: falling back to libaio
wavelog-324-db    | 2026-11-01  9:40:31 0 [Note] InnoDB: Using Linux native AIO
wavelog-324-db    | 2026-11-01  9:40:31 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
wavelog-324-db    | 2026-11-01  9:40:31 0 [Note] InnoDB: Completed initialization of buffer pool
wavelog-324-db    | 2026-11-01  9:40:31 0 [Note] InnoDB: End of log at LSN=45450
wavelog-324-db    | 2026-11-01  9:40:31 0 [Note] Plugin 'FEEDBACK' is disabled.
wavelog-324-db    | 2026-11-01  9:40:31 0 [Note] InnoDB: Buffer pool(s) load completed at 261101  9:40:31

解读:

  • AH00558 是 Apache 未设 ServerName 的告警,不影响服务(处理办法见十一、11.1);
  • create_uring failed: falling back to libaio 是 InnoDB 尝试 io_uring 异步 IO 失败后自动回退 libaio,属环境适配信息而非错误(见十一、11.3);
  • innodb_buffer_pool_size=128m 是镜像默认缓冲池,个人日志库量级足够,大日志量调优见站内 《Wavelog 3.2.4 配置参数详解》 的生产模板章。

4.5 初始化向导

浏览器访问 http://<服务器IP>:8137/install/ 即进入官方安装向导,依次填写数据库连接、站点 URL 与管理员信息。本文用 curl 脚本把向导逐步自动化实测(等价于浏览器点击,字段完全一致),脚本关键步骤:

#!/bin/bash
set -e
BASE=http://127.0.0.1:8137
JAR=/opt/wavelog/cookies.txt
rm -f "$JAR"

# 步骤0: GET 向导页, 提取 64 位 form_token
FORM_TOKEN=$(curl -sL -c "$JAR" "$BASE/install/" | grep -oE 'name="form_token" value="[a-f0-9]+"' | grep -oE '[a-f0-9]{64}')

# 表单字段(演示账号/台站信息全部落实际值)
FIELDS=(
  --data-urlencode "form_token=$FORM_TOKEN"
  --data-urlencode "db_hostname=wavelog-324-db"
  --data-urlencode "db_name=wavelog"
  --data-urlencode "db_username=wavelog"
  --data-urlencode "db_password=q1w2e3r4"
  --data-urlencode "directory="
  --data-urlencode "websiteurl=$BASE/"
  --data-urlencode "firstname=Qu"
  --data-urlencode "lastname=Zuo"
  --data-urlencode "username=root"
  --data-urlencode "callsign=BH1ABC"
  --data-urlencode "password=q1w2e3r4"
  --data-urlencode "cnfm_password=q1w2e3r4"
  --data-urlencode "user_email=root@quzuo.net"
  --data-urlencode "userlocator=OM89KK"
  --data-urlencode "timezone=131"
  --data-urlencode "city=Beijing"
  --data-urlencode "userlanguage=english"
  --data-urlencode "log_threshold=1"
  --data-urlencode "global_call_lookup=none"
  --data-urlencode "callbook_username="
  --data-urlencode "callbook_password="
  --data-urlencode "callbook_token="
  --data-urlencode "dxcc=27"
)

# 步骤1: POST run.php 提交全部表单字段, 提取 installer_token
INSTALLER_TOKEN=$(curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/install/run.php" "${FIELDS[@]}" | grep -oE "_installer_token = '[a-f0-9]+'" | grep -oE '[a-f0-9]{64}')

# 步骤2-4: 带 X-Installer-Token 头逐步执行 ajax 步骤
run_step run_config_file      # 生成 config.php / database.php
run_step run_database_file    # 写入数据库连接配置
run_step run_database_tables  # 建表

# 步骤5: 执行迁移
curl -s -b "$JAR" "$BASE/index.php/migrate"

# 步骤6: 生成 cron 访问令牌并首更 DXCC
curl -s -b "$JAR" -X POST "$BASE/install/ajax.php" -H "X-Installer-Token: $INSTALLER_TOKEN" --data-urlencode "run_cron_token=1"
curl -s -b "$JAR" -H "X-Wavelog-Auth: $CRON_TOKEN" "$BASE/index.php/update/dxcc"

# 步骤7: 上安装锁
run_step run_installer_lock

实测逐步回显:

form_token=2a94f8f79d9abfa3...
installer_token=8ce3f076440ada91...
run_config_file: success
run_database_file: success
run_database_tables: success
migrate: {"status":"success","version":"307"}
cron_token=3104a9e2d58faefc...
update/dxcc: success
run_installer_lock: success
DONE

解读:

  • migrate: {"status":"success","version":"307"} 表明全部数据表建好并迁移到版本 307;
  • cron_token 是后台任务访问令牌(实测确认它不落数据库、由 encryption_key 经 HMAC-SHA256 派生,机制详见站内 《Wavelog 3.2.4 配置参数详解》);
  • run_installer_lock: success 上安装锁后,/install/ 即失效,防止重复安装覆盖数据。

⚠️ 注意:向导中数据库主机名必须填 wavelog-324-db(compose 服务实例名),官方文档特别提醒不是 localhost——数据库端口没有映射到宿主,localhost 上并没有 3306。

4.6 安装后验证

安装锁生效后,根路径行为应立即改变。实测 curl -sI http://127.0.0.1:8137/:

HTTP/1.1 303 See Other
Date: Sun, 01 Nov 2026 09:41:31 GMT
Server: Apache/2.4.69 (Debian)
X-Powered-By: PHP/8.5.12
Set-Cookie: language=english; expires=Wed, 02 Dec 2026 09:41:31 GMT; Max-Age=2678400; path=/
Set-Cookie: ci_wavelog=62968f5b2ce5a1271dd2f2c7f941d7364b87d063; expires=Sun, 01 Nov 2026 21:41:31 GMT; Max-Age=43200; path=/; HttpOnly; SameSite=Lax
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: http://127.0.0.1:8137/user/login
Content-Type: text/html; charset=UTF-8

解读:302→/install/(未装)变为 303→/user/login(已装),安装锁生效;ci_wavelog 会话 Cookie 带 HttpOnly; SameSite=Lax、Max-Age=43200(12 小时),与 config.php 的 session 配置一致。

用管理员凭据登录做端到端验证:

login: 303 -> http://127.0.0.1:8137/dashboard
dashboard: 200 url=http://127.0.0.1:8137/index.php/dashboard
<title>Dashboard - Wavelog</title>

root / q1w2e3r4 登录后 303 跳转 Dashboard、页面 200,部署主线完成。

五、数据持久化说明

四个 bind mount 的职责与备份要点:

宿主目录挂载点内容丢失后果
data/dbdata/var/lib/mysql全部业务数据(QSO、用户、台站、options)灾难性,必须定期备份(见 10.2)
data/config/var/www/html/application/config/docker安装器生成的 config.php、database.php需重走向导或从备份恢复
data/uploads/var/www/html/uploadsQSL 图片等上传件上传件丢失
data/userdata/var/www/html/userdata用户数据(标签模板等,按 user_id 分目录)用户级文件丢失

实测 userdata 目录结构(安装并创建台站后):

total 16
drwxrwxr-x 3 wavelog  www-data 4096 Nov  1 09:41 .
drwxrwxrwt 1 www-data www-data 4096 Oct 21 19:06 ..
drwxr-xr-x 4 www-data www-data 4096 Nov  1 09:41 1

解读:userdata/1 即 user_id=1(root)的私有目录;应用运行用户(wavelog/www-data)对四个目录均有写权限,属主在首次启动时已自动调整。

⚠️ 注意:docker compose down -v 只删 named volume,不动 bind mount 数据;但删除宿主目录等于删库。真正的数据库级备份恢复见 10.2 演练实录。

六、环境变量表

compose 中两个服务的环境变量实测清单:

变量服务值作用
MARIADB_RANDOM_ROOT_PASSWORDwavelog-db"yes"随机生成 root 口令并打印到启动日志(本例生成 `&
MARIADB_DATABASEwavelog-dbwavelog首次启动预建业务库
MARIADB_USERwavelog-dbwavelog预建业务账号
MARIADB_PASSWORDwavelog-dbq1w2e3r4业务账号口令(演示值)
CI_ENVwavelog-maindocker启用 application/config/docker 配置目录

应用镜像内其他关键环境变量(实测 env 回显节选):

CI_ENV=docker
PHP_VERSION=8.5.12
WAVELOG_GIT_DESCRIBE=3.2.4
APACHE_CONFDIR=/etc/apache2
PHP_INI_DIR=/usr/local/etc/php

解读:WAVELOG_GIT_DESCRIBE=3.2.4 与 PHP_VERSION=8.5.12 是核对镜像版本线的第一手依据;PHP_INI_DIR 指出 PHP 配置目录,PHP 层参数(memory_limit 等)的实测生效值见七、7.3。

七、配置文件生成与关键参数

7.1 安装器生成的配置目录

初始化向导 run_config_file 步骤把配置写进挂载目录,实测 ls -l /var/www/html/application/config/docker/:

total 52
drwxrwxr-x 2 999  www-data  4096 Nov  1 17:40 .
drwxr-xr-x 6 999  www-data  4096 Nov  1 17:40 ..
-rw-r--r-- 1 www-data www-data 34739 Nov  1 17:40 config.php
-rw-r--r-- 1 www-data www-data  4633 Nov  1 17:40 database.php

config.php 948 行、database.php 98 行(实测 wc -l),前者承载应用全部静态配置,后者只描述数据库连接。

7.2 database.php 关键段实测

$db['default'] = array(
	'dsn'	=> '',
	'hostname' => 'wavelog-324-db',
	'username' => 'wavelog',
	'password' => 'q1w2e3r4',
	'database' => 'wavelog',
	'dbdriver' => 'mysqli',
	'pconnect' => TRUE,
	'char_set' => 'utf8mb4',
	'dbcollat' => 'utf8mb4_general_ci',
	...
);

(输出节选(实测首尾):省略 dbprefix/db_debug/cache_on 等保持默认值的键。)hostname 即 compose 服务实例名,与 4.5 向导填写一致。

7.3 PHP 运行时参数实测生效值

max_execution_time => 0 => 0
memory_limit => 256M => 256M
post_max_size => 64M => 64M
upload_max_filesize => 64M => 64M

解读:Web 请求不限执行时间(CLI 值 0)、内存 256M、上传上限 64M,决定了 ADIF 大文件导入与 QSL 图片上传的单次容量边界。

配置项的完整分类详解(session、cache、auth、cron、options 表、cron 表 21 任务等)见站内 《Wavelog 3.2.4 配置参数详解》。

八、配置文件挂载

本栈三个应用侧挂载点的对应关系:

compose 卷容器内路径说明
./data/config/var/www/html/application/config/docker配置目录整体外置;镜像升级/重建不丢配置,改配置后 docker compose restart wavelog-main 生效
./data/uploads/var/www/html/uploadsQSL 图片等上传件
./data/userdata/var/www/html/userdata用户级数据

⚠️ 注意:CI_ENV=docker 时 CodeIgniter 加载 config/docker/ 覆盖默认 config/ 目录;若把该目录删空,应用会退回「未安装」状态(302 跳 /install/)。备份 data/config 与备份数据库同等重要。

九、等价 docker run

Compose 可拆解为手工 docker run。以下为本栈的等价命令,并已实测验证(临时实例用后删除):

docker network create --subnet 10.89.59.0/24 --gateway 10.89.59.1 wavelog-net

docker run -d --name wavelog-324-db \
  -e MARIADB_RANDOM_ROOT_PASSWORD=yes \
  -e MARIADB_DATABASE=wavelog -e MARIADB_USER=wavelog -e MARIADB_PASSWORD=q1w2e3r4 \
  -v /opt/wavelog/data/dbdata:/var/lib/mysql \
  --network wavelog-net --ip 10.89.59.10 \
  --restart unless-stopped \
  mariadb:11.8

docker run -d --name wavelog-324-main \
  -e CI_ENV=docker \
  -v /opt/wavelog/data/config:/var/www/html/application/config/docker \
  -v /opt/wavelog/data/uploads:/var/www/html/uploads \
  -v /opt/wavelog/data/userdata:/var/www/html/userdata \
  -p 8137:80 \
  --network wavelog-net --ip 10.89.59.20 \
  --restart unless-stopped \
  ghcr.io/wavelog/wavelog:3.2.4

实测验证(用独立临时实例 wl-run-verify 挂到既有网络、映射空闲端口 8142,避免与 compose 栈冲突):

docker run -d --name wl-run-verify \
  --network wavelog-324-stack_wavelog-net \
  -e CI_ENV=docker \
  -v /opt/wavelog/data-run/config:/var/www/html/application/config/docker \
  -p 8142:80 \
  ghcr.io/wavelog/wavelog:3.2.4
83dbbef039b121907b32f11ff55bf279664c6f4c0dbbdf0d4e81eadf7053d00b
run exit=0
wl-run-verify  ghcr.io/wavelog/wavelog:3.2.4  Up 4 seconds  0.0.0.0:8142->80/tcp, [::]:8142->80/tcp

首次访问(空配置目录,应回到未安装态):

HTTP/1.1 302 Found
Date: Sun, 01 Nov 2026 10:35:02 GMT
Server: Apache/2.4.69 (Debian)
X-Powered-By: PHP/8.5.12
Location: /install/
Content-Type: text/html; charset=UTF-8
http_code=302

清理临时实例:

docker rm -f wl-run-verify
wl-run-verify
cleanup exit=0

解读:手工 run 与 compose 行为完全一致——同一镜像、同一挂载、同一网络语义;独立配置目录使实例回到 302 未安装态,反证「配置全在挂载目录、镜像本身无状态」。日常运维建议仍用 compose 管理(一条 up -d 收敛全部差异)。

十、常用运维命令

10.1 状态、日志、重启与下线

cd /opt/wavelog
docker compose ps            # 查看栈内实例状态
docker compose logs -f       # 跟踪日志
docker compose restart wavelog-main   # 只重启应用(改配置后常用)
docker compose down          # 停止并移除实例与网络(数据目录不受影响)

docker compose restart wavelog-main 实测回显:

 Container wavelog-324-main Restarting 
 Container wavelog-324-main Started 

重启后立即探测会因服务未就绪得到 http_code=000,稍候重试即恢复——重启竞态排障见十一、11.2:

root http_code=000 redirect=
root http_code=307 redirect=http://127.0.0.1:8137/user/login

docker compose down 实测回显(收工或迁移前操作):

 Container wavelog-324-main Stopping 
 Container wavelog-324-main Stopped 
 Container wavelog-324-main Removing 
 Container wavelog-324-main Removed 
 Container wavelog-324-db Stopping 
 Container wavelog-324-db Stopped 
 Container wavelog-324-db Removing 
 Container wavelog-324-db Removed 
 Network wavelog-324-stack_wavelog-net Removing 
 Network wavelog-324-stack_wavelog-net Removed

10.2 备份与恢复演练(实测)

数据库级全量备份用 MariaDB 客户端工具 mariadb-dump,在栈内对业务库导出:

mariadb-dump -h 10.89.59.10 -u wavelog -pq1w2e3r4 --single-transaction wavelog > backup-verify.sql

实测结果:

exit=0
-rw-r--r-- 1 root root 174102551 Nov  1 18:25 backup-verify.sql

备份文件头确认版本与目标库(head 节选):

/*M!999999\- enable the sandbox mode */ 
-- MariaDB dump 10.20-11.8.9-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost    Database: wavelog
-- ------------------------------------------------------
-- Server version	11.8.9-MariaDB-ubu2404

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8mb4 */;

恢复演练:把 dump 导入一个新库 wavelog_restore 验证可用性。用业务账号 wavelog 执行建库时实测报错(排障实录):

--------------
CREATE DATABASE IF NOT EXISTS wavelog_restore CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
--------------

ERROR 1044 (42000) at line 1: Access denied for user 'wavelog'@'%' to database 'wavelog_restore'
ERROR 1044 (42000): Access denied for user 'wavelog'@'%' to database 'wavelog_restore'
restore exit=1

定位:MARIADB_USER 预建的业务账号只被授予 wavelog.* 的权限,对新建库无 CREATE 权限——这是最小权限的正常表现,不是故障。解决:改用启动日志中的 root 随机口令执行恢复:

mariadb -h 10.89.59.10 -u root -p'&|YOKHf_Yw+9&W%}}XMD/~,V_$0FMOR2' < create_restore.sql
mariadb -h 10.89.59.10 -u root -p'&|YOKHf_Yw+9&W%}}XMD/~,V_$0FMOR2' wavelog_restore < backup-verify.sql

实测重跑回显:

create exit=0
restore exit=0

一致性对照(表数量与关键行数):

src_tables	54
restore_tables	54
src_qso	3
restore_qso	3
src_options	11
restore_options	11

54 张表、QSO 3 行、options 11 行全部对齐,备份可用。再给业务账号补授恢复库权限后复核:

54

业务账号可见表数同为 54,授权路径可行。演练完毕清理恢复库与临时授权:

cleanup exit=0

⚠️ 注意:生产环境请把「root 口令」收敛到仅运维可见的凭据管理,恢复操作二选一:用 root,或预先 GRANT CREATE 给备份专用账号。dump 文件本身含全部日志数据,落盘目录需权限管控。

10.3 升级与回滚

  • 升级:改 compose 中 ghcr.io/wavelog/wavelog:<新版本> → docker compose pull wavelog-main → docker compose up -d wavelog-main → 访问 http://127.0.0.1:8137/index.php/migrate 完成迁移(实测回显 {"status":"success","version":"307"},重复执行幂等);
  • 回滚:改回旧镜像 tag 重新 up -d 即可,配置与数据都在 bind mount 上;跨大版本回滚前先做 10.2 的数据库备份。

十一、常见问题

11.1 AH00558 ServerName 告警

现象:启动日志反复出现

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.89.59.20. Set the 'ServerName' directive globally to suppress this message

定位:镜像内 Apache 全局未设 ServerName,回退用实例 IP。影响:仅告警,不影响服务。解决:需要消音时把自定义 Apache 配置挂载进 /etc/apache2/conf-enabled/(内容一行 ServerName wavelog.example.com),或接受默认。

11.2 重启后立即探测 http_code=000

现象:docker compose restart wavelog-main 后立刻 curl 得到

root http_code=000 redirect=

定位:000 是 curl 连不上(Apache 尚未完成启动),属重启竞态而非服务异常。解决:等待 2–3 秒重试,实测第二次即恢复:

root http_code=307 redirect=http://127.0.0.1:8137/user/login

脚本化健康检查应带重试而非单次判定。

11.3 create_uring failed: falling back to libaio

现象:数据库启动日志

create_uring failed: falling back to libaio
2026-11-01  9:40:31 0 [Note] InnoDB: Using Linux native AIO

定位:InnoDB 优先尝试 io_uring 异步 IO,当前内核/环境不可用时自动回退 libaio。影响:无,属正常适配日志。解决:无需处理;若追求 io_uring 性能,需升级宿主内核并确认允许该调用。

11.4 端口已被占用(port is already allocated)

现象:等价 docker run 验证时首试映射 8138 端口失败:

docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint wl-run-verify2: Bind for 0.0.0.0:8138 failed: port is already allocated

定位:docker ps --format '{{.Names}} {{.Ports}}' 盘点发现 8138/8139 已被同机其他服务占用。解决:换空闲端口(实测 8142 可用)重跑即成功;部署前先用同样方式盘点端口,compose 与手工 run 同理。

11.5 恢复演练 ERROR 1044 建库被拒

见十、10.2 实录:业务账号无新库 CREATE 权限,用 root 执行恢复或预授权即可,非镜像缺陷。

11.6 302 到 /install/ 还是 303 到 /user/login?

未安装实例 302→/install/,安装完成上锁后 303→/user/login(两者实测回显见 4.4/4.6)。若已装好的实例突然回到 /install/,优先检查 data/config 挂载是否丢失(见八、注意)。

十二、参考链接

Wavelog 3.2.4 Docker Compose 部署指南 - Quzuo