关 于
·Hellow 我是 辛 旗 今天给大家分享的是ezBookkeeping的部署他是一款开源、轻量、自托管 (self-hosted) 的个人记账应用.
本教程分为两个部分:
1. 一键安装(使用的是 sqlite3 数据库)
2. 安装(内置 / 外部 Mysql 数据库)
官方网站:ezBookkeeping - 开源、轻量、自托管 (self-hosted) 的个人记账应用
应用展示:

/

部 署 教 程
1.一键安装
执行官方Docker安装命令
docker run -d -p8080:8080 --name ezbookkeeping mayswind/ezbookkeeping执行完该命令后,ezBookkeeping 将会使用默认的配置在后台启动,并监听端口 8080。
容器中的默认路径:
• 配置文件:/ezbookkeeping/conf/ezbookkeeping.ini
• 数据库文件(使用 sqlite3 数据库):/ezbookkeeping/data/ezbookkeeping.db
• 日志文件:/ezbookkeeping/log/ezbookkeeping.log
• 对象存储根路径(使用 local_filesystem 对象存储): /ezbookkeeping/storage/
持久化存储数据
默认数据库类型是 sqlite3,数据库文件存储在容器中的 /ezbookkeeping/data/ezbookkeeping.db。 如果你想继续使用 sqlite3 作为数据库,并持久化保存这些数据,你需要使用 Docker 持久化数据卷或挂载宿主机的路径到容器内。 此外,默认对象存储使用本地文件系统,默认路径是 /ezbookkeeping/storage/,如果你使用本地文件系统存储对象数据(例如用户上传的图片),你也需要使用 Docker 持久化数据卷或挂载宿主机的路径到容器内。
使用持久化数据卷运行容器
# 创建持久化数据卷
docker volume create ezbookkeeping-data
docker volume create ezbookkeeping-storage
# 使用持久化数据卷运行容器
docker run -d -p8080:8080 --name ezbookkeeping -v ezbookkeeping-data:/ezbookkeeping/data -v ezbookkeeping-storage:/ezbookkeeping/storage mayswind/ezbookkeeping挂载宿主机路径运行容器
# 在宿主机创建数据路径并修改 UID/GID
mkdir -p /var/lib/ezbookkeeping/data
mkdir -p /var/lib/ezbookkeeping/storage
chown 1000:1000 /var/lib/ezbookkeeping/data
chown 1000:1000 /var/lib/ezbookkeeping/storage
# 挂载宿主机路径运行容器
docker run -d -p8080:8080 --name ezbookkeeping -v /var/lib/ezbookkeeping/data:/ezbookkeeping/data -v /var/lib/ezbookkeeping/storage:/ezbookkeeping/storage mayswind/ezbookkeeping运行 ezBookkeeping 的 用户 ID(UID)和 分组 ID(GID)都是 1000,所以你需要保证当你想修改路径或挂载数据卷时,ezBookkeeping 使用的目录有权限被 UID/GID 1000 读 / 写。
2.安装(内置Mysql数据库)
⚠:内置 Mysql 若需要个性化配置,可以参考(外部 Mysql 的 INI 配置文件,记得去掉 INI 文件 Mysql 的配置和 Yml 文件挂载前面的 #)
创建docker文件
#在opt目录下创建ezbookkeeping文件夹
mkdir -p /opt/ezbookkeeping#打开ezbookkeeping文件
cd /opt/ezbookkeeping创建Docker Compose 配置
#编辑docker-compose.yml
vim docker-compose.ymlYml文件
services:
mysql:
image: mysql:8.0 # 使用官方 MySQL 8.0 镜像
container_name: ezbookkeeping-mysql # 容器名称(可自定义)
restart: unless-stopped # 除非手动停止,否则异常会自动重启
command:
- --character-set-server=utf8mb4 # 默认字符集(支持中文/emoji)
- --collation-server=utf8mb4_unicode_ci # 默认排序规则
- --default-time-zone=+08:00 # MySQL 时区(这里设为东八区)
volumes:
- ./data:/var/lib/mysql # MySQL 数据持久化(重要:避免重启丢数据)
environment:
MYSQL_DATABASE: ezbookkeeping # 初始化创建数据库名
MYSQL_USER: ezbookkeeping # 初始化创建普通用户
MYSQL_PASSWORD: ezbookkeeping # 普通用户密码(建议改强密码)
MYSQL_ROOT_PASSWORD: ezbookkeeping # root 密码(建议改强密码)
healthcheck:
# 健康检查:用 mysqladmin ping 判断 MySQL 是否就绪
# -p 密码要紧跟,不要有空格(-pPASSWORD)
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-pezbookkeeping"]
interval: 5s # 每 5 秒检查一次
timeout: 5s # 单次检查超时时间 5 秒
retries: 20 # 连续失败 20 次才判定为 unhealthy
ezbookkeeping:
image: mayswind/ezbookkeeping:latest # ezBookkeeping 镜像(latest 表示最新版)
container_name: ezbookkeeping # 容器名称
restart: unless-stopped # 异常自动重启
ports:
- "8082:8080" # 访问端口:宿主机 8082 -> 容器 8080
volumes:
- /etc/localtime:/etc/localtime:ro # 同步宿主机时间(只读挂载)
- ./storage:/ezbookkeeping/storage # 应用存储目录(持久化数据/附件等)
- ./log:/ezbookkeeping/log # 应用日志目录(写到宿主机)
#- ./ezbookkeeping.ini:/ezbookkeeping/conf/ezbookkeeping.ini:ro
# 如果你需要用配置文件覆盖默认配置,可取消注释并准备 ezbookkeeping.ini(只读更安全)
environment:
EBK_DATABASE_TYPE: mysql # 数据库类型:mysql
EBK_DATABASE_HOST: mysql:3306 # 数据库地址:服务名 mysql + 端口 3306(同一网络内自动解析)
EBK_DATABASE_NAME: ezbookkeeping # 数据库名
EBK_DATABASE_USER: ezbookkeeping # 数据库用户
EBK_DATABASE_PASSWD: ezbookkeeping # 数据库密码
EBK_LOG_MODE: file # 日志模式:写文件(配合 ./log 挂载)
EBK_SECURITY_SECRET_KEY: "eyJhbGciOiJBMTI4R0NNIiwiZXh0Ijp0cnVlLCJrIj"
# 安全密钥:建议改成 32~64 位以上随机字符串(用于安全相关加密/签名)
depends_on:
mysql:
condition: service_healthy # 等 MySQL 健康检查通过后再启动 ezBookkeeping(更稳)/
运行ezbookkeeping的docker镜像
# 启动docker
docker compose up -d
# 重启docker
docker compose stop
docker compose start
# 升级docker
docker compose down
docker compose pull
docker compose up -d启动成功docker-compose.yml之后我们开放一下日志文件权限
chmod -R 777 log storage重启一下docker服务
docker compose restart ezbookkeeping3.安装(外部Mysql数据库)
⚠:除了 Yml 文件的配置,其他命令一致.(新增 INI 配置文件)
Yml文件
services:
ezbookkeeping:
image: mayswind/ezbookkeeping:latest # ezBookkeeping 镜像(latest 表示最新版)
container_name: ezbookkeeping # 容器名称
restart: unless-stopped # 异常自动重启
ports:
- "8082:8080" # 访问端口:宿主机 8082 -> 容器 8080
volumes:
- /etc/localtime:/etc/localtime:ro # 同步宿主机时间(只读挂载)
- ./storage:/ezbookkeeping/storage # 应用存储目录(持久化数据/附件等)
- ./log:/ezbookkeeping/log # 应用日志目录(写到宿主机)
- ./ezbookkeeping.ini:/ezbookkeeping/conf/ezbookkeeping.ini:ro
# 如果你需要用配置文件覆盖默认配置,可取消注释并准备 ezbookkeeping.ini(只读更安全)
environment:
EBK_DATABASE_TYPE: mysql # 数据库类型:mysql
EBK_DATABASE_HOST: 必填 # 外部MySQL地址+默认端口
EBK_DATABASE_NAME: ezbookkeeping # 数据库名(需确保外部MySQL已创建该库)
EBK_DATABASE_USER: ezbookkeeping # 外部MySQL用户名
EBK_DATABASE_PASSWD: ezbookkeeping # 外部MySQL密码
EBK_LOG_MODE: file # 日志模式:写文件(配合 ./log 挂载)
EBK_SECURITY_SECRET_KEY: "eyJhbGciOiJBMTI4R0NNIiwiZXh0Ijp0cnVlLCJrIj"
# 安全密钥:建议改成 32~64 位以上随机字符串(用于安全相关加密/签名) INI文件
⚠:INI 配置文件(和 Yml 文件放到同一目录下)
; =============================================================================
; ezBookkeeping 配置文件(适配 MySQL + 高德地图 + 飞书 SMTP 邮件)
; 配置规则:
; 1. 注释用 ; 开头(单独行),或值后空1格用 ; 注释
; 2. [global].mode 仅支持 production/development(纯值)
; 3. [server].protocol 仅支持 http/https/socket(纯值)
; =============================================================================
; ================ 全局配置 (global) ================
[global]
; 应用实例名称(两步验证使用)
app_name = ezBookkeeping
; 运行模式:production(生产)/development(开发)
mode = production
; ================ Web 服务器配置 (server) ================
[server]
; 服务协议:仅支持 http/https/socket
protocol = http
; 绑定IP(0.0.0.0表示所有网卡)
http_addr = 0.0.0.0
; 容器内端口(与yml映射的8080对应)
http_port = 8080
; 访问域名
domain = 必填
; 完整访问路径
root_url = %(protocol)s://%(domain)s:%(http_port)s/
; https证书文件路径(留空则不启用https)
cert_file =
; https证书私钥路径
cert_key_file =
; unix socket路径(仅socket协议使用)
unix_socket =
; 静态文件根目录
static_root_path = public
; 是否开启gzip压缩
enable_gzip = false
; 是否记录请求日志
log_request = true
; 是否添加X-Request-Id响应头
request_id_header = true
; ================ MCP 配置 (mcp) ================
[mcp]
; 是否启用MCP(与yml中EBK_MCP_ENABLE_MCP=true一致)
enable_mcp = false
; MCP允许的远程IP(*表示所有,留空则不限制)
mcp_allowed_remote_ips =
; ================ 数据库配置 (database) ================
[database]
; 数据库类型(与yml中EBK_DATABASE_TYPE=mysql一致)
type = mysql
; 数据库地址(容器内服务名,与yml中EBK_DATABASE_HOST一致)
host = 必填(ip或域名):3306
; 数据库名(与yml中EBK_DATABASE_NAME一致)
name = ezbookkeeping
; 数据库用户(与yml中EBK_DATABASE_USER一致)
user = ezbookkeeping
; 数据库密码(与yml中EBK_DATABASE_PASSWD一致)
passwd = ezbookkeeping
; postgres专属:SSL连接模式(disable/require/verify-full)
ssl_mode = disable
; sqlite3专属:数据库文件路径(mysql模式下无效)
db_path = data/ezbookkeeping.db
; 连接池最大空闲连接数(0-65535)
max_idle_conn = 2
; 最大打开连接数(0表示不限制)
max_open_conn = 0
; 空闲连接最大存活时长(秒)
conn_max_lifetime = 1440
; 是否记录SQL执行日志
log_query = false
; 启动时自动更新数据库结构
auto_update_database = true
; ================ 邮件配置 (mail) ================
[mail]
; 是否启用 SMTP 发送邮件(必须设为 true 才生效)
enable_smtp = true
; SMTP 服务器地址+SSL端口(飞书 SMTP 地址+465端口)
smtp_host = 必填
; SMTP 登录用户名(你的发件人邮箱)
smtp_user = 必填
; SMTP 登录密码(你的 IMAP/SMTP 密码)
smtp_passwd = 必填
; 是否跳过 SSL 证书校验(建议 false,保证安全)
smtp_skip_tls_verify = false
; 发件人地址(与 smtp_user 一致,支持"名称 <邮箱>"格式)
from_address = 必填
; ================ 日志配置 (log) ================
[log]
; 日志输出模式:console/file(与yml中EBK_LOG_MODE=file一致)
mode = file
; 日志级别:debug/info/warn/error
level = info
; 日志文件路径
log_path = log/ezbookkeeping.log
; 请求日志单独路径(留空则合并到默认日志)
request_log_path =
; SQL日志单独路径(留空则合并到默认日志)
query_log_path =
; 是否启用日志轮转
log_file_rotate = false
; 日志轮转最大大小(字节,默认100MB)
log_file_max_size = 104857600
; 日志保留天数(0表示永久保留)
log_file_max_days = 7
; ================ 对象存储配置 (storage) ================
[storage]
; 存储类型:local_filesystem/minio/webdav
type = local_filesystem
; 本地存储根目录
local_filesystem_path = storage/
; MinIO地址
minio_endpoint = 127.0.0.1:9000
; MinIO区域
minio_location =
; MinIO Access Key
minio_access_key_id =
; MinIO Secret Key
minio_secret_access_key =
; MinIO是否启用SSL
minio_use_ssl = false
; 是否跳过MinIO证书校验
minio_skip_tls_verify = false
; MinIO桶名称
minio_bucket = ezbookkeeping
; MinIO桶内根路径
minio_root_path = /
; WebDAV地址
webdav_url =
; WebDAV用户名
webdav_username =
; WebDAV密码
webdav_password =
; WebDAV根路径
webdav_root_path = /
; WebDAV请求超时(毫秒)
webdav_request_timeout = 10000
; WebDAV代理:system/none/自定义
webdav_proxy = system
; 是否跳过WebDAV证书校验
webdav_skip_tls_verify = false
; ================ 大语言模型 (LLM) 配置 (llm) ================
[llm]
; 是否启用AI识图创建交易
transaction_from_ai_image_recognition = false
; AI识图最大文件大小(10MB)
max_ai_recognition_picture_size = 10485760
; ================ 收据图片识别 LLM 配置 (llm_image_recognition) ================
[llm_image_recognition]
; LLM提供商:openai/openrouter/ollama/google_ai等
llm_provider =
; OpenAI API Key
openai_api_key =
; OpenAI模型ID
openai_model_id =
; 兼容OpenAI的API地址
openai_compatible_base_url =
; 兼容OpenAI的API Key
openai_compatible_api_key =
; 兼容OpenAI的模型ID
openai_compatible_model_id =
; OpenRouter API Key
openrouter_api_key =
; OpenRouter模型ID
openrouter_model_id =
; Ollama服务器地址
ollama_server_url =
; Ollama模型ID
ollama_model_id =
; Google AI API Key
google_ai_api_key =
; Google AI模型ID
google_ai_model_id =
; LLM请求超时(毫秒)
request_timeout = 60000
; LLM代理:system/none/自定义
proxy = system
; 是否跳过LLM证书校验
skip_tls_verify = false
; ================ Uuid 配置 (uuid) ================
[uuid]
; UUID生成器类型:internal
generator_type = internal
; 服务器实例ID(0-255)
server_id = 0
; ================ 重复检查器配置 (duplicate_checker) ================
[duplicate_checker]
; 重复检查器类型:in_memory
checker_type = in_memory
; 清理过期数据间隔(秒)
cleanup_interval = 60
; 重复提交最小间隔(秒)
duplicate_submissions_interval = 300
; ================ 定时任务配置 (cron) ================
[cron]
; 是否清理过期令牌
enable_remove_expired_tokens = true
; 是否创建定时交易
enable_create_scheduled_transaction = false
; ================ 安全配置 (security) ================
[security]
; 安全密钥(与yml中EBK_SECURITY_SECRET_KEY一致,建议替换为随机字符串)
secret_key = 必填(生成一个密钥)
; 令牌过期时间(30天,秒)
token_expired_time = 2592000
; 令牌最小刷新间隔(1天,秒)
token_min_refresh_interval = 86400
; 临时令牌过期时间(5分钟,秒)
temporary_token_expired_time = 300
; 邮箱验证令牌过期时间(1小时,秒)
email_verify_token_expired_time = 3600
; 密码重置令牌过期时间(1小时,秒)
password_reset_token_expired_time = 3600
; 是否开启API令牌
enable_api_token = true
; 每IP每分钟失败次数上限
max_failures_per_ip_per_minute = 5
; 每用户每分钟失败次数上限
max_failures_per_user_per_minute = 5
; ================ 身份验证配置 (auth) ================
[auth]
; 是否启用账号密码登录
enable_internal_auth = true
; 是否启用OAuth2登录
enable_oauth2_auth = false
; 是否启用两步验证
enable_two_factor = true
; 是否启用密码重置(需SMTP配置生效)
enable_forget_password = true
; 密码重置是否要求邮箱必须验证
forget_password_require_email_verify = true
; OAuth2提供商:oidc/nextcloud/gitea/github
oauth2_provider =
; OAuth2客户端ID
oauth2_client_id =
; OAuth2客户端密钥
oauth2_client_secret =
; OAuth2用户匹配字段:email/username
oauth2_user_identifier = email
; 是否启用PKCE
oauth2_use_pkce = false
; OAuth2用户自动注册(需enable_register=true)
oauth2_auto_register = true
; OAuth2状态过期时间(秒)
oauth2_state_expired_time = 300
; OAuth2请求超时(毫秒)
oauth2_request_timeout = 10000
; OAuth2代理:system/none/自定义
oauth2_proxy = system
; 是否跳过OAuth2证书校验
oauth2_skip_tls_verify = false
; OIDC提供商地址
oidc_provider_base_url =
; 是否校验OIDC Issuer URL
oidc_provider_check_issuer_url = true
; 是否自定义OIDC显示名称
enable_oidc_display_name = false
; OIDC自定义显示名称
oidc_custom_display_name =
; Nextcloud地址
nextcloud_base_url =
; Gitea地址
gitea_base_url =
; ================ 用户配置 (user) ================
[user]
; 是否启用用户注册
enable_register = true
; 是否启用邮箱验证(需SMTP配置生效)
enable_email_verify = true
; 登录是否强制邮箱验证
enable_force_email_verify = false
; 是否启用交易图片
enable_transaction_picture = true
; 交易图片最大大小(10MB)
max_transaction_picture_size = 10485760
; 是否启用定时交易
enable_scheduled_transaction = false
; 头像提供商:internal/gravatar(留空禁用)
avatar_provider = internal
; 头像最大大小(1MB)
max_user_avatar_size = 1048576
; 默认功能限制(留空无限制)
default_feature_restrictions =
; ================ 数据配置 (data) ================
[data]
; 是否启用数据导出
enable_export = true
; 是否启用数据导入
enable_import = true
; 导入文件最大大小(10MB)
max_import_file_size = 5242880
; ================ 提示配置 (tip) ================
[tip]
; 是否启用登录页自定义提示
enable_tips_in_login_page = false
; 登录页自定义提示内容(支持多语言)
login_page_tips_content =
; ================ 通知配置 (notification) ================
[notification]
; 注册后显示自定义通知
enable_notification_after_register = false
; 注册后通知内容(支持多语言)
after_register_notification_content =
; 登录后显示自定义通知
enable_notification_after_login = false
; 登录后通知内容(支持多语言)
after_login_notification_content =
; 打开应用显示自定义通知
enable_notification_after_open = false
; 打开应用通知内容(支持多语言)
after_open_notification_content =
; ================ 地图配置 (map) ================
[map]
; 地图提供商:amap(高德)
map_provider = amap
; 是否通过服务端转发地图请求
map_data_fetch_proxy = false
; 地图代理:system/none/自定义
proxy = system
; TomTom API Key
tomtom_map_api_key =
; 天地图App Key
tianditu_map_app_key =
; Google地图API Key
google_map_api_key =
; 百度地图AK
baidu_map_ak =
; 高德API Key(你的密钥)
amap_application_key = 必填
; 高德安全验证方式
amap_security_verification_method = internal_proxy
; 高德安全密钥(你的密钥)
amap_application_secret = 必填
; 高德外部代理地址
amap_api_external_proxy_url =
; 自定义地图瓦片地址
custom_map_tile_server_url =
; 自定义地图标注地址
custom_map_tile_server_annotation_url =
; 自定义地图最小缩放等级
custom_map_tile_server_min_zoom_level = 1
; 自定义地图最大缩放等级
custom_map_tile_server_max_zoom_level = 18
; 自定义地图默认缩放等级
custom_map_tile_server_default_zoom_level = 14
; ================ 汇率配置 (exchange_rates) ================
[exchange_rates]
; 汇率数据源:欧央行(支持多国央行/IMF)
data_source = euro_central_bank
; 汇率请求超时(毫秒)
request_timeout = 10000
; 汇率代理:system/none/自定义
proxy = system
; 是否跳过汇率证书校验
skip_tls_verify = false好了各位小伙伴,教学完成,我们也配置了 DEMO(页脚 ezBookkeeping)提供给大家免费使用.
若有技术问题可以加入千帆社区 QQ(页脚)