Kresus 0.26.0 Docker Compose 部署指南

Kresus 0.26.0 从零部署实录:官方制品 bnjbvr/kresus:0.26.0 与 PostgreSQL 16 的 Docker Compose 编排、启动日志逐段解析、三处数据持久化与销毁重建恢复闭环、环境变量表与等价 docker run、常见问题排查,全部命令与回显实测。

KresusKresus财务记账自托管2026/10/24

Kresus 0.26.0 Docker Compose 部署指南

目标:在真实 Linux 服务器上以 Docker Compose 从零部署 Kresus 0.26.0 个人财务管理系统,包含官方推荐的 PostgreSQL 数据库与内置 Woob 银行同步环境,覆盖启动验证、数据持久化、销毁重建后的数据恢复闭环与常用运维操作。已在 Ubuntu 22.04.4 LTS(内核 6.8)+ Docker 29.8.1 + Compose v5.5.1 环境实测通过,Kresus 运行版本 0.26.0、Woob 3.7、PostgreSQL 16。

一、环境信息

本文所有命令与回显均在以下环境实测采集:

  • 操作系统:Ubuntu 22.04.4 LTS(内核 6.8.0-138-generic,x86_64)
  • Docker:29.8.1;Docker Compose:v5.5.1
  • Kresus:0.26.0(官方制品 bnjbvr/kresus:0.26.0,Docker Hub 构建时间 2026-10-22)
  • 数据库:PostgreSQL 16(postgres:16-alpine)
  • 银行同步引擎:Woob 3.7(制品内置,启动时自动升级,Python 3.11.2 运行时)
  • Node.js 运行时:v24.22.1(制品内置)
  • 规划端口:宿主机 8146 → Kresus 9876(9876 为 Kresus 默认端口)
  • 部署目录:/opt/kresus/(本文示例根目录,含 compose 编排与持久化数据)
  • 内部网络:kresus-net(10.89.67.0/24,桥接)

二、镜像选型说明

Kresus 官方在 Docker Hub 维护制品仓库 bnjbvr/kresus(以原作者 Benjamin Bouvier 的用户名命名),本文选型基于以下实查与考量:

候选结论理由
bnjbvr/kresus:0.26.0采用与当前最新稳定版 GitHub Release 同步的版本化制品(2026-10-22 构建,Docker Hub API 实查);内置完整 Woob 及其 Python 依赖链,开箱即用
bnjbvr/kresus:latest不采用指向随时间漂移的最新构建,不利于版本固定与回滚
自行构建(support/docker/Dockerfile-stable)备选官方仓库提供构建定义,基于 node:24,仅在需要定制时使用

⚠️ 注意一个官方设计带来的重要事实:官方入口脚本(entrypoint.sh)在每次启动时都会执行两步升级——pip install -U woob(升级 Woob 与银行模块)与 yarn global upgrade kresus --prefix /home/user/app(升级 Kresus 本体到 npm 上的最新版)。因此即使制品标签固定为 0.26.0,实例在启动联网后也会自动演进到 npm 上的最新发布版(本次实测启动日志显示升级目标即为 kresus@0.26.0)。若你的实例运行一段时间后行为变化,首先排查这条自动升级机制;要做到完全版本锁定,需在离线环境运行或自行修改入口脚本。

数据库选型上,官方管理文档明确「唯一兼容且适合生产的是 PostgreSQL」,SQLite 因迁移支持不佳仅建议开发用途(官方文档原文:It is highly recommended to avoid sqlite in production),本文按官方推荐配置 PostgreSQL 16。

💡 技术拓展:Kresus 这类「应用 + 数据库」双服务编排中,两个服务间的依赖等待有三种常见写法——

写法原理适用
depends_on 短格式只保证启动顺序,不等待就绪数据库无健康检查时
depends_on + condition: service_healthy等待健康检查通过后才启动应用本文采用,PostgreSQL 用 pg_isready 做健康检查
应用侧重试循环应用启动失败后由重启策略拉起重试无健康检查能力的老应用

本文采用 service_healthy:Kresus 首次启动要跑数据库迁移,若 PostgreSQL 未就绪会直接报连接错误退出。

三、前置条件

  1. 服务器已安装 Docker 24+ 与 Compose v2+(本文实测 29.8.1 / v5.5.1),验证命令:
docker --version && docker compose version

实测回显:

Docker version 29.8.1, build 4a63305
Docker Compose version v5.5.1
  1. 服务器可访问外网(首次启动需联网升级 Woob 与 Kresus 依赖,并拉取制品);若在受限网络,为 Docker 守护进程配置 HTTP 代理后 docker pull 可正常拉取。
  2. 宿主机端口 8146 空闲(可按需更换,映射目标固定为 9876):
ss -ltn | grep 8146 || echo "8146 free"

实测回显:

8146 free
  1. 创建部署目录:
mkdir -p /opt/kresus/{data,woob,pgdata}
cd /opt/kresus

四、部署步骤

4.1 编写 docker-compose.yml

在 /opt/kresus/docker-compose.yml 写入以下内容(本项目名 kresus-0.26.0-stack 已在文件内显式声明,避免与服务器上其他 Compose 项目同名冲突):

name: kresus-0.26.0-stack

services:
  kresus:
    image: bnjbvr/kresus:0.26.0
    container_name: kresus-0.26.0-app
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      - LOCAL_USER_ID=9001
      - KRESUS_DB_TYPE=postgres
      - KRESUS_DB_HOST=postgres
      - KRESUS_DB_PORT=5432
      - KRESUS_DB_USERNAME=kresus
      - KRESUS_DB_PASSWORD=q1w2e3r4
      - KRESUS_DB_NAME=kresus
    ports:
      - "8146:9876"
    volumes:
      - ./data:/home/user/data
      - ./woob:/woob
      - ./config.ini:/opt/config.ini
    networks:
      - kresus-net

  postgres:
    image: postgres:16-alpine
    container_name: kresus-0.26.0-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=kresus
      - POSTGRES_PASSWORD=q1w2e3r4
      - POSTGRES_DB=kresus
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kresus"]
      interval: 5s
      timeout: 5s
      retries: 10
    networks:
      - kresus-net

networks:
  kresus-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.67.0/24

关键项说明:

  • name: kresus-0.26.0-stack:Compose 项目名显式固定,down/up 只作用于本项目;
  • LOCAL_USER_ID=9001:制品内运行身份的 UID,默认即 9001;改为服务器上已有用户的 UID 可实现宿主机文件权限对齐(入口脚本会 usermod 调整内置 user 的 UID);
  • KRESUS_DB_* 六项:数据库连接配置,与 4.2 节 config.ini 二选一或同时存在(环境变量优先级更高,官方文档明确「每个配置项都有对应环境变量,定义后将覆盖 INI 文件值」);
  • ./data:/home/user/data:Kresus 数据目录(日志、Woob 数据等),必须持久化;
  • ./woob:/woob:Woob 本地克隆目录(可选挂载,便于在宿主机侧查看/维护模块源);
  • ./config.ini:/opt/config.ini:Kresus 配置文件;
  • 端口映射 8146:9876:生产环境若经反向代理转发,建议改为 127.0.0.1:8146:9876 只监听本机回环(官方文档同样建议)。

4.2 编写 config.ini

创建 /opt/kresus/config.ini(完整参数逐项解释见《Kresus 0.26.0 配置参数详解》;最小可运行配置如下,数据库段与 4.1 环境变量保持一致):

[kresus]
datadir=
userid=
port=
host=
server_timeout=300
python_exec=python3
url_prefix=
salt=
force_demo_mode=
auth=

[woob]
srcdir=
sources_list=

[email]
transport=

[notifications]
appriseApiBaseUrl=

[logs]
log_file=

[db]
type=postgres
log=error
host=postgres
port=5432
username=kresus
password=q1w2e3r4
name=kresus

⚠️ 安全机制:生产模式(NODE_ENV=production,制品默认)下,Kresus 会检查 config.ini 的文件权限——只允许属主读写/属组可读,权限过宽将拒绝启动并提示用 chmod 收紧。挂载前先收紧权限:

chmod 600 /opt/kresus/config.ini

实测确认(启动后进入运行环境查看权限,入口脚本亦会强制 600):

# ls -l /opt/config.ini
-rw------- 1 user user 1150 Oct 23 18:01 /opt/config.ini

4.3 拉取制品并启动

cd /opt/kresus
docker compose pull
docker compose up -d

实测回显(up -d 输出):

[+] Running 22/22
 ✔ kresus Pulled                                          108.6s
 ✔ Network kresus-0260-stack_kresus-net     Created         0.1s
 ✔ Container kresus-0.26.0-db               Healthy        12.5s
 ✔ Container kresus-0.26.0-app              Started        12.7s

docker compose ps 确认两服务状态:

NAME                IMAGE                   COMMAND                  SERVICE    CREATED          STATUS                    PORTS
kresus-0.26.0-app   bnjbvr/kresus:0.26.0    "/entrypoint.sh '/ho…"   kresus     11 seconds ago   Up 4 seconds              0.0.0.0:8146->9876/tcp, [::]:8146->9876/tcp
kresus-0.26.0-db    postgres:16-alpine      "docker-entrypoint.s…"   postgres   11 seconds ago   Up 10 seconds (healthy)   5432/tcp

4.4 观察首次启动日志

首次启动约需 1—2 分钟:入口脚本依次完成 UID 设置、Woob 升级、Kresus 升级,再交由 Kresus 完成数据库迁移。docker compose logs -f kresus 关键节点(实测节选,首尾保留):

[ENTRYPOINT] Starting with UID : 9001
[ENTRYPOINT] Setting fake values for git config...
[ENTRYPOINT] Installing or upgrading woob...
Collecting woob
  Downloading woob-3.7-py3-none-any.whl (514 kB)
...(中间为 pip 依赖下载回显,省略)...
[ENTRYPOINT] Done installing.
[ENTRYPOINT] Trying to update kresus...
success Saved lockfile.
success Saved 117 new dependencies.
info Direct dependencies
└─ kresus@0.26.0
...(中间为 yarn 依赖树回显,省略)...
[ENTRYPOINT] Done.
[ENTRYPOINT] Changing rights on user home directory...
[ENTRYPOINT] Running kresus as user.
[2026-10-23T18:01:52.546] [INFO] apply-config - Running Kresus 0.26.0 with the following parameters:
...(中间为 28 个配置项生效值回显,省略,完整见《Kresus 0.26.0 配置参数详解》)...
[2026-10-23T18:01:52.949] [INFO] models/index - database is ready
[2026-10-23T18:01:52.949] [INFO] models/index - Creating default user as administrator...
[2026-10-23T18:01:52.954] [INFO] models/index - Default user “user“ is set with id 1 (admin: true)
[2026-10-23T18:01:52.960] [INFO] poller - All accounts have been polled.
[2026-10-23T18:01:52.960] [INFO] report-manager - No emailer found, skipping reports management.
[2026-10-23T18:01:52.960] [INFO] init - Server is ready, let's start the show!

💡 说明:数据库为空时,Kresus 自动创建首个管理员账户,登录名固定为 user(id=1,管理员),无密码——正因为 Kresus 不提供内置登录认证,该「用户」主要用于多用户数据隔离标识,Web 界面直接放行;公网部署务必叠加反向代理认证或启用 config.ini 的 auth 项(HTTP Basic Auth)。

4.5 验证服务可用

curl -s -o /dev/null -w 'HTTP %{http_code}, %{size_download} bytes\n' http://127.0.0.1:8146/

实测回显:

HTTP 200, 10131 bytes

浏览器访问 http://<服务器IP>:8146/ 应看到 Kresus 界面(页面标题 Kresus)。同时确认数据已落库——查询 PostgreSQL 的业务表:

docker exec kresus-0.26.0-db psql -U kresus -d kresus -c '\dt'

实测回显:

                    List of relations
 Schema |             Name              | Type  | Owner
--------+-------------------------------+-------+--------
 public | access                        | table | kresus
 public | access_fields                 | table | kresus
 public | account                       | table | kresus
 public | alert                         | table | kresus
 public | applied-recurring-transaction | table | kresus
 public | budget                        | table | kresus
 public | category                      | table | kresus
 public | duplicates-ignored            | table | kresus
 public | migrations                    | table | kresus
 public | recurring-transaction         | table | kresus
 public | setting                       | table | kresus
 public | transaction                   | table | kresus
 public | transaction-rule              | table | kresus
 public | transaction-rule-action       | table | kresus
 public | transaction-rule-condition    | table | kresus
 public | user                          | table | kresus
 public | view                          | table | kresus
 public | view-accounts                 | table | kresus
(18 rows)

18 张业务表就绪,说明迁移完成、服务可用。

五、数据持久化说明

本编排共有三处持久化,全部落在 /opt/kresus/ 下:

宿主机路径挂载点内容是否必需
/opt/kresus/data/home/user/dataKresus 数据目录:kresus.log 运行日志、Woob 数据(模块源列表等)必需
/opt/kresus/pgdata/var/lib/postgresql/dataPostgreSQL 全部数据目录:账户、交易、分类、预算、设置等核心业务数据必需
/opt/kresus/woob/woobWoob 本地克隆(可选共享目录)可选
/opt/kresus/config.ini/opt/config.iniKresus 配置文件(单文件挂载)建议持久化

💡 说明:Kresus 的核心业务数据全部在 PostgreSQL(pgdata),data 目录只承载日志与辅助文件。备份策略应为「pg_dump 导出数据库 + 复制 config.ini」,这是官方管理文档推荐的备份组合(官方文档:保存配置文件、保存 datadir、用 pg_dump 导出数据库)。

实测宿主机侧落盘确认:

# ls /opt/kresus/pgdata/ | head -8
base
global
pg_commit_ts
pg_dynshmem
pg_hba.conf
pg_ident.conf
pg_logical
pg_multixact

# ls -la /opt/kresus/data/
total 92
drwx------ 2 9001 1001  4096 Oct 24 02:01 .
drwxr-xr-x 5 root root  4096 Oct 24 01:59 ..
-rw------- 1 9001 1001 78274 Oct 24 02:10 kresus.log

六、环境变量表

以下环境变量均实测有效(回显依据见启动日志 apply-config 段与《Kresus 0.26.0 配置参数详解》的参数-环境变量映射表):

环境变量实测取值作用
LOCAL_USER_ID9001制品内运行身份 UID;入口脚本按此值 usermod 内置 user
KRESUS_DB_TYPEpostgres数据库类型(postgres/sqlite)
KRESUS_DB_HOSTpostgres数据库主机(Compose 服务名)
KRESUS_DB_PORT5432数据库端口(启动日志回显 KRESUS_DB_PORT = 5432)
KRESUS_DB_USERNAMEkresus数据库用户名
KRESUS_DB_PASSWORDq1w2e3r4数据库密码(日志中回显为 (hidden),不泄明文)
KRESUS_DB_NAMEkresus数据库名
KRESUS_DB_LOGerrorSQL 日志级别(默认 error,日志回显生效)
HOST0.0.0.0监听地址(制品 ENV 默认,启动日志回显 HOST = 0.0.0.0)
PORT9876监听端口(启动日志回显 PORT = 9876)
KRESUS_DIR/home/user/data数据目录(制品 ENV 默认)
KRESUS_SERVER_TIMEOUT300内置 HTTP 服务超时秒数(默认 300)
KRESUS_PYTHON_EXECpython3Woob 调用的 Python 解释器(制品 ENV 默认)
KRESUS_AUTH未设置应用层 Basic Auth(user:pass 格式),日志回显 KRESUS_AUTH = null
IS_NIGHTLY未设置nightly 构建标识;设置后入口脚本跳过 Kresus 自动升级

完整的全部配置项与对应环境变量见官方配置模板与《Kresus 0.26.0 配置参数详解》。

七、配置参数说明

本文部署形态下最常调整的参数(完整逐参数详解见《Kresus 0.26.0 配置参数详解》):

  • [kresus] 节 auth=:设置后启用应用层 HTTP Basic Auth,格式 用户名:密码,例如 auth=admin:q1w2e3r4;这是无内置认证的 Kresus 在小团队/家庭场景下最快捷的访问控制补丁;
  • [kresus] 节 server_timeout=:银行抓取是同步阻塞请求,部分银行站点响应慢,默认 300 秒可按需调大;
  • [woob] 节 srcdir=:指定 Woob 核心目录;留空表示使用系统 Python 环境(制品内 pip 全局安装的 Woob 3.7);
  • [email] 节 transport=:留空不发邮件;设为 smtp 后需补齐 host/port/user/password/from 五项,Kresus 的日报与告警邮件由此发出(未配置时启动日志提示 No emailer found, skipping reports management);
  • [notifications] 节 appriseApiBaseUrl=:填入 Apprise-API 地址后可把通知推送到 Telegram、钉钉等数十种渠道;
  • [db] 节:生产固定 type=postgres;log=error 仅记录 SQL 报错,排障时可临时改 all。

八、配置文件挂载

config.ini 通过单文件 bind 挂载进运行环境(./config.ini:/opt/config.ini),注意三点:

  1. 权限:生产模式要求 600 或 640,Kresus 启动时校验,过宽即拒启(报错原文:For security reasons, the configuration file ... should be at most readable by its owner and group, writable by its owner.);
  2. 入口脚本二次收紧:官方入口脚本在每次启动时会强制 chmod 600 /opt/config.ini 并把属主改为运行用户,宿主机侧即便疏忽也会被纠正;
  3. 修改后需重启:INI 配置在进程启动时读取,改完执行 docker compose restart kresus 生效(重启同样会触发 Woob 升级流程,见第九章 FAQ)。

九、等价 docker run 命令

不经 Compose、以单条 docker run 部署等价环境(数据库需另行启动):

# 1. 先启动 PostgreSQL(命令行形态)
docker run -d --name kresus-0.26.0-db \
    -e POSTGRES_USER=kresus \
    -e POSTGRES_PASSWORD=q1w2e3r4 \
    -e POSTGRES_DB=kresus \
    -v /opt/kresus/pgdata:/var/lib/postgresql/data \
    postgres:16-alpine

# 2. 启动 Kresus(DB_HOST 用宿主机可达地址,同宿主机可用容器网关 IP 或 host 网络)
docker run -d --name kresus-0.26.0-app \
    -p 8146:9876 \
    -e LOCAL_USER_ID=9001 \
    -e KRESUS_DB_TYPE=postgres \
    -e KRESUS_DB_HOST=172.17.0.1 \
    -e KRESUS_DB_PORT=5432 \
    -e KRESUS_DB_USERNAME=kresus \
    -e KRESUS_DB_PASSWORD=q1w2e3r4 \
    -e KRESUS_DB_NAME=kresus \
    --restart unless-stopped \
    -v /opt/kresus/data:/home/user/data \
    -v /opt/kresus/woob:/woob \
    -v /opt/kresus/config.ini:/opt/config.ini \
    bnjbvr/kresus:0.26.0

⚠️ 说明:单 docker run 形态没有内置 DNS,KRESUS_DB_HOST 需写数据库的真实可达地址(同宿主机典型为网关 IP 172.17.0.1,或改用 host 网络后写 127.0.0.1);这正是本文推荐 Compose 编排的原因之一——Compose 网络内可直接用服务名 postgres 互访。

十、常用运维命令

以下命令均在实测环境执行验证(工作目录 /opt/kresus):

# 查看两服务状态
docker compose ps

# 跟踪应用日志(重点看 ENTRYPOINT 段与 Server is ready 字样)
docker compose logs -f kresus

# 重启应用(会重新执行 Woob/Kresus 升级检查)
docker compose restart kresus

# 停止与销毁(销毁只删运行实例与内部网络,三处持久化目录全部保留)
docker compose down

# 重新拉起
docker compose up -d

实测 down 回显:

 Container kresus-0.26.0-db Removed
 Network kresus-0260-stack_kresus-net Removed

实测重新 up -d 回显:

 Container kresus-0.26.0-db Healthy
 Container kresus-0.26.0-app Starting
 Container kresus-0.26.0-app Started

销毁重建后的数据恢复闭环(实测):为验证持久化,实测流程为——销毁前创建一个测试用户(docker exec kresus-0.26.0-app /home/user/app/bin/kresus create:user demo,回显 User demo created with success! id=5),docker compose down 销毁全部实例后 up -d 重建,待服务就绪(HTTP 200)后查询用户列表:

# docker exec kresus-0.26.0-app /home/user/app/bin/kresus list:users
...(配置回显省略)...
[2026-10-23T18:10:16.668] [INFO] cli - Found 2 users.
[2026-10-23T18:10:16.668] [INFO] cli - - id=1 login=user isAdmin=true
[2026-10-23T18:10:16.668] [INFO] cli - - id=5 login=demo isAdmin=false

销毁前创建的 demo 用户(id=5)在重建后依然存在,HTTP 服务同样恢复 200,持久化闭环成立。用户与账户数据的备份恢复细节见《Kresus 0.26.0 配置参数详解》第八章与官方管理文档。

进入运行环境手动排查:

# 进入应用运行环境
docker exec -it kresus-0.26.0-app bash

# 查看实时生效配置(启动日志 apply-config 段即全部参数生效值)
docker logs kresus-0.26.0-app 2>&1 | grep 'apply-config' | head -30

# 直连数据库排查
docker exec -it kresus-0.26.0-db psql -U kresus -d kresus

十一、常见问题(FAQ)

Q1:首次启动要多久?为什么每次重启都慢? 首次启动约 1—2 分钟:入口脚本要联网执行 pip install -U woob(下载 Woob 3.7 及依赖)与 yarn global upgrade kresus(117 个 npm 依赖,实测回显见 4.4 节),然后才启动应用本体。每次 restart 都会重复这两步升级检查,这是官方设计(保证银行模块始终最新),离线环境需自行改造入口脚本或接受升级失败后继续运行。

Q2:启动报数据库连接失败? 检查两点:一是 PostgreSQL 是否 healthy(docker compose ps),Kresus 用 depends_on: condition: service_healthy 已规避多数竞态;二是 KRESUS_DB_HOST 是否用了 Compose 网络内可达的服务名(postgres)。若自行改过网络或用 docker run 形态,见第九章的地址说明。

Q3:启动报配置文件权限错误并退出? 生产模式下 config.ini 权限过宽会拒启,报错含 should be at most readable by its owner and group 字样。执行 chmod 600 /opt/kresus/config.ini 后重启即可;入口脚本后续也会自动收紧权限。

Q4:Web 页面打开没有登录框,是否安全? Kresus 无内置登录认证(官方文档明确警告),首次启动自动生成的 user 账户只用于数据隔离。公网部署三选一:反向代理层加 Basic Auth/SSO;或 config.ini 设 auth=admin:q1w2e3r4 启用应用层 Basic Auth;或将端口映射改为 127.0.0.1:8146:9876 仅本机访问。

Q5:银行自动同步在中国能直接用吗? 不能直接依赖。银行同步由 Woob 驱动,其模块库以法国及部分欧美银行站点为主(实测 woob bank list 列出约 96 个模块,以法系银行为主),中国主要银行与支付平台不在覆盖范围。中文用户的交易数据走手工录入或文件导入;Woob 模块生态的进一步说明见 《Kresus 0.26.0 介绍与选型指南》。

Q6:如何完全卸载?

cd /opt/kresus
docker compose down
rm -rf /opt/kresus   # 危险操作:连同三处持久化数据一并删除,执行前确认已备份

down 后制品仍在本机,可用 docker rmi bnjbvr/kresus:0.26.0 postgres:16-alpine 释放存储空间。

十二、参考链接

  • Kresus 官方安装文档(Docker):https://kresus.org/en/install-docker.html
  • 官方管理文档(备份/配置):https://kresus.org/en/admin.html
  • 制品仓库:https://hub.docker.com/r/bnjbvr/kresus
  • 代码仓库:https://git.kresus.org/kresus/kresus
  • Woob 项目:https://woob.tech/
  • 同专栏篇目:《Kresus 0.26.0 介绍与选型指南》《Kresus 0.26.0 配置参数详解》《Kresus 0.26.0 常用 CLI 命令详解》