OpenBudgeteer Docker Compose 部署指南
OpenBudgeteer 1.11.2 Docker Compose 从零部署实战:Web+API+MariaDB+Redis 四服务编排、首次启动日志、持久化与备份、升级与常见问题排障,全部命令与回显实测(2026-10-24)。
OpenBudgeteer Docker Compose 部署指南
目标:在一台 Ubuntu 22.04 服务器上,用 Docker Compose 从零部署 OpenBudgeteer 1.11.2(Web 前端 + MariaDB + Redis + 可选 API 服务),完成启动、验证、数据持久化、备份与升级全流程。本文全部命令与回显在 Docker 29.8.1 + Compose v5.5.1 环境实测通过(2026-10-24)。
一、环境信息
- 操作系统:Ubuntu 22.04(x86_64)
- Docker:29.8.1(
docker version实测:Docker 29.8.1 (api 1.56)) - Docker Compose:v5.5.1(
docker compose version实测:Docker Compose version v5.5.1) - OpenBudgeteer:1.11.2(镜像
axelander/openbudgeteer:1.11.2,2026-10-23 发布,为当前最新稳定版) - API 镜像:
axelander/openbudgeteer-api:latest(与 1.11.2 同日更新;该镜像只有latest与pre-release两个标签) - 依赖服务:MariaDB 11.8(
mariadb:11.8)、Redis 8.2(redis:8.2) - 部署目录:
/opt/openbudgeteer/ - 端口规划:Web
8080(应用内置监听 8080)、API8082 - 数据库依赖链:MariaDB/MySQL 或 PostgreSQL 二选一 + Redis 强制(v1.10 起 Redis 为必需组件;SQLite 已在 v1.8.3 被移除,官方 Install 页 "Database & Redis" 一节明确 "OpenBudgeteer requires a connection to a database and to Redis")
二、镜像选型说明
OpenBudgeteer 官方只通过 Docker Hub 分发预构建镜像,无发行版软件包。选型对照(Docker Hub 2026-10-24 实查):
| 镜像 | 标签 | 用途 | 说明 |
|---|---|---|---|
axelander/openbudgeteer | 1.11.2 | Web 前端(推荐) | 按版本锁定的稳定标签,生产环境首选 |
axelander/openbudgeteer | latest | Web 前端 | 跟随最新稳定版,官方 Quick Start 使用 |
axelander/openbudgeteer | pre-release | Web 前端 | 预发布尝鲜,官方文档注明 "can contain bugs on web frontend and also on database side" |
axelander/openbudgeteer-api | latest / pre-release | REST API 服务 | 无版本号标签,与主镜像同期更新 |
镜像体积:主镜像压缩层约 94.2 MB(解压后约 347 MB),API 镜像约 66.3 MB(解压后约 226 MB),均基于 ASP.NET 运行时。主镜像内置声明端口 8080(当前监听端口,.NET 8 默认)与 8081(历史版本默认端口,仅作兼容声明,无需映射)。
选择建议:生产环境用 1.11.2 这样的版本标签锁定,升级时显式改标签;体验新功能再考虑 pre-release。不要混用 latest 与 pre-release——pre-release 可能包含数据库 schema 变更,回退有风险。
三、前置条件
- 服务器已安装 Docker Engine 24+ 与 Docker Compose v2 插件(
docker compose version可执行); - 服务器可访问 Docker Hub 拉取镜像(内网环境需预先导入镜像或配置镜像加速);
- 端口 8080(Web)、8082(API,可选)未被占用,检查命令与实测回显:
ss -ltn | grep -E ':(8080|8082)\b'
无输出即表示两个端口均空闲(本文实测环境该命令无输出)。
- 磁盘空间 ≥ 1 GB(镜像约 600 MB + 数据库数据);
- 若使用外部已有 MariaDB/PostgreSQL 与 Redis,可省略下文对应的 service,只保留应用容器并指向外部地址。
四、部署步骤
4.1 准备部署目录与 Compose 文件
创建部署目录并写入 docker-compose.yml。以下配置在官方 Quick Start(MariaDB + Redis 组合)基础上做了三点工程化补强:显式 Compose 项目名(避免与其他项目同名冲突)、固定版本标签、API 服务一起部署:
mkdir -p /opt/openbudgeteer && cd /opt/openbudgeteer
# /opt/openbudgeteer/docker-compose.yml
name: openbudgeteer-1.11.2-stack
services:
openbudgeteer:
image: axelander/openbudgeteer:1.11.2
container_name: openbudgeteer
ports:
- "8080:8080"
environment:
- CONNECTION_PROVIDER=mariadb
- CONNECTION_SERVER=openbudgeteer-mariadb
- CONNECTION_PORT=3306
- CONNECTION_DATABASE=openbudgeteer
- CONNECTION_USER=openbudgeteer
- CONNECTION_PASSWORD=q1w2e3r4
- CONNECTION_ROOT_PASSWORD=q1w2e3r4
- CONNECTION_REDIS_SERVER=openbudgeteer-redis
- APPSETTINGS_CULTURE=en-US
- APPSETTINGS_DEMO_DATA=true
depends_on:
- mariadb
- redis
openbudgeteer-api:
image: axelander/openbudgeteer-api:latest
container_name: openbudgeteer-api
ports:
- "8082:8080"
environment:
- CONNECTION_PROVIDER=mariadb
- CONNECTION_SERVER=openbudgeteer-mariadb
- CONNECTION_PORT=3306
- CONNECTION_DATABASE=openbudgeteer
- CONNECTION_USER=openbudgeteer
- CONNECTION_PASSWORD=q1w2e3r4
depends_on:
- mariadb
mariadb:
image: mariadb:11.8
container_name: openbudgeteer-mariadb
environment:
MYSQL_ROOT_PASSWORD: q1w2e3r4
MYSQL_DATABASE: openbudgeteer
MYSQL_USER: openbudgeteer
MYSQL_PASSWORD: q1w2e3r4
volumes:
- db-data:/var/lib/mysql
redis:
image: redis:8.2
container_name: openbudgeteer-redis
volumes:
- redis-data:/data
volumes:
db-data:
redis-data:
⚠️ 注意:
CONNECTION_ROOT_PASSWORD仅在"数据库用户与库尚不存在、需要 OpenBudgeteer 自行创建"时才需要(首次启动后可移除)。本文同时预置了MYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD让 MariaDB 镜像建库,两种方式二选一即可;同时存在时以 MariaDB 镜像的初始化为准,OpenBudgeteer 直接使用已存在的库。
配置逐项说明:
name: openbudgeteer-1.11.2-stack:Compose 项目名,显式指定可避免多套部署同名互相干扰;CONNECTION_PROVIDER=mariadb:数据库类型,大小写不敏感,可选mysql/mariadb/postgres/postgresql;CONNECTION_SERVER=openbudgeteer-mariadb:数据库主机名,必须是同一 Compose 网络内可达的服务名(见"十一、常见问题"第 1 条,这是最容易踩的坑);APPSETTINGS_DEMO_DATA=true:首次启动灌入演示数据(账户、桶、交易),方便部署后立即看到界面效果;正式使用改为false并清空数据库重建;APPSETTINGS_CULTURE=en-US:货币/日期/数字格式,可改zh-CN;- API 服务与前端的数据库四要素(provider/server/database/user/password)必须完全一致,因为两者操作同一个库。
4.2 启动
cd /opt/openbudgeteer
docker compose up -d
实测回显(首次启动,镜像已拉取完毕后):
Container openbudgeteer-redis Starting
Container openbudgeteer-mariadb Starting
Container openbudgeteer-redis Started
Container openbudgeteer-mariadb Started
Container openbudgeteer-web Starting
Container openbudgeteer-api Starting
Container openbudgeteer-web Started
Container openbudgeteer-api Started
首次启动会先拉取镜像,docker compose up -d 的输出会包含 Pulling openbudgeteer ... Pulled 等进度行,整体耗时取决于带宽(四个镜像合计约 160 MB 压缩层)。
4.3 首次启动日志
应用启动分"等待依赖 → 自动建表 → 开始监听"三个阶段,docker compose logs openbudgeteer 实测回显:
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
Storing keys in a directory '/home/app/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to https://aka.ms/aspnet/dataprotectionwarning
Waiting for database.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
No XML encryptor configured. Key {640f7d3d-f54e-433b-82b4-93ecf935b113} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://[::]:8080
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /app
两处 warn 属正常现象:DataProtection 密钥默认存放在容器内 /home/app/.aspnet/DataProtection-Keys,重建容器后 Blazor 的页面状态加密会失效,但不影响业务数据(业务数据在 MariaDB);若介意可挂载该目录持久化。
若日志持续出现 Waiting for Redis database. 或 Waiting for database. 而不进入监听阶段,说明 Redis 或数据库不可达,排查方法见"十一、常见问题"。
4.4 验证部署
依次验证容器状态、HTTP 可达性、版本号与数据库表结构:
docker compose ps
实测回显(服务状态):
SERVICE STATUS
openbudgeteer-api Up 2 minutes
mariadb Up 2 minutes
redis Up 2 minutes
openbudgeteer Up 2 minutes
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/
实测回显:
200
curl -s http://localhost:8080/info | grep -oE 'Version: [0-9.]+'
实测回显(Info 页头部渲染的版本串):
Version: 1.11.2
验证数据库自动建表(12 张业务表 + 1 张 EF Core 迁移记录表):
docker compose exec mariadb mariadb -uopenbudgeteer -pq1w2e3r4 openbudgeteer -e 'SHOW TABLES;'
实测回显:
Tables_in_openbudgeteer
Account
BankTransaction
Bucket
BucketGroup
BucketMovement
BucketRuleSet
BucketVersion
BudgetedTransaction
ImportProfile
MappingRule
RecurringBankTransaction
__EFMigrationsHistory
浏览器访问 http://<服务器IP>:8080 即可使用(APPSETTINGS_DEMO_DATA=true 时首页已能看到 Checking account / Savings account 两张演示账户卡片)。API 服务的验证方式与端点清单见《OpenBudgeteer 1.11.2 API 使用详解》。
五、数据持久化说明
- 业务数据(账户/交易/桶/规则/导入配置):全部存放在 MariaDB 的
openbudgeteer库,经db-data卷持久化(容器内路径/var/lib/mysql)。这是唯一需要认真备份的数据; - UI 设置(配色主题等):存 Redis,经
redis-data卷持久化(容器内路径/data),丢失的后果仅是主题重置; - DataProtection 密钥:默认在容器内
/home/app/.aspnet/DataProtection-Keys,未挂载时随容器重建而丢失(见 4.3 的 warn 日志)。
持久化验证实测:docker compose down(保留卷)后重新 docker compose up -d,Account 页面数据原样保留(Checking account Balance: $1,255.70、Savings account Balance: $1,500.00),版本号与建表结构不变。
六、环境变量表
OpenBudgeteer 应用容器可识别的全部环境变量如下(官方 Configuration 页 2026-10-24 版本,含实测确认的默认值)。
数据库连接(CONNECTION_*):
| 变量 | 说明 | 默认值(MySQL/MariaDB) | 默认值(PostgreSQL) |
|---|---|---|---|
CONNECTION_PROVIDER | 数据库类型(必填,大小写不敏感) | — | — |
CONNECTION_SERVER | 数据库地址(IP/FQDN) | localhost | localhost |
CONNECTION_PORT | 数据库端口 | 3306 | 5432 |
CONNECTION_DATABASE | 库名(≤64 字符) | openbudgeteer | postgres |
CONNECTION_USER | 数据库用户 | openbudgeteer | postgres |
CONNECTION_PASSWORD | 数据库密码 | 空 | 空 |
CONNECTION_ROOT_PASSWORD | root 密码(仅 MySQL/MariaDB,用于首次自动建库建用户) | 空 | 不适用 |
Redis 连接(v1.10 起必需):
| 变量 | 说明 | 默认值 |
|---|---|---|
CONNECTION_REDIS_SERVER | Redis 地址 | — |
CONNECTION_REDIS_PORT | Redis 端口 | 6379 |
CONNECTION_REDIS_USER | Redis 用户(使用 ACL 时) | — |
CONNECTION_REDIS_PASSWORD | Redis 密码(使用 ACL 时) | — |
CONNECTION_REDIS_PREFIX | Redis 键前缀(使用 ACL 时) | — |
应用设置(APPSETTINGS_*):
| 变量 | 说明 | 默认值 |
|---|---|---|
APPSETTINGS_CULTURE | 本地化标识(BCP 47),控制货币/日期/数字格式 | en-US |
APPSETTINGS_DEMO_DATA | 是否生成演示数据集 | false |
关键解读:CONNECTION_PROVIDER 与 CONNECTION_REDIS_* 是两组最常被漏配的变量——前者配错直接启动失败,后者缺失会让应用停在 Waiting for Redis database.;APPSETTINGS_* 前缀是应用自身设置的统一命名空间,后续版本扩展的新设置项也会沿用该前缀。各变量取值细节与自动建库机制逐项实测见《OpenBudgeteer 1.11.2 配置参数详解》。
七、配置参数说明
- 数据库初始化:应用首次启动自动建表、后续升级自动执行 schema 迁移(
__EFMigrationsHistory表记录迁移版本)。若让应用自建库(CONNECTION_ROOT_PASSWORD方式),实测会创建同名库openbudgeteer与用户openbudgeteer@%,并授予GRANT ALL PRIVILEGES ON openbudgeteer.*; - PostgreSQL 变体:把
CONNECTION_PROVIDER改为postgres(或postgresql),端口5432,并按"容器即数据库"模式由 PostgreSQL 镜像的POSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DB初始化角色与空库;库名字符集限制 MySQL 系比 PostgreSQL 多一项约束(-不允许用于 PostgreSQL); - Redis ACL:启用鉴权时四个 Redis 变量都要配,官方给出的 ACL 文件示例为:
user openbudgeteer-redis +@all -@dangerous +info ~openbudgeteer:* on >openbudgeteer-redis-pw
即限定用户只能操作 openbudgeteer:* 前缀的键——因此配了 ACL 时 CONNECTION_REDIS_PREFIX 必须与键模式一致(示例中为 openbudgeteer)。
八、配置文件挂载
OpenBudgeteer 支持两种等价的配置方式:环境变量(上文)与 .env 文件。官方 Configuration 页原文:"Settings can be defined via Docker environment variables or via .env file which needs to be located in the root folder of the application"——即 .env 放在应用运行目录(镜像内为 /app,与 Info 页第三方依赖清单中的 dotnet-env 库对应)。
.env 文件格式为 KEY=VALUE 每行一条,例如:
CONNECTION_PROVIDER=mariadb
CONNECTION_SERVER=192.168.1.100
CONNECTION_PORT=3306
CONNECTION_DATABASE=openbudgeteer
CONNECTION_USER=openbudgeteer
CONNECTION_PASSWORD=q1w2e3r4
源码部署(非镜像)时 .env 用法最常见;镜像部署时建议仍以 Compose 的 environment: 为准,environment: 与 .env 并存时需自行确认优先级,避免两处配置漂移。
九、等价 docker run
不使用 Compose 时,等价的单容器启动命令(假设 MariaDB 与 Redis 已独立运行于同一自定义网络 openbudgeteer-net):
docker network create openbudgeteer-net
docker run -d --name openbudgeteer \
--network openbudgeteer-net \
-p 8080:8080 \
-e CONNECTION_PROVIDER=mariadb \
-e CONNECTION_SERVER=192.168.1.100 \
-e CONNECTION_PORT=3306 \
-e CONNECTION_DATABASE=openbudgeteer \
-e CONNECTION_USER=openbudgeteer \
-e CONNECTION_PASSWORD=q1w2e3r4 \
-e CONNECTION_REDIS_SERVER=192.168.1.101 \
-e APPSETTINGS_CULTURE=en-US \
axelander/openbudgeteer:1.11.2
等价 API 容器:
docker run -d --name openbudgeteer-api \
--network openbudgeteer-net \
-p 8082:8080 \
-e CONNECTION_PROVIDER=mariadb \
-e CONNECTION_SERVER=192.168.1.100 \
-e CONNECTION_PORT=3306 \
-e CONNECTION_DATABASE=openbudgeteer \
-e CONNECTION_USER=openbudgeteer \
-e CONNECTION_PASSWORD=q1w2e3r4 \
axelander/openbudgeteer-api:latest
注意 CONNECTION_SERVER 此时指向外部数据库的真实 IP/FQDN(容器网络内的服务名仅在 Compose 编排下有效)。
十、常用运维命令
以下命令均在 /opt/openbudgeteer 目录下执行。
启停与状态:
docker compose ps # 查看四个服务状态
docker compose stop # 全部停止(保留容器与卷)
docker compose start # 全部启动
docker compose restart # 重启全部服务
docker compose down # 停止并删除容器与网络(保留数据卷)
docker compose down -v # 连同数据卷一起删除(危险,业务数据将丢失)
日志排查:
docker compose logs openbudgeteer # Web 前端日志(启动/运行期)
docker compose logs openbudgeteer-api # API 服务日志
docker compose logs -f openbudgeteer # 持续跟踪
备份业务数据(实测 mariadb-dump 全库导出约 500 行、覆盖全部 12 张表):
docker compose exec mariadb mariadb-dump -uopenbudgeteer -pq1w2e3r4 openbudgeteer > openbudgeteer-backup.sql
实测回显(文件头):
/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.20-11.8.9-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: openbudgeteer
-- ------------------------------------------------------
-- Server version 11.8.9-MariaDB-ubu2404
恢复:
docker compose exec -T mariadb mariadb -uopenbudgeteer -pq1w2e3r4 openbudgeteer < openbudgeteer-backup.sql
升级流程(跨小版本前先读官方 Releases 页的 Breaking Changes):
# 1. 备份(见上)
# 2. 修改 docker-compose.yml 中的镜像标签,如 1.11.2 -> 下一版本
# 3. 拉取新镜像并滚动重建
docker compose pull
docker compose up -d
# 4. 观察启动日志确认数据库迁移自动完成,再验证 /info 页版本串
schema 迁移无需手工干预:官方 Config 页明确 "Database schema changes after an update will be also applied automatically",__EFMigrationsHistory 表即迁移记录。
卸载:
docker compose down -v # 删除容器、网络与数据卷
rm -rf /opt/openbudgeteer # 删除部署目录
十一、常见问题
Q1:日志一直刷 Waiting for Redis database. 不启动?
原因:CONNECTION_REDIS_SERVER 指向的主机名在 Compose 网络内不可达(本文实测踩坑:写成 openbudgeteer-redis 而实际服务名/容器名不匹配时,应用会无限重试)。定位方法:进应用容器确认解析与连通性——
docker compose exec openbudgeteer getent hosts openbudgeteer-redis
无输出即解析失败。修正 CONNECTION_REDIS_SERVER 为 docker compose ps 里显示的服务名,重新 docker compose up -d(改过 environment 需 --force-recreate)。
Q2:日志卡在 Waiting for database.?
同样是连接问题:数据库容器未就绪、CONNECTION_SERVER 拼写错误、或用户/密码与数据库实际授权不符。先 docker compose logs mariadb 确认数据库自身就绪(mariadbd 正常启动),再核对四要素。注意 depends_on 只保证启动顺序,不保证数据库完成初始化,应用的重试机制会自动等待。
Q3:访问 8081 端口不通?
镜像元数据同时声明了 8080 与 8081 两个端口,但当前版本应用实际监听 8080——v1.8 官方 Release Notes 明确 "Docker Image now listens on port 8080 (new .Net 8 default)"。8081 是镜像遗留的声明端口,并无服务监听,映射 8080:8080 即可,无需映射 8081。
Q4:演示数据能删吗?
能。演示数据(APPSETTINGS_DEMO_DATA=true 生成)就是普通业务数据。正式启用前推荐:备份数据库 → docker compose down → 清空 db-data 卷(docker volume rm)→ 把 APPSETTINGS_DEMO_DATA 改为 false → 重新 up -d,得到干净的空库。
Q5:pre-release 镜像能直接升级覆盖正式数据吗?
不建议。官方 Install 页明确 pre-release "can contain bugs on web frontend and also on database side",即数据库 schema 也可能处于过渡状态,一旦自动迁移执行、回退旧版可能失败。尝鲜请用独立数据库实例。
十二、参考链接
- 官方 Quick Start:https://theaxelander.github.io/latest/quick-start/
- 官方 Install 文档:https://theaxelander.github.io/latest/install/
- 官方 Configuration 文档:https://theaxelander.github.io/latest/config/
- Docker Hub:https://hub.docker.com/r/axelander/openbudgeteer
- GitHub Releases(升级前必读 Breaking Changes):https://github.com/TheAxelander/OpenBudgeteer/releases
- 站内延伸:《OpenBudgeteer 1.11.2 介绍与选型指南》、《OpenBudgeteer 1.11.2 配置参数详解》、《OpenBudgeteer 1.11.2 API 使用详解》