Wallos 5.10.2 Docker Compose 部署指南

用 Docker Compose 部署 Wallos 5.10.2(bellamy/wallos 官方镜像):覆盖镜像选型、部署步骤、数据持久化、环境变量、PHP 配置挂载、等价 docker run 与常用运维命令,全程实测。

WallosWallos订阅计费PHP 应用自托管2026/10/25

Wallos 5.10.2 Docker Compose 部署指南

目标:用 Docker Compose 在服务器上一键部署 Wallos v5.10.2(官方镜像 bellamy/wallos),覆盖镜像选型、部署目录规划、数据持久化、环境变量、PHP 配置挂载、等价 docker run 写法与常用运维命令。已在 Ubuntu 22.04.5 LTS + Docker Engine 29.9.2 + Compose v5.6.1 实测通过(2026-10-25)。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • 系统架构:x86_64
  • Docker 版本:Docker Engine 29.9.2(含 Docker Compose v5.6.1 插件)
  • 镜像版本:bellamy/wallos:5.10.2(Digest sha256:8873c2328e745c7ca8ff0e0f5508215219ec5c02a3469c0d8049602be2a2bca3,镜像体积 293MB)
  • 镜像基底:Alpine Linux 3.24.3,内置 nginx 1.30.6 + PHP 8.3.36 + crond(定时任务已随镜像内置,无需手工配置)
  • Compose 项目名:wallos-5.10.2-stack
  • 容器名称:wallos-5.10.2-app
  • 端口映射:宿主机 8131 → 容器 80
  • 部署目录:/opt/lab/wallos-stack(含 docker-compose.yml、db/、logos/)
  • 数据库:SQLite 单文件,持久化在宿主机 /opt/lab/wallos-stack/db/wallos.db
  • 演示账号:admin / q1w2e3r4

二、镜像选型说明

Wallos 官方在 Docker Hub 维护唯一镜像仓库 bellamy/wallos,常用 tag 对照如下(查询日期 2026-10-25):

镜像 tag说明适用场景
bellamy/wallos:5.10.2固定版本 tag,内容不随时间变化生产环境锁定版本(本文采用)
bellamy/wallos:latest滚动指向最新稳定版体验新特性,但重启拉新可能被动升级
bellamy/wallos:<旧版本>历史版本 tag需要回退或复现旧环境

💡 技术拓展:Docker 镜像 tag 策略是「同一个仓库名 + 不同 tag」指向不同镜像快照。常见用法对比——

策略做法取舍
固定版本 tagbellamy/wallos:5.10.2可复现、可回退,升级需人工改 tag
latest 滚动bellamy/wallos:latest总能拿到最新,但两次部署结果可能不同
Digest 锁定bellamy/wallos@sha256:8873c2…最强不可变性,可读性差

本文采用固定版本 tag 5.10.2:既保证环境可复现,又比 digest 易读易维护。

关键差异解读:生产环境务必锁定具体版本号,避免 latest 在镜像更新后被动升级导致环境漂移;Wallos 升级时只需改 tag 后重新 up -d,启动脚本会自动执行数据库迁移(见"十、常用运维命令")。

三、前置条件

  • 已安装 Docker Engine 20.10+ 与 Docker Compose v2 插件。Ubuntu 22.04 安装 Docker 官方源的标准流程:
# 添加 Docker 官方 GPG key 与 apt 仓库
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker Engine 与 Compose 插件
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
  • 验证安装(实测回显):
docker --version

输出(实测):

Docker version 29.9.2, build a82e528
docker compose version

输出(实测):

Docker Compose version v5.6.1
  • 已规划部署目录(本文用 /opt/lab/wallos-stack)与宿主机端口(本文用 8131,确保未被占用)。
  • 服务器防火墙/安全组需放行宿主机 8131 端口(仅内网使用时可不放行公网)。

四、部署步骤

本节完成从创建目录到浏览器可访问的全流程,预期结果:docker compose ps 显示容器 healthy,浏览器打开 http://服务器IP:8131 出现 Wallos 注册页。

4.1 创建部署目录

sudo mkdir -p /opt/lab/wallos-stack
cd /opt/lab/wallos-stack

数据子目录 db/ 与 logos/ 无需手工创建,首次启动时由容器进程自动创建(见"五、数据持久化说明")。

4.2 编写 docker-compose.yml

将以下内容保存为 /opt/lab/wallos-stack/docker-compose.yml:

name: wallos-5.10.2-stack

services:
  wallos:
    container_name: wallos-5.10.2-app
    image: bellamy/wallos:5.10.2
    ports:
      - "8131:80/tcp"
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - './db:/var/www/html/db'
      - './logos:/var/www/html/images/uploads/logos'
    restart: unless-stopped

逐项说明:

  • name:Compose 项目名,决定网络等资源的命名前缀;不指定时默认取目录名。
  • container_name:固定容器名,方便 docker ps / docker logs 定位。
  • ports:左边 8131 是宿主机暴露端口(可改为任意空闲端口),右边 80 是容器内 nginx 监听端口(不可改)。
  • TZ:容器时区,影响定时任务执行时刻与页面显示的日期时间;建议与宿主机一致。
  • volumes:两个 bind mount 分别持久化 SQLite 数据库目录与上传的 Logo 目录,是数据不丢的关键(详见"五、数据持久化说明")。
  • restart: unless-stopped:容器异常退出或宿主机重启后自动拉起,除非被手工 stop。

4.3 拉取镜像并启动

cd /opt/lab/wallos-stack
docker compose pull

输出(实测):

5.10.2: Pulling from bellamy/wallos
Digest: sha256:8873c2328e745c7ca8ff0e0f5508215219ec5c02a3469c0d8049602be2a2bca3
Status: Image is up to date for bellamy/wallos:5.10.2
docker.io/bellamy/wallos:5.10.2

启动:

docker compose up -d

输出(实测):

 Network wallos-5102-stack_default Creating 
 Network wallos-5102-stack_default Created 
 Container wallos-5.10.2-app Creating 
 Container wallos-5.10.2-app Created 
 Container wallos-5.10.2-app Starting 
 Container wallos-5.10.2-app Started 

⚠️ 注意:Compose 会把项目名规范化用于资源命名(去掉点号),所以实际创建的网络名是 wallos-5102-stack_default,属正常现象。

4.4 验证部署

查看容器状态(镜像内置健康检查,约 20 秒启动期后显示 healthy):

docker compose ps

输出(实测):

NAME                IMAGE                   COMMAND                  SERVICE   CREATED          STATUS                    PORTS
wallos-5.10.2-app   bellamy/wallos:5.10.2   "dumb-init -- /var/w…"   wallos    34 seconds ago   Up 33 seconds (healthy)   9000/tcp, 0.0.0.0:8131->80/tcp, [::]:8131->80/tcp

验证健康检查端点:

curl -s http://127.0.0.1:8131/health.php

输出(实测):

OK

验证登录页可访问:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8131/login.php
curl -s http://127.0.0.1:8131/login.php | grep -o '<title>[^<]*</title>'

输出(实测):

200
<title>Wallos - Subscription Tracker</title>

HTTP 200 且页面标题正确,说明容器内 nginx + PHP-FPM 已正常解析 Wallos。

4.5 浏览器注册首个管理员账号

浏览器打开:

http://服务器IP:8131/registration.php

填写表单:用户名 admin、密码 q1w2e3r4、确认密码 q1w2e3r4、邮箱 admin@example.com(示例邮箱,生产环境替换为真实地址)。提交后系统自动完成数据库迁移并跳转登录页。

注册过程的容器日志(实测,含启动时自动执行的数据库检查与定时任务预跑):

Database already exist. Checking for upgrades...
Table 'notifications' already exists.
Column 'notify' already exists in table 'subscriptions'.
No migrations to run.

2026-10-25 09:01:36<br />
Asia/Shanghai<br />
Updated next payment dates
127.0.0.1 -  25/Oct/2026:09:01:39 +0800 "GET /health.php" 200
127.0.0.1 -  25/Oct/2026:09:02:00 +0800 "GET /index.php" 302
127.0.0.1 -  25/Oct/2026:09:02:00 +0800 "GET /registration.php" 200
127.0.0.1 -  25/Oct/2026:09:02:12 +0800 "POST /registration.php" 302
127.0.0.1 -  25/Oct/2026:09:02:12 +0800 "POST /login.php" 200
127.0.0.1 -  25/Oct/2026:09:02:12 +0800 "POST /login.php" 302
127.0.0.1 -  25/Oct/2026:09:02:12 +0800 "GET /about.php" 200

💡 说明:日志中的 Asia/Shanghai 即 TZ 环境变量生效的证据;Updated next payment dates 是启动脚本自动预跑一次「更新下次付款日期」任务的输出。镜像内已内置全部定时任务(由 crond 驱动),这是容器部署相对裸机部署最省心的一点——裸机部署需手工配置 crontab,详见《Ubuntu 22.04 安装 Wallos 5.10.2 指南》。

五、数据持久化说明

Wallos 的全部状态都在两个目录里,compose 文件已通过 bind mount 映射到宿主机:

宿主机目录(相对部署目录)容器内路径内容
./db/var/www/html/dbSQLite 数据库 wallos.db(全部业务数据)与 setup_token.db(备份恢复令牌)
./logos/var/www/html/images/uploads/logos上传的订阅 Logo 与用户头像(avatars/ 子目录自动创建)

首次启动后实测目录内容:

cd /opt/lab/wallos-stack
ls -la db/ logos/

输出(实测):

db/:
total 236
drwxr-xr-x    2 82       www-data      4096 Oct 25 01:26 .
drwxr-xr-x    4 root     root          4096 Oct 25 01:25 ..
-rwxr-xr-x    1 82       www-data        64 Oct 25 01:01 setup_token.db
-rwxr-xr-x    1 82       www-data    225280 Oct 25 01:26 wallos.db

logos/:
total 12
drwxr-xr-x    3 82       www-data      4096 Oct 25 01:01 .
drwxr-xr-x    4 root     root          4096 Oct 25 01:25 ..
drwxr-xr-x    2 82       www-data      4096 Oct 25 01:01 avatars

要点:

  • 属主显示 82:www-data 属正常:镜像基于 Alpine,内部 nginx/php-fpm 工作进程以 uid 82(www-data)运行,首次启动自动对挂载目录 chown,无需手工处理权限。
  • 删除容器不丢数据:docker compose down 只删容器与网络,./db 与 ./logos 仍在;compose 未声明匿名卷,down -v 也不会删 bind mount 目录。
  • 备份:直接打包宿主机目录即可,例如 tar czf wallos-backup-$(date +%F).tar.gz -C /opt/lab/wallos-stack db logos;恢复时把文件放回原路径后 docker compose up -d。

六、常用环境变量表

Wallos 实例级参数可通过环境变量声明式注入(compose 的 environment: 段)。注入后 Admin 管理页对应字段会变为只读,避免「数据库里一份、部署里一份」不一致。

环境变量对应配置说明
TZ容器时区建议与宿主机一致,如 Asia/Shanghai
WALLOS_SERVER_URL实例对外访问 URL邮件/通知里的链接基地址,如 https://wallos.example.com
WALLOS_SMTP_HOSTSMTP 服务器地址通知邮件发送通道
WALLOS_SMTP_PORTSMTP 端口1–65535,常见 465/587
WALLOS_SMTP_ENCRYPTIONSMTP 加密方式仅接受 none / tls / ssl
WALLOS_SMTP_USERNAMESMTP 用户名
WALLOS_SMTP_PASSWORDSMTP 密码支持 WALLOS_SMTP_PASSWORD_FILE 指向密码文件(文件内容优先于变量值)
WALLOS_SMTP_FROM发件人地址
SSRF_ALLOWLIST内网地址放行清单逗号分隔 host[:port],用于放行私有地址的 Webhook/SMTP/OIDC 回调;设置后整表覆盖管理页的安全设置
DEMO_MODE演示模式官方演示站用,自托管无需设置
OIDC_*单点登录系列共 16 个变量(OIDC_ENABLED、OIDC_CLIENT_ID、OIDC_CLIENT_SECRET、端点 URL 等),用于声明式配置 OIDC/OAuth 登录

取值优先级:<变量名>_FILE 文件内容 > 环境变量 > admin 表存储值。已在实测环境验证:设置 WALLOS_SMTP_HOST 等变量后,读取到的实例配置即被环境变量接管(完整机制与逐项参数说明见本专栏《Wallos 5.10.2 配置参数详解》篇)。

⚠️ 安全提醒:WALLOS_SMTP_PASSWORD、OIDC_CLIENT_SECRET 属敏感值,建议用 *_FILE 变体挂载文件注入,避免明文出现在 compose 文件与 docker inspect 输出里。

七、配置参数说明

Wallos 镜像没有 command 启动参数,运行行为由「环境变量(见六) + 管理页设置(存 SQLite)」共同决定。这里说明镜像级的两个关键运行配置。

1. 内置健康检查(镜像自带,无需在 compose 中声明):

docker inspect wallos-5.10.2-app --format '{{json .Config.Healthcheck}}'

输出(实测,JSON 已格式化展示):

{"Test":["CMD","curl","-fsS","http://127.0.0.1/health.php"],"Interval":120000000000,"Timeout":2000000000,"StartPeriod":20000000000,"StartInterval":5000000000,"Retries":3}

即:每 120 秒用 curl 请求容器内 /health.php,超时 2 秒,启动后 20 秒开始检查(启动期内每 5 秒一次),连续 3 次失败判定 unhealthy。docker compose ps 的 STATUS 列即由它驱动。若部署环境不需要健康检查,可在 compose 的 wallos 服务下显式禁用:

    healthcheck:
      test: ["NONE"]

2. 镜像内进程结构(了解它有助于看懂日志与排查问题):

docker exec wallos-5.10.2-app ps -ef

输出(实测):

PID   USER     TIME  COMMAND
    1 root      0:00 dumb-init -- /var/www/html/startup.sh
    7 root      0:00 {startup.sh} /bin/sh /var/www/html/startup.sh
   13 root      0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
   14 root      0:00 crond -f
   15 root      0:00 nginx: master process nginx -g daemon off;
   18 nginx     0:00 nginx: worker process
   19 www-data  0:00 php-fpm: pool www
   20 www-data  0:00 php-fpm: pool www

单容器内含完整运行时:dumb-init(1 号进程,负责信号转发)→ startup.sh(启动脚本,负责迁移检查与首次任务预跑)→ php-fpm + crond + nginx 三进程常驻。定时任务由镜像内置的 /etc/cron.d/cronjobs 驱动,无需任何额外配置。

八、配置文件挂载

Wallos 业务配置存于 SQLite(已随 ./db 持久化),需要额外挂载配置文件的场景是定制 PHP 运行参数(典型如调整上传大小限制)。镜像基于官方 PHP 镜像构建,加载 /usr/local/etc/php/conf.d/ 下全部 .ini,把自定义 ini 以 bind mount 挂进该目录即可。

镜像已自带一个上传参数文件(实测内容):

$ docker exec wallos-5.10.2-app cat /usr/local/etc/php/conf.d/wallos-uploads.ini
upload_max_filesize = 256M
post_max_size = 256M

⚠️ 注意:conf.d 目录按文件名字典序加载、后加载的覆盖先加载的。自定义文件若命名为 99-wallos.ini,会排在 wallos-uploads.ini 之前导致被镜像默认值覆盖;实测命名为 zz-wallos.ini 才能生效。

示例:把 PHP 上传上限收紧到 20M。

1)在部署目录创建 php.ini:

cd /opt/lab/wallos-stack
echo 'upload_max_filesize = 20M' > php.ini

2)在 compose 的 volumes: 段追加一行挂载(注意文件名前缀 zz-):

    volumes:
      - './db:/var/www/html/db'
      - './logos:/var/www/html/images/uploads/logos'
      - './php.ini:/usr/local/etc/php/conf.d/zz-wallos.ini'

3)重建容器并验证:

docker compose up -d
docker exec wallos-5.10.2-app php -r 'echo ini_get("upload_max_filesize"); echo PHP_EOL;'

输出(实测):

20M

修改该类配置后需 docker compose up -d 重建容器(bind mount 单文件变更不触发 PHP-FPM 重读,restart 亦可)。

九、等价 docker run 运行方式

不用 Compose 时,下列单条命令与"四、部署步骤"的 compose 配置完全等价:

docker run -d \
  --name wallos-5.10.2-app \
  -p 8131:80 \
  -e TZ=Asia/Shanghai \
  -v /opt/lab/wallos-stack/db:/var/www/html/db \
  -v /opt/lab/wallos-stack/logos:/var/www/html/images/uploads/logos \
  --restart unless-stopped \
  bellamy/wallos:5.10.2

参数对照:-p ↔ ports,-e ↔ environment,-v ↔ volumes,--restart ↔ restart。验证方式与 4.4 相同(curl http://127.0.0.1:8131/health.php 返回 OK)。日常更推荐 Compose:配置即代码、可进 git 版本管理,升级与改参不易出错。

十、常用运维命令

以下命令均在部署目录 /opt/lab/wallos-stack 下执行。

查看状态与日志:

docker compose ps                 # 容器状态(含 healthy)
docker compose logs -f            # 跟踪应用日志(nginx 访问日志 + cron 输出)
docker compose logs --tail=5      # 只看最近 5 行

docker compose logs --tail=5 输出(实测):

wallos-5.10.2-app  | 2026-10-25 09:30:21<br />
wallos-5.10.2-app  | Asia/Shanghai<br />
wallos-5.10.2-app  | Updated next payment dates
wallos-5.10.2-app  | 2026-10-25 09:30:21<br />
wallos-5.10.2-app  | 127.0.0.1 -  25/Oct/2026:09:30:25 +0800 "GET /health.php" 200

重启与进入容器排障:

docker compose restart            # 重启(改 PHP ini 后用)
docker exec -it wallos-5.10.2-app sh   # 进入容器 shell(镜像为 Alpine,无 bash)

升级到新版本(以 5.10.2 → 后续新版本为例,改 tag 后两行命令):

# 1. 编辑 docker-compose.yml,把 image 改为新版本 tag
docker compose pull
docker compose up -d

启动脚本会自动检查并执行数据库迁移(日志出现 Checking for upgrades... / No migrations to run.),升级后无需手工跑迁移。

备份与恢复:

# 备份:打包宿主机数据目录
tar czf wallos-backup-$(date +%F).tar.gz -C /opt/lab/wallos-stack db logos

# 恢复:把备份文件解回部署目录后重启
tar xzf wallos-backup-2026-10-25.tar.gz -C /opt/lab/wallos-stack
docker compose restart

停止与彻底清理:

docker compose down               # 停止并删除容器/网络,数据目录保留

十一、常见问题(FAQ)

11.1 启动报端口被占用?

宿主机 8131 已被其他进程占用。改 compose 里 ports 左边的宿主机端口(如 "8132:80/tcp"),docker compose up -d 重建即可;容器内的 80 不可改。

11.2 数据目录属主显示 82:www-data,需要改成宿主机用户吗?

不需要。镜像内 nginx/php-fpm 工作进程以 uid 82(Alpine 的 www-data)运行,属主为 82 正是进程可读写的前提。手工 chown 成宿主机用户反而会导致写库失败。

11.3 忘记管理员密码怎么办?

优先走登录页「忘记密码」邮件重置(需已配置 SMTP)。未配置 SMTP 时,可直接改库重置(以重置 admin 为 q1w2e3r4 为例,实测通过):

# 1. 生成 PHP password_hash 格式的哈希(每次输出不同)
HASH=$(docker exec wallos-5.10.2-app php -r 'echo password_hash("q1w2e3r4", PASSWORD_DEFAULT);')

# 2. 用预编译语句更新 admin 记录(避免哈希中 $ / . 字符的引号转义问题)
docker exec wallos-5.10.2-app php -r '$db=new SQLite3("/var/www/html/db/wallos.db"); $stmt=$db->prepare("UPDATE user SET password=:p WHERE username=:u"); $stmt->bindValue(":p",$argv[1]); $stmt->bindValue(":u",$argv[2]); $stmt->execute(); echo "done, rows=".$db->changes().PHP_EOL;' "$HASH" admin

输出(实测):

done, rows=1

11.4 上传 Logo/头像有大小限制吗?

PHP 层默认 upload_max_filesize = 256M、post_max_size = 256M(镜像内置 wallos-uploads.ini),日常 Logo 图片远不会触限。如需收紧或放宽,按"八、配置文件挂载"挂载 zz- 前缀的 ini 覆盖。

11.5 docker compose ps 一直显示 health: starting?

健康检查有 20 秒启动期(start-period),启动期内显示 health: starting 属正常,约 20–30 秒后变为 healthy。长时间不变化时 docker compose logs 查看是否有 PHP 报错。

11.6 升级到新版后数据会丢吗?需要手工迁移吗?

不会丢(数据在宿主机 bind mount 目录);也不需要手工迁移——启动脚本每次启动都会检查库版本并自动执行迁移脚本。建议升级前先按"十、常用运维命令"做一次备份。

十二、参考链接