Firefly III Docker Compose 部署实战

Firefly III v6.7.9 官方镜像 + PostgreSQL 16 + cron + Data Importer v2.3.5 全栈 Docker Compose 部署实测:APP_KEY 生成与固定、自动迁移、管理员注册与首启向导、API 令牌签发、持久化验证与密码策略等排障实录。

Firefly IIIDockerDocker Compose财务记账Laravel2026/10/28

Firefly III Docker Compose 部署实战

目标:在一台 Ubuntu 22.04 服务器上,用 Docker Compose 从零部署 Firefly III v6.7.9(主程序 + PostgreSQL 16 + 定时任务器 + Data Importer v2.3.5 全套基线服务),完成应用密钥配置、首次启动自动迁移、管理员注册与首启向导、API 令牌签发与健康验证,并沉淀密码策略、镜像命名空间、Passport 客户端缺失等真实排障实录。本文全部命令与回显均在 6.7.9 环境实测;产品背景与选型见《Firefly III 介绍与选型指南》,APP_KEY 变更演练的排障实录见《Firefly III 常用命令与运维实战》第十一章。

一、环境信息

本次实测环境与部署基准:

项目值
操作系统Ubuntu 22.04(服务器内网 IP 192.168.146.128)
Docker / ComposeDocker 29.9.2,Compose v5.6.1(docker compose 子命令)
Firefly III 版本6.7.9(官方 fireflyiii/core:latest 当前指向版本,/api/v1/about 实测返回 "version":"6.7.9")
数据库PostgreSQL 16(postgres:16-alpine)
Data Importerv2.3.5(fireflyiii/data-importer:latest,容器内 php artisan importer:version 实测)
服务监听主程序 8130、Data Importer 8133(服务器 IP 直连访问)
编排项目目录/opt/firefly-iii(compose 文件与 .env 所在目录)
演示管理账号admin@firefly.local / q1w2e3r4q1w2e3r4(密码策略要求至少 16 字符,见 10.1)

版本核验回显(实测):

$ curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" http://192.168.146.128:8130/api/v1/about
{"data":{"version":"6.7.9","api_version":"6.7.9","php_version":"8.5.12","os":"Linux","driver":"pgsql"}}
$ docker exec firefly-iii-6.7.9-importer php artisan importer:version
Firefly III data importer v2.3.5
PHP: cli 8.5.12 Linux

二、镜像选型说明

官方发布两个主镜像(Docker Hub,同属 fireflyiii 命名空间):

镜像本次实测版本职责
fireflyiii/core:latest6.7.9(PHP 8.5.12 运行时,digest sha256:d51ab6a3...e060871,构建日期 2026-10-26)主程序:Web 界面、JSON REST API、规则引擎、迁移启动器,内置 nginx + PHP-FPM
fireflyiii/data-importer:latest2.3.5独立 Web 导入器:CSV/银行对账单导入,通过 OAuth 客户端凭据对接主程序
postgres:16-alpinePostgreSQL 16业务数据库(官方推荐 MySQL/PostgreSQL 二选一,本文按任务基线选 PostgreSQL)
alpine官方编排原样保留定时任务器:每天 03:00 以 STATIC_CRON_TOKEN 调用主程序 cron 入口

选型说明与两点官方事实:

  1. 数据库选 PostgreSQL:官方 Docker 安装文档默认编排为 MariaDB,并明确给出切换 PostgreSQL 的改法(DB_CONNECTION=pgsql、DB_PORT=5432、挂载点 /var/lib/postgresql/data);官方同时注明"Pointing the image to postgres will install PostgreSQL-18"——为锁定 16 版本本文显式使用 postgres:16-alpine,挂载点相应用 /var/lib/postgresql/data。
  2. 镜像名有两个拼写:官方仓库当前文档同时存在 firefly-iii/core(新组织名)与 fireflyiii/core(官方 docker-compose.yml 中实际使用的名字)。⚠️ 实测本服务器所在网络经 DaoCloud 公共镜像加速器拉取时,firefly-iii/core 报"这镜像不在白名单",而官方编排文件中写的 fireflyiii/core:latest 实测可正常拉取,本文沿用官方编排的写法。其他网络环境如遇拉取失败,优先核对镜像名拼写与加速器白名单。

⚠️ 网络说明:本次实测 docker pull fireflyiii/core:latest 与 fireflyiii/data-importer:latest 直接成功(走已配置的镜像加速通道);postgres:16-alpine 本机已存在。离线环境需提前导入镜像,见第十章常见问题。

三、前置条件

  1. 一台 Ubuntu 22.04 服务器,已安装 Docker 29.x 与 Compose v5.x 插件;
  2. 服务器可达 docker.io(或可用的镜像加速通道);
  3. 两个空闲宿主端口:本文用 8130(主程序)、8133(Data Importer);
  4. openssl//dev/urandom(Ubuntu 自带),用于生成 32 位应用密钥。

确认 Compose 可用(实测回显):

$ docker compose version
Docker Compose version v5.6.1
$ docker --version
Docker version 29.9.2, build a82e528

四、部署步骤

4.1 准备编排目录

官方推荐的部署形态是"一个目录放三个文件":docker-compose.yml(官方仓库 firefly-iii/docker 提供)、.env(主程序变量)、.db.env(数据库变量)。本文将官方编排改写为 PostgreSQL 版并把数据库变量并入 .env(变量同源传递,减少一处密码两处改的错位风险),落到 /opt/firefly-iii:

mkdir -p /opt/firefly-iii/data/upload && cd /opt/firefly-iii

4.2 生成应用密钥(APP_KEY 与 STATIC_CRON_TOKEN)

Firefly III 官方要求:APP_KEY 必须是恰好 32 个字符的随机串,并避免 =、# 等特殊字符;STATIC_CRON_TOKEN 同样要求恰好 32 字符。用官方文档给出的生成命令各生成一个(实测回显):

$ head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo
CqRn77wKahWp5Bsnwogd4wbgBrXKU9Rw
$ head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo
msiPUbX4gIqx9L1gAkwUmrfgJqYRmGzS

⚠️ 注意:APP_KEY 一经使用就必须永久固定。它参与 Laravel 加密体系(会话、令牌等),更换会导致既有加密数据不可读、全部登录态失效——排障实录见《Firefly III 常用命令与运维实战》第十一章的变更演练。(以上密钥为本次实测演示值;生产环境请自行重新生成,切勿照抄。)

4.3 编写 .env

按官方 .env.example 取必填与关键项,写成 /opt/firefly-iii/.env,本次实测完整内容如下(密钥/口令为实测演示值):

APP_ENV=production
APP_DEBUG=false
SITE_OWNER=admin@firefly.local
APP_KEY=CqRn77wKahWp5Bsnwogd4wbgBrXKU9Rw
APP_URL=http://192.168.146.128:8130
DEFAULT_LANGUAGE=en_US
DEFAULT_LOCALE=equal
TZ=Asia/Shanghai
TRUSTED_PROXIES=
LOG_CHANNEL=stack
APP_LOG_LEVEL=notice
AUDIT_LOG_LEVEL=emergency
AUDIT_LOG_CHANNEL=
DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=q1w2e3r4
PGSQL_SCHEMA=public
CACHE_STORE=file
SESSION_DRIVER=file
STATIC_CRON_TOKEN=msiPUbX4gIqx9L1gAkwUmrfgJqYRmGzS
MAIL_MAILER=log
MAIL_FROM=changeme@example.com
COOKIE_SECURE=false
COOKIE_SAMESITE=lax

逐项说明:

变量作用说明
APP_KEY应用加密密钥必须 32 字符、避免特殊符号;首次启动后不可更换(见 4.2 ⚠️)
APP_URL对外访问地址填浏览器实际访问的 http://<IP>:<端口>,页面内链接由它生成
SITE_OWNER站点管理员邮箱演示环境填管理员邮箱即可
TZ时区影响日志与页面时间展示
DB_CONNECTION/DB_HOST/DB_PORT数据库类型/地址/端口PostgreSQL 三件套:pgsql / db(编排内服务名)/ 5432
DB_DATABASE/DB_USERNAME/DB_PASSWORD库名/账号/口令必须与 db 服务的 POSTGRES_* 一致
PGSQL_SCHEMA数据库 schema默认 public
CACHE_STORE/SESSION_DRIVER缓存与会话驱动默认 file,不依赖 Redis;如需 Redis 再改 REDIS_*
STATIC_CRON_TOKEN定时任务触发口令恰好 32 字符;cron 服务与主程序 /api/v1/cron/<token> 共用
MAIL_MAILER=log邮件驱动log 表示邮件写入日志(离线环境首选,注册确认邮件可在日志中看到);生产改 smtp 并补 MAIL_HOST/MAIL_FROM 等
TRUSTED_PROXIES可信代理直接暴露端口时留空;置于反向代理之后时填代理网段

4.4 编写 docker-compose.yml

在 /opt/firefly-iii/docker-compose.yml 写入以下编排(基于官方 docker-compose.yml 调整:数据库换 PostgreSQL、并入 Data Importer、显式项目名与自定义网段、上传目录绑定到 /opt/firefly-iii/data/upload):

name: firefly-iii-6.7.9-stack

services:
  app:
    image: fireflyiii/core:latest
    hostname: app
    container_name: firefly-iii-6.7.9-app
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "8130:8080"
    env_file: .env
    volumes:
      - ./data/upload:/var/www/html/storage/upload

  db:
    image: postgres:16-alpine
    hostname: db
    container_name: firefly-iii-6.7.9-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: firefly
      POSTGRES_PASSWORD: q1w2e3r4
      POSTGRES_DB: firefly
      TZ: Asia/Shanghai
    volumes:
      - firefly_iii_db:/var/lib/postgresql/data

  cron:
    image: alpine
    restart: unless-stopped
    container_name: firefly-iii-6.7.9-cron
    env_file: .env
    command: ["sh", "-c", "apk add tzdata >/dev/null 2>&1 && \
      (ln -s /usr/share/zoneinfo/$$TZ /etc/localtime || true) && \
      echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/$$STATIC_CRON_TOKEN;echo\" \
      | crontab - && \
      crond -f -L /dev/stdout"]
    depends_on:
      - app

  importer:
    image: fireflyiii/data-importer:latest
    hostname: importer
    container_name: firefly-iii-6.7.9-importer
    restart: unless-stopped
    depends_on:
      - app
    ports:
      - "8133:8080"
    environment:
      FIREFLY_III_URL: http://app:8080
      TZ: Asia/Shanghai

volumes:
  firefly_iii_db:

networks:
  default:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.57.0/24

逐项说明:

  • name: 显式指定编排项目名 firefly-iii-6.7.9-stack——这是多套部署共存时的关键项,默认项目名取自目录名,同名目录会被相互覆盖;
  • app 的 env_file: .env 让主程序读到 4.3 的全部变量;db 的三个 POSTGRES_* 与 .env 中 DB_* 必须一致;
  • 数据库数据放命名卷 firefly_iii_db(随项目生命周期管理),主程序上传附件目录绑定到宿主 ./data/upload(升级镜像时附件不丢,且备份时可直接打包该目录);
  • cron 是官方编排原样保留的定时任务器:每天 03:00 调用 http://app:8080/api/v1/cron/$STATIC_CRON_TOKEN,驱动自动预算、循环交易等后台作业;
  • importer 的 FIREFLY_III_URL 指向编排内主程序服务名 http://app:8080(编排内 DNS 解析);
  • 数据库端口不发布到宿主机,只在编排网络内可见,缩小攻击面。

4.5 启动并观察迁移

cd /opt/firefly-iii && docker compose up -d

启动耗时约 30–40 秒(首次需执行全量数据库迁移)。用 docker compose logs -f 跟踪,直到出现"Thank you for installing Firefly III"横幅(实测日志节选):

$ docker compose logs -f app
  [i] Wait for the database. You may see an error about an 'aborted connection', this is normal.
wait-for-it.sh: waiting 60 seconds for db:5432
wait-for-it.sh: db:5432 is available after 1 seconds
  [✓] DB is up.
  [i] Will run database commands.
  [i] CreateDB does not apply to "pgsql", skipped.
  [i] Will run upgrade commands.
  [✓] Connected to the database.

   INFO  Preparing database.

  Creating migration table ....................................... 8.25ms DONE

   INFO  Running migrations.
(迁移输出节选——数十条表创建记录)
  [11:11:47] Command firefly-iii:report-integrity took 0.0040 seconds.
  [11:11:47] Command firefly-iii:correct-database took 0.5900 seconds.
  [i] Encryption keys exist already.
  [i] Updated version.
  [✓] No security alerts for version 6.7.9

+------------------------------------------------------------------------------+
| Thank you for installing Firefly III, v6.7.9!                                |
| There are no extra installation instructions.                                |
| Firefly III should be ready for use.                                         |
+------------------------------------------------------------------------------+
[28-Oct-2026 11:11:49] NOTICE: fpm is running, pid 210
[28-Oct-2026 11:11:49] NOTICE: ready to handle connections
✅ NGINX + PHP-FPM is running correctly.

确认四个服务全部就位(实测回显):

$ docker compose ps
NAME                        IMAGE                             STATUS                  PORTS
firefly-iii-6.7.9-app       fireflyiii/core:latest            Up 2 minutes (healthy)  0.0.0.0:8130->8080/tcp
firefly-iii-6.7.9-cron      alpine                            Up 2 minutes
firefly-iii-6.7.9-db        postgres:16-alpine                Up 2 minutes            5432/tcp
firefly-iii-6.7.9-importer  fireflyiii/data-importer:latest   Up 2 minutes (healthy)  0.0.0.0:8133->8080/tcp

4.6 验证 Web 入口

浏览器访问 http://192.168.146.128:8130,无用户时会引导到注册页创建第一个管理员。命令行验证(实测回显):

$ curl -sI http://192.168.146.128:8130/ | head -6
HTTP/1.1 302 Found
Server: nginx
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Cache-Control: no-cache, private
Date: Wed, 28 Oct 2026 03:12:34 GMT

(302 重定向到登录/注册流程属预期行为。)

4.7 注册管理员并完成首启向导

  1. 打开 http://192.168.146.128:8130/register,填入邮箱 admin@firefly.local 与密码。⚠️ 密码策略:至少 16 个字符——实测用 8 位演示口令 q1w2e3r4 注册被服务端拒绝,回显 The password must be at least 16 characters.;本文改用满足策略的 q1w2e3r4q1w2e3r4(生产环境请用更强的独立密码)。
  2. 注册成功后自动登录并跳转首启向导(/new-user,"Welcome to Firefly III!"页面)。填写"银行名称"(如 Demo Bank)并提交,向导会自动创建三个演示资产账户与对应期初余额交易。
  3. 实测向导完成后数据库中创建的账户(psql 查询回显):
$ docker exec firefly-iii-6.7.9-db psql -U firefly -c "select a.id, a.name, t.type from accounts a join account_types t on a.account_type_id = t.id order by a.id limit 15;"
 id |                      name                       |          type
----+-------------------------------------------------+-------------------------
  1 | Demo Bank                                       | Asset account
  2 | Initial balance for "Demo Bank"                 | Initial balance account
  3 | Demo Bank savings account                       | Asset account
  4 | Initial balance for "Demo Bank savings account" | Initial balance account
  5 | Cash wallet                                     | Asset account
(5 rows)

💡 说明:期初余额(Initial balance)账户是复式记账的"账外源头"——期初余额交易的资金从它流入资产账户,这是 Firefly III 表达"开户时已有多少钱"的标准方式。

4.8 签发 API 静态令牌(Personal Access Token)

API 调用需要静态令牌。实测流程:登录后进入个人资料页(Profile),在"OAuth / Personal access tokens"处新建令牌。⚠️ 实测全新部署直接创建会报 500(排障实录见 10.3),需先在服务器上补建一次 Passport personal client:

$ docker exec firefly-iii-6.7.9-app php artisan passport:client --personal --name='firefly-cli' --no-interaction

   INFO  New client created successfully.

之后页面创建令牌成功,得到一长串 JWT 形态令牌,用于 Authorization: Bearer <token> 调用 API(实测冒烟):

$ curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" http://192.168.146.128:8130/api/v1/about
{"data":{"version":"6.7.9","api_version":"6.7.9","php_version":"8.5.12","os":"Linux","driver":"pgsql"}}

4.9 配置 Data Importer 对接

导入器已在编排内随栈启动(8133 端口)。对接需要主程序侧创建一个 OAuth 客户端:主程序 Web 界面 → Profile → OAuth → Create new client,名称如 data-importer,重定向 URI 填 http://192.168.146.128:8133/client-callback。实测通过 API 创建的返回(节选):

{"name":"data-importer","revoked":false,"redirect_uris":["http://192.168.146.128:8133/client-callback"],
 "grant_types":["authorization_code","refresh_token"],"owner_id":1,
 "id":"01a18085-648d-7025-87cd-92e8dc38cc7f",
 "plainSecret":"VoMN8Grt1x8PG95hWDZppW1xD8BDC03D1Q...(演示值节选)"}

把 id(client id)与 plainSecret(client secret,仅创建时完整返回一次)填入导入器 8133 页面的设置页即可。CSV 导入操作实测见《Firefly III 常用命令与运维实战》第六章。

五、数据持久化说明

Firefly III 的状态分两处,编排中分别处理:

数据存放编排配置说明
业务数据(账户/交易/规则/预算等全部结构化数据)PostgreSQL 数据目录命名卷 firefly_iii_db → /var/lib/postgresql/data最重要的状态,备份走 pg_dump
上传附件/导出文件/var/www/html/storage/upload绑定目录 ./data/upload → 宿主 /opt/firefly-iii/data/upload镜像升级不丢附件
会话/缓存容器内文件(file 驱动)未持久化重启后需重新登录,属预期行为

持久化实测:整栈 docker compose down(不删卷)再 up -d,管理员账号、API 令牌、资产账户全部保留,令牌直连 API 依旧有效(实测回显见 4.8;重启后 docker compose ps 四服务全部 Up,见 4.5 同款回显)。注意:down 不带 -v 不会删除命名卷;down -v 会连数据库一起删除,属销毁性操作。

六、环境变量表

主程序支持数百个 .env 变量,完整清单见部署目录内官方模板(主程序仓库 .env.example)。本部署实际使用的 26 个变量、默认值与影响面:

变量实测取值默认值作用与改动影响
APP_ENVproductionproduction运行环境标识,保持 production
APP_DEBUGfalsefalse调试模式;生产必须 false(true 会暴露堆栈)
SITE_OWNERadmin@firefly.localmail@example.com站点管理员邮箱,错误报告收件人
APP_KEY(32 位随机串)无加密密钥,首次启动后不可更换
APP_URLhttp://192.168.146.128:8130—对外基准地址,页面链接由它拼接
DEFAULT_LANGUAGEen_USen_US新用户默认语言(界面支持含简体中文在内的多语言)
DEFAULT_LOCALEequalequal数字/日期本地化格式,equal 表示跟随语言
TZAsia/ShanghaiEurope/Amsterdam时区
TRUSTED_PROXIES(空)(空)反向代理场景填代理网段
LOG_CHANNELstackstack日志通道;日志文件在容器内 /var/www/html/storage/logs/laravel.log
APP_LOG_LEVELnoticenotice应用日志级别
AUDIT_LOG_LEVELemergencyemergency审计日志级别(默认几乎不记)
DB_CONNECTIONpgsqlmysql数据库驱动;pgsql/mysql/sqlite
DB_HOSTdbdb编排内数据库服务名
DB_PORT54323306数据库端口(PostgreSQL 5432)
DB_DATABASEfireflyfirefly库名
DB_USERNAMEfireflyfirefly账号
DB_PASSWORD(与 POSTGRES_PASSWORD 一致)secret_firefly_password口令;首次启动落库后不可再改(官方文档明确警示)
PGSQL_SCHEMApublicpublicPostgreSQL schema 名
CACHE_STOREfilefile缓存驱动(file 不依赖 Redis)
SESSION_DRIVERfilefile会话驱动
STATIC_CRON_TOKEN(32 位随机串)无cron 入口口令,cron 服务与主程序共用
MAIL_MAILERloglog邮件驱动:log/smtp 等
MAIL_FROMchangeme@example.comchangeme@example.com发件地址
COOKIE_SECUREfalsefalseHTTPS 部署时改 true
COOKIE_SAMESITElaxlax会话 Cookie 策略

数据库侧另有三个 POSTGRES_* 变量直接写在编排里(POSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DB),与上表 DB_USERNAME/DB_PASSWORD/DB_DATABASE 一一对应。

七、配置参数说明

  • 数据库驱动切换:DB_CONNECTION=pgsql 是官方文档给出的 PostgreSQL 切换路径(MySQL 部署则为 mysql + 3306 + 挂载点 /var/lib/mysql)。切换只允许在首次启动前做;已有数据后再换驱动等于换库,需走导出/导入迁移而非改配置。
  • APP_URL 必须与实际访问地址一致:页面内生成的链接、OAuth 回调校验都基于它。实测本次部署填 http://192.168.146.128:8130,Data Importer 的回调地址也按该基准拼接(http://192.168.146.128:8133/client-callback)。
  • 邮件驱动 log 的取舍:离线/内网部署用 log,注册确认邮件写入日志而非真实发送;需要真实邮件时改 smtp 并补齐 MAIL_HOST/MAIL_PORT/MAIL_USERNAME/MAIL_PASSWORD。
  • Redis 可选:默认 file 缓存/会话即可运行;多实例或高并发场景再引入 CACHE_STORE=redis + REDIS_HOST/REDIS_PORT。
  • 参数级详解(认证 OIDC/SAML、静态令牌、审计日志、邮件全套等逐项展开)见本专栏配置参数详解篇(发布后此处更新为站内链接)。

八、配置文件挂载

本部署的挂载面很小,全部盘点如下:

编排内路径宿主侧用途
/var/www/html/storage/upload/opt/firefly-iii/data/upload(绑定)上传附件、导入/导出文件
/var/lib/postgresql/data命名卷 firefly_iii_db全部业务数据
/etc/nginx/nginx.conf 等未挂载主程序镜像内置 nginx,按需进容器改模板变量
.env/opt/firefly-iii/.env(env_file 注入)主程序配置源

验证挂载生效(实测回显):

$ docker exec firefly-iii-6.7.9-app ls -ld /var/www/html/storage/upload
drwxr-xr-x 3 www-data www-data 4096 Oct 28 10:53 /var/www/html/storage/upload
$ ls -l /opt/firefly-iii/data/upload
total 8
drwxr-xr-x 3 www-data www-data 4096 Oct 28 10:53 .

💡 说明:Firefly III 的业务数据不存文件而存数据库,upload 目录只承载附件与导入导出文件——因此备份主战场是 pg_dump,upload 目录是次要补充(组合备份命令见《Firefly III 常用命令与运维实战》第七章)。

九、等价 docker run

不用 Compose 时,可用等价的 docker 命令逐个启动(效果等同 4.4 编排的最小子集:主程序 + 数据库)。先建网络与卷:

docker network create --subnet 10.89.57.0/24 firefly-iii-net
docker volume create firefly_iii_db
docker volume create firefly_iii_upload

启动数据库(实测等价命令):

docker run -d --name firefly-iii-6.7.9-db \
  --network firefly-iii-net \
  -e POSTGRES_USER=firefly \
  -e POSTGRES_PASSWORD=q1w2e3r4 \
  -e POSTGRES_DB=firefly \
  -v firefly_iii_db:/var/lib/postgresql/data \
  --restart unless-stopped \
  postgres:16-alpine

启动主程序(DB_HOST 指向网络内的数据库容器名;APP_KEY 用 4.2 生成的 32 位串):

docker run -d --name firefly-iii-6.7.9-app \
  --network firefly-iii-net \
  -p 8130:8080 \
  -e APP_KEY=CqRn77wKahWp5Bsnwogd4wbgBrXKU9Rw \
  -e APP_URL=http://192.168.146.128:8130 \
  -e DB_CONNECTION=pgsql \
  -e DB_HOST=firefly-iii-6.7.9-db \
  -e DB_PORT=5432 \
  -e DB_DATABASE=firefly \
  -e DB_USERNAME=firefly \
  -e DB_PASSWORD=q1w2e3r4 \
  -v firefly_iii_upload:/var/www/html/storage/upload \
  --restart unless-stopped \
  fireflyiii/core:latest

💡 说明:官方文档的"Plain Docker"路径即此形态(镜像 fireflyiii/core:latest、上传卷固定挂 /var/www/html/storage/upload)。与 Compose 相比缺了定时任务器与导入器,长驻部署仍建议用第 4.4 的完整编排。

十、常用运维命令

均在部署目录 /opt/firefly-iii 下执行(实测命令,回显见前文对应段落):

docker compose ps                  # 四服务状态(含健康检查)
docker compose logs -f app         # 跟踪主程序日志(迁移/启动/错误)
docker compose restart app         # 只重启主程序(改 .env 后必须做)
docker compose up -d               # 增量应用编排变更
docker compose down                # 停止并移除四服务(保留命名卷)
docker compose down -v             # ⚠️ 销毁性:连数据库命名卷一起删除
docker exec firefly-iii-6.7.9-app php artisan firefly-iii:output-version   # 版本

改 .env 后的生效顺序:docker compose restart app → 重新登录 → 验证。升级版本:把 image: 的 latest 换成目标版本 tag(或保持 latest)后 docker compose pull && docker compose up -d,首次启动自动执行升级迁移。

十一、常见问题(FAQ)

Q1:注册时提示密码太短? Firefly III v6 服务端密码策略为至少 16 个字符。实测 8 位口令 q1w2e3r4 被拒,回显 The password must be at least 16 characters.。用满足长度的密码即可;该策略无内置开关,属固定约束。

Q2:docker pull 报"这镜像不在白名单"(allowlist)? 镜像有两个命名空间:fireflyiii/core(官方 compose 文件使用)与 firefly-iii/core(新组织名)。部分国内镜像加速通道(如 DaoCloud 公共镜像)对不在白名单的仓库直接拒绝。实测使用官方编排写的 fireflyiii/core:latest 与 fireflyiii/data-importer:latest 可正常拉取。排障顺序:核对镜像名拼写 → 换用官方 compose 中的命名空间 → 直连 docker.io 或更换加速器。

Q3:创建 API 静态令牌报 500"Personal access client not found"? 全新部署首次创建 PAT 时的已知坑:Passport 尚无 personal access client。服务器上补建一次即可(实测回显见 4.8):

docker exec firefly-iii-6.7.9-app php artisan passport:client --personal --name='firefly-cli' --no-interaction

补建后无需重启,页面再次创建即成功。该客户端只建一次,随数据库持久化。

Q4:首次启动后改了 DB_PASSWORD 连不上库? 官方文档明确警示:密码在首次运行时写入数据卷,之后改配置只会导致认证失败。正确做法是首次启动前定稿密码;已落库后必须进入 PostgreSQL 改库内口令同步,或删卷重建(销毁性)。

Q5:改了 .env 不生效? .env 通过 env_file 在容器创建时注入,修改后必须 docker compose restart app(或 up -d 重建)才生效;其中 APP_KEY 例外——任何时候都不应更换,更换会导致既有加密数据不可读与全端登录态失效(实测演练见《Firefly III 常用命令与运维实战》第十一章)。

十二、参考链接