项目/家庭服务
家庭服务 · 运行中

记账系统 Firefly III

两年家庭流水记账,报表、预算、多账户管理。

Firefly III记账Docker

这是什么

Firefly III 是一套开源的记账系统,用 PHP 写的,跑在 Docker 里。我这套实例叫 Firefly,主要用来记全家的日常流水:谁花的、花在哪、从哪个账户出的。

为什么自己做

记账这件事我最怕两点:一是数据不在自己手里,二是换个工具就丢一批历史账。自建之后,整个账本就是「一个数据库 + 一个上传目录」,备份下来就是全部,迁移也不求人。顺带把 PHP 应用怎么部署、数据库怎么连、备份怎么留这三件事走了一遍,踩过的坑都留在了配置里。

解决什么问题

账户太多是记账最大的障碍:现金、银行卡、支付宝、微信各记一本,月底根本对不上。Firefly III 把它们拆成多个账户但汇总在一个视图里;报表按月份、分类、账户出,能看清钱到底花在哪儿,而不是只有一堆流水;再给几个大头类别设月度预算,超没超一眼就能看出来。

现在什么状态

运行中,已经连续记了两年家庭流水,日常记账都走网页。部署配置放在 opt-configs/ledger 下用 docker-compose 管理,容器重建不丢数据,这也是我坚持写 compose 文件而不是手工 docker run 的原因。

功能

  • 多账户记账:现金、银行卡、第三方支付分开记,汇总在一处
  • 报表与图表:按月、按分类、按账户出流水统计
  • 预算管理:给主要开销类别设月度预算并跟踪
  • Docker Compose 部署:配置集中在一个 compose 文件里,随时重建
  • 数据自持:数据库与上传目录可整体备份、可迁移

技术栈

Firefly IIIPHPDocker ComposeMariaDBNginx Proxy Manager

使用 / 部署教程

1. 准备目录

在装好 Docker 的主机上建工作目录,配置和数据都放这里:

mkdir -p /opt/ledger && cd /opt/ledger

2. 写 docker-compose.yml

一个应用容器 + 一个数据库容器,上传目录单独挂出来:

services:
  firefly:
    image: fireflyiii/core:latest
    restart: unless-stopped
    volumes:
      - ./upload:/var/www/html/storage/upload
    env_file: .env
    ports:
      - "8082:8080"
    depends_on:
      - db
  db:
    image: mariadb:lts
    restart: unless-stopped
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: firefly
      MYSQL_USER: firefly
      MYSQL_PASSWORD: 换成你自己的密码
    volumes:
      - ./db:/var/lib/mysql

3. 写 .env

关键是 APP_KEY(32 位随机字符串)和数据库连接,DB_HOST 填 compose 里的服务名 db:

APP_KEY=填32位随机字符串
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=与compose里一致

4. 启动并初始化

docker compose up -d
docker compose logs -f firefly

日志里出现迁移完成后,浏览器打开 http://主机IP:8082,第一个注册的账号就是管理员,注册完记得把开放注册关掉。

5. 挂反向代理和 HTTPS

用 Nginx Proxy Manager 新建一条代理,指向 主机IP:8082,申请证书开强制 HTTPS。局域网自用可以只在内网访问;要外网用就走 Tailscale 这类内网穿透,比直接把端口暴露到公网省心。

6. 备份

两份东西都要备:数据库和 upload 目录。数据库用 dump 最稳:

docker compose exec db mysqldump -u firefly -p firefly > backup-$(date +%F).sql
tar czf upload-$(date +%F).tar.gz upload/

丢进定时任务,定期验证能不能恢复,别只备不测。

注意

  • APP_KEY 和数据库密码要单独记一份,重建容器时必须保持一致,否则会产生一堆对不上的数据。
  • 备份要成对:数据库 dump 加上传目录,只备其中一个恢复出来是不完整的。
  • 别把服务直接暴露在公网;真要外网访问,至少上 HTTPS + 强密码,并关闭开放注册。