HBB's Blog

Ordinary road, record every bit

Beancount × 群晖NAS容器化部署指南

本文记录在群晖NAS上部署Beancount记账系统的完整流程。作为一款基于文本的开源复式记账工具,Beancount可以通过fava实现数据可视化,本部署指南通过以下技术方案解决实际问题:

  • 随处访问:利用Docker在群晖DSM系统中运行fava服务,通过浏览器实现跨平台访问
  • ​访问控制:通过群晖SSO(Synology Single Sign-On),为Web界面添加账户鉴权
  • ​数据安全:将Beancount账本文件存储在私有Git仓库并进行GPG加密
  • ​云端同步:将账本文件托管至Git私有仓库,配合cron定时任务实现「本地修改→加密提交→NAS服务定时拉取更新」的跨端数据流(确保各设备数据一致性)

适用读者

本文面向具备基础开发和运维能力的爱折腾型用户,适合以下场景:

  • 已使用Beancount但希望实现跨设备访问的个人用户
  • 寻求私有化部署财务系统的NAS使用者

部署前的环境准备

在开始部署前,请确保已完成以下基础设施配置。这些条件既是系统运行的底层依赖,也是保障数据安全与远程访问的关键前提。

群晖NAS基础环境

​系统要求:DSM 7.0及以上版本(测试机型:DS920+)
​必要套件:

  • Container Manager(套件中心安装)
  • SSO 服务器(套件中心安装,用于增加鉴权)
  • Web Station (用于增加别名访问)

域名与网络配置

​域名指向:已注册域名(示例:nas.domain.com)

​HTTPS证书:通过域名服务商可以申请免费或者其他有效的HTTPS证书

代码托管准备

​GitHub私有仓库:

  • 拥有一个有Beancount账本数据并可以在本地正常运行的Github私有仓库(可以参考mckelvin大佬的beancount-boilerplate-cn仓库)

  • 针对仓库中私人的敏感数据进行加密,推荐使用git-crypt

NAS内访问仓库的准备

生成Github私有仓库访问密钥:

访问Personal Access Tokens (Classic),点击右上角Generate new token

保存好你的私有仓库访问密钥,丢失后你需要重新生成将上面的token保存到文件./secrets/github_token.txt中(文件名可任取)

git-crypt解密密钥:

在仓库根目录执行下面的命令导出密钥,用于在Docker容器内部署时内对仓库代码进行解密。

git-crypt export-key ./secrets/git_crypt_key

群晖SSO配置(以DSM 7.2为例)

首先在群晖的套件中心安装SSO服务器,安装好后下面配置SSO服务。

SSO服务器 → 常规设置

账户类型:选择域/LDAP/本地

服务器URL:输入你的DSM地址,记得携带端口号 dsm.yourdomain.com:5000

SSO服务器 → 服务 → OIDC

开启OIDC服务,并记录Well-known URL

SSO服务器 → 应用程序 → 新增

选择SSO协议:OIDC

应用名称: My_Beancount

重定向URL: 填写你的SSO登陆回调地址,后续回调接口地址变更后需要再进入应用程序进行同步修改和添加。

获取OIDC配置参数

创建完成后会获得两个配置参数

  • 应用程序ID
  • 应用程序密钥

准备部署配置

通过Docker Compose实现服务编排,服务流程为用户请求 → Nginx → SSO → Fava服务

具体容器配置如下,省略了部分配置,可在底部查看详细配置:

# docker-compose.yml
fava:
container_name: fava_server
environment:
- TZ=Asia/Shanghai

sso_gateway:
image: nginx:latest
container_name: sso_gateway
ports:
- "8111:8111" # 对外暴露端口
volumes:
- ./sso_nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- sso_auth
- fava

sso_auth:
container_name: sso_auth
depends_on:
- fava

文件目录结构说明

具体编排代码已经开源:https://github.com/Leon2xiaowu/fava-synology-sso,这里做一个简单的说明,详情还请进入仓库具体查看。

.
├── Dockerfile # fava 服务配置
├── README.md
├── cert # https的证书目录
│ ├── ssl.pem
│ └── ssl.key
├── docker-compose.yml # 服务编排配置
├── secrets
│ ├── git_crypt_key # git仓库解密
│ └── github_token.txt # 私有git仓库访问
├── sso_auth
│ ├── Dockerfile # sso鉴权服务配置
│ ├── app.py
│ └── requirements.txt
└── sso_nginx.conf # nginx配置

./Dockerfile 是fava的容器配置文件,你需要修改https://${GITHUB_TOKEN}@github.com/yourname/your_bucket.git 为你自己的github仓库地址。

sso_auth/Dockerfile 是SSO鉴权服务的配置,也需要你进行部分配置项的修改。

部署

  1. 将上面目录结构中的文件传到NAS File Station的任意位置
  2. 在群晖 Container Manager 中创建项目
  3. 打开 Container Manager ,点击项目新增
  4. 点击设置路径,选择步骤1中上传的目录
  5. 弹出的对话框中确定选择使用现有的 docker-compose.yml 来创建项目
  6. 输入项目名称后下一步,设置门户为fava,门户别名可以修改,同时你需要修改sso_nginx.conf./Dockerfile中的相关配置。

例子🌰

假设你的群晖DSM地址为: https://nas.domain.com:5000

你的SSO服务器 URL 就应该配置为 https://nas.domain.com:5000

在你开启OIDC后 WELL_KNOWN_URL 可能是 "https://nas.domain.com:5000/webman/sso/.well-known/openid-configuration"

部署成功后fava的请求地址为:https://nas.domain.com:8111/fava

在SSO服务器应用程序中配置的重定向URL为 https://nas.domain.com:8111/fava/callback