InvoiceShelf 2.4.7 配置参数详解

InvoiceShelf 2.4.7 配置体系详解:.env 全参数分组逐项说明、APP_KEY/DB/会话域/PDF 引擎/调度/邮件取值与默认值实测,settings 业务配置层实测,生产配置模板与生效排障。

InvoiceShelf配置自托管发票管理2026/10/24

InvoiceShelf 2.4.7 配置参数详解

目标:讲清 InvoiceShelf 2.4.7 的配置体系——.env 文件全部参数的取值、默认值与影响面,数据库侧的业务配置层(settings/company_settings),以及参数的查看、修改与验证方法。已在 InvoiceShelf 2.4.7(PHP 8.4.27 / Laravel 13.15.0,SQLite 与 MariaDB 双形态)实测通过。

一、环境信息

本文实测环境与取证来源:

  • 应用版本:InvoiceShelf 2.4.7(stable,2026-10-21 发布;GET /api/v1/app/version 与应用内 settings 表 version=2.4.7 双重实测确认)
  • 运行时:PHP 8.4.27、Laravel Framework 13.15.0(php artisan about 实测)
  • 数据库形态:SQLite 3.53.4(连接名 sqlite)与 MariaDB 11.8.9(连接名 mysql)两套均实测
  • 参数溯源:应用根目录 .env 与 .env.example(上游仓库 2.4.7 tag,2026-10-24 取证)逐键比对;config/ 目录默认值用 php artisan config:show <名> 实测
  • 部署形态细节(Compose 环境变量注入)见 《InvoiceShelf Docker Compose 部署指南》,本文聚焦参数本身,两种部署形态下 .env 参数完全一致

二、前置条件

  1. 已有一套可运行的 InvoiceShelf 2.4.7(部署方法见本专栏《InvoiceShelf Docker Compose 部署指南》),本文的查看与验证命令都需要在应用根目录执行;
  2. 运行应用的用户对 .env 有读写权限(.env 含加密密钥,建议权限收紧为 600);
  3. 修改参数前建议先备份:cp .env .env.bak;
  4. 若系统曾执行过 php artisan config:cache(或部署层开启了 AUTORUN_LARAVEL_OPTIMIZE),改 .env 前须知:配置缓存会屏蔽 .env 的后续修改,必须先 php artisan config:clear(见第三章 3.3)。

三、参数查看与修改方式

3.1 配置的三层结构

InvoiceShelf 的配置分三层,排障与改参数前先分清目标在哪一层:

层载体管理方式典型内容
框架/运行时层应用根目录 .env 文件文本编辑 + 清缓存数据库连接、会话域名、缓存驱动、PDF 引擎、调度开关
框架默认值config/*.php一般不动,.env 覆盖邮件传输参数、队列连接、缓存存储定义
业务配置层数据库 settings/company_settings 表Web 后台界面公司信息、发票编号规则、邮件模板、税制币种、报表

💡 说明:第一层与第三层的分界可以概括为「服务怎么连」在 .env,「业务怎么开」在数据库。例如同样与邮件相关:SMTP 服务器地址属于传输层配置在 .env,而发票邮件的正文模板、附件开关、发件人展示地址属于业务配置在后台改(第六章实测展示了库内真实键值)。

3.2 查看参数:artisan config:show 与 about

查看某一组配置的实际生效值(合并 .env 与默认值之后),用 config:show:

cd /var/www/html && php artisan config:show session

实测回显:


  session ....................................................................
  driver ................................................................ file
  lifetime ............................................................... 240
  expire_on_close ...................................................... false
  encrypt .............................................................. false
  files ........................................... storage/framework/sessions
  connection ............................................................ null
  table ............................................................. sessions
  store ................................................................. null
  lottery ⇁ 0 .............................................................. 2
  lottery ⇁ 1 ............................................................ 100
  cookie ................................................ invoiceshelf_session
  path ..................................................................... /
  domain ........................................................... localhost
  secure ................................................................ null

要点:driver=file、lifetime=240、domain=localhost 正是部署时 .env 注入的三个值,说明 config:show 反映的就是合并后的生效值,核对参数是否生效以它为准。不带文件名时可用 php artisan about 一次看全应用概貌:

php artisan about

实测回显:


  Environment ................................................................
  Application Name .............................................. InvoiceShelf
  Laravel Version .................................................... 13.15.0
  PHP Version ......................................................... 8.4.27
  Composer Version .................................................... 2.10.3
  Environment ..................................................... production
  Debug Mode ............................................................. OFF
  URL ......................................................... localhost:8129
  Maintenance Mode ....................................................... OFF
  Timezone ............................................................... UTC
  Locale .................................................................. en

  Cache ......................................................................
  Config .......................................................... NOT CACHED
  Events .......................................................... NOT CACHED
  Routes .......................................................... NOT CACHED
  Views ............................................................... CACHED

  Drivers ....................................................................
  Broadcasting .......................................................... null
  Cache ................................................................. file
  Database ............................................................ sqlite
  Logs ........................................................ stack / single
  Mail ................................................................... log
  Queue ................................................................. sync
  Session ............................................................... file

  Storage ....................................................................
  public/storage ...................................................... LINKED

Drivers 区块是速查重点:Database/Cache/Session/Mail/Queue 五个运行驱动的当前值一目了然(默认部署下 Mail=log、Queue=sync,见 5.4 与 5.7 的展开)。

3.3 修改参数与生效验证(含一次实测排障)

.env 的标准修改流程(以把会话有效期从 240 分钟改为 480 分钟为例):

cd /var/www/html
cp .env .env.bak
sed -i 's/^SESSION_LIFETIME=240/SESSION_LIFETIME=480/' .env
php artisan config:clear

实测回显:


   INFO  Configuration cache cleared successfully.

验证生效:

php artisan config:show session | grep lifetime

实测回显(随官方打包部署的环境):

  lifetime ............................................................... 240

值没有变成 480——这是一次有价值的实测排障:Laravel 读取配置的优先级是「系统真实环境变量 > .env 文件」,本环境部署时已通过部署层注入了 SESSION_LIFETIME=240 环境变量,因此只改 .env 文件不生效。结论分两种部署形态:

  • 随官方打包部署:改参数必须改部署层的变量定义(Compose 文件 environment: 段,见部署篇第八章),改完重建应用服务生效;
  • 手动部署的服务器(系统里不存在同名环境变量):同一流程修改 .env 后值即为 480,config:clear 后立即生效。

除优先级外还有一条生效规则:若 php artisan about 显示 Config: CACHED(执行过 config:cache 或打包层开启了启动优化),配置缓存会屏蔽 .env 的后续修改,必须先 php artisan config:clear——这是「改了配置没反应」的另一常见原因。实验结束恢复原值并清缓存:

mv /var/www/html/.env.bak /var/www/html/.env && php artisan config:clear

实测回显:


   INFO  Configuration cache cleared successfully.

3.4 APP_KEY 的生成与保留

APP_KEY 是应用级加密密钥(会话加密、敏感字段加密都依赖它),首次安装时向导自动生成。手工部署或丢失时可用 artisan 重新生成:

php artisan key:generate --show

--show 只显示不写入;去掉 --show 才会写入 .env。实测每次调用的返回值都是随机新串(以下为实测回显):

base64:h7V9ad337ERB04nAc/qP0xSjpgt/8pxqzjH695/lvjc=

⚠️ 迁移服务器、重建部署时必须原样保留旧 APP_KEY,换新密钥会使既有会话与加密数据不可解。

四、参数总览

以官方 .env.example(2.4.7)与应用内生效 .env 实测逐键比对,全部参数分组如下(「默认值」列以 .env.example 与 config:show 实测为准):

应用基础组:

参数默认值作用
APP_ENVproduction运行环境标识,影响报错展示与日志级别
APP_DEBUGfalse调试模式;开启后报错页暴露源码路径与配置,生产必须 false
APP_KEY(空,向导生成)加密密钥,base64 串
APP_NAMEInvoiceShelf应用名(页面标题、邮件抬头)
APP_TIMEZONEUTC框架层时区(业务展示时区在后台按公司设置,见第六章)
APP_URL(空,必填)对外访问地址,含协议与端口
APP_LOCALEen界面语言(翻译文件可用值见官方 Crowdin 项目)

数据库组:

参数SQLite 默认外部库(MySQL/MariaDB/PostgreSQL)作用
DB_CONNECTIONsqlitemysql / mariadb / pgsql连接驱动
DB_HOST(空)数据库主机名服务地址
DB_PORT(空)3306(MySQL 系)/ 5432(PG)服务端口
DB_DATABASE/var/www/html/storage/app/database.sqlite库名SQLite 为文件路径,外部库为库名
DB_USERNAME / DB_PASSWORD(空)数据库账号/口令外部库凭据

会话与安全组:

参数默认值作用
SESSION_DRIVERfile会话存储驱动(file/database/redis)
SESSION_LIFETIME240会话有效期(分钟)
SESSION_DOMAINnull会话 Cookie 域,须与访问域名一致
SANCTUM_STATEFUL_DOMAIN / SANCTUM_STATEFUL_DOMAINS(空)Sanctum 有状态域(SPA 登录会话),须含端口
TRUSTED_PROXIES*信任的反向代理网段,生产建议收敛到代理实际网段

缓存/队列组:

参数默认值作用
CACHE_STOREfile应用缓存驱动(实测 config:show cache 生效值 file)
QUEUE_CONNECTIONsync队列驱动(实测 config:show queue 生效值 sync)

PDF 与调度组(默认在 .env 中以注释形式提供,见 5.5/5.6):

参数默认值作用
DOMPDF_ENABLE_REMOTEfalsedompdf 远程资源加载开关(SSRF 防护)
PDF_DRIVERdompdfPDF 引擎选择
GOTENBERG_HOST(注释)Gotenberg 服务地址
GOTENBERG_PAPERSIZE(注释)Gotenberg 纸张尺寸
GOTENBERG_ALLOWED_PRIVATE_HOST(注释)内网 Gotenberg 主机白名单
SCHEDULER_ENABLEDtrue打包形态内置调度器开关
CRON_JOB_AUTH_TOKEN(空)外部 cron 兜底调用的鉴权令牌

打包形态专用组(仅随官方打包部署注入时生效,手动部署可忽略):

参数默认值作用
AUTORUN_ENABLEDtrue启动自动引导总开关
AUTORUN_LARAVEL_MIGRATIONfalse启动时自动执行数据库迁移
AUTORUN_LARAVEL_OPTIMIZEfalse启动时自动执行 php artisan optimize
PHP_OPCACHE_ENABLE1PHP OPcache 开关
CONTAINERIZEDtrue打包形态标记(影响部分自动行为判断)

总览解读:日常部署需要动的只有「应用基础组的 APP_URL/SESSION_DOMAIN/SANCTUM_STATEFUL_DOMAINS」与「数据库组」共七八个键;其余保持默认。下面各子节对每组展开。

五、核心参数分类详解

5.1 应用基础:APP_* 系列

本组定义应用身份与环境边界,是修改频率最高的一组。逐项说明:

  • APP_ENV=production:框架据此决定错误处理与部分默认行为。误设为 local/dev 时报错页会直接堆栈外泄,上线前必须核对;
  • APP_DEBUG=false:调试开关。生产铁律为 false。开启时任何报错都会向访问者展示完整堆栈、环境变量名(含密钥名)与文件路径;
  • APP_KEY=base64:…:如 3.4 所述,安装时生成,迁移必带;
  • APP_URL:必须与实际访问地址完全一致(含协议与端口)。实测环境为 http://localhost:8129;若经 HTTPS 域名反代访问则应为 https://invoice.example.com。该值同时决定:安装向导与登录页的跳转目标、发票/邮件里生成的链接、以及会话域校验的基准。与实际不符时最典型症状是登录后 302 回登录页(官方 issue #213 专述);
  • APP_TIMEZONE=UTC:框架层时区(日志、定时任务基准)。业务层展示时区独立——在后台「设置→公司信息」按公司设置,两层互不覆盖。跨时区团队建议保持 UTC 基准 + 业务层本地化;
  • APP_LOCALE=en:界面语言。改为 zh_CN 等值前确认对应语言包存在(官方经 Crowdin 维护翻译)。

5.2 数据库连接:DB_* 系列

驱动与取值随部署变体而定,两种实测形态的真实 .env 数据库段如下。

SQLite 形态(单文件,零外部依赖):

DB_CONNECTION=sqlite
DB_HOST=
DB_PORT=
DB_DATABASE=/var/www/html/storage/app/database.sqlite
DB_USERNAME=
DB_PASSWORD=

外部数据库形态(MariaDB 11.8.9 实测,MySQL/PostgreSQL 同构):

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=invoiceshelf
DB_USERNAME=invoiceshelf
DB_PASSWORD=invoiceshelf_secret

要点:

  • SQLite 的 DB_DATABASE 是绝对路径,官方明确「请勿随意改动」——该文件在应用存储目录内,改路径会脱离持久化目录导致数据「丢失」(实为落在了未持久化的位置);
  • 外部库的 DB_HOST 用主机名而非 IP(打包形态下为服务名,自建为数据库服务器域名),IP 会随基础设施变动失效;
  • DB_PASSWORD_FILE 是打包形态支持的口令文件变体(从文件读口令,避免明文),手动部署不用;
  • 换驱动属于迁移操作:改连接参数后需执行 php artisan migrate 初始化新库结构,再用数据导出导入搬数据(见本专栏《InvoiceShelf 2.4.7 常用 CLI 命令与工具详解》 migrate 族命令)。

5.3 会话与跨域安全:SESSION_/SANCTUM_/TRUSTED_PROXIES

这一组决定了「能不能登录成功」,是自托管部署第一常见坑。三个值必须构成一致的访问基准(实测环境统一为 localhost:8129):

APP_URL=http://localhost:8129
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8129
  • SESSION_DRIVER=file:会话文件落在存储目录的 framework/sessions/ 下。多实例共享会话时应改为 database(官方已建 sessions 表结构)或 redis;
  • SESSION_LIFETIME=240:240 分钟(4 小时)登录有效期,实测生效值经 config:show session 确认;
  • SESSION_DOMAIN:Cookie 的 Domain 属性。IP 访问填 IP 或 localhost,域名访问填该域名(不带协议);
  • SANCTUM_STATEFUL_DOMAINS:Sanctum 认为「同源 SPA」的域清单,必须带端口,多域逗号分隔。管理端 Web 界面的登录会话依赖它;与 APP_URL/SESSION_DOMAIN 不一致时,典型症状为 CSRF token mismatch.(实测故意错配即可复现);
  • TRUSTED_PROXIES="*":信任全部代理。官方默认值为开放配置,便于初次经反代部署即通;生产加固应改为反代的实际网段(如 10.0.0.0/8),防止伪造 X-Forwarded-* 头欺骗来源判定。

5.4 缓存与队列:CACHE_STORE / QUEUE_CONNECTION

  • CACHE_STORE=file:默认文件缓存(实测生效值 file)。可选 database(复用业务库,免额外组件)、redis(多实例共享缓存时的标准选择,上游依赖 predis 已内置)。单实例部署 file 即可,无需为缓存引入 Redis;
  • QUEUE_CONNECTION=sync:默认同步队列——邮件发送等任务在请求内直接执行(实测 config:show queue 生效值 sync)。任务量小无感知;如果后续启用大批量群发或接入重队列,建议改 database 驱动并以 php artisan queue:work(或打包形态的第二实例)常驻消费,失败任务可用 queue:failed/queue:retry 管理(命令详解见本专栏《InvoiceShelf 2.4.7 常用 CLI 命令与工具详解》)。

5.5 PDF 引擎与 SSRF 防护:DOMPDF_/PDF_DRIVER/GOTENBERG_

InvoiceShelf 支持双 PDF 引擎,.env.example 中以带注释的配置段提供(注释原文翻译见下):

# Dompdf: 保持 false,使 PDF 备注中的不可信 HTML 无法触发对外请求(SSRF)。
# 仅当你完全信任 PDF HTML 且需要远程图片/CSS 时才设为 true。
DOMPDF_ENABLE_REMOTE=false

# Gotenberg(可选的替代 PDF 驱动;默认是 dompdf)。
# PDF_DRIVER=gotenberg
# GOTENBERG_HOST=http://pdf:3000
# GOTENBERG_PAPERSIZE="210mm 297mm"
#
# Gotenberg 通常作为内网旁路服务部署,会被 SSRF 防护拒绝。
# 需要把该主机名加入豁免——且仅豁免这一个主机。其余内网目标保持拦截。
# GOTENBERG_ALLOWED_PRIVATE_HOST=http://pdf:3000

逐项解读:

  • DOMPDF_ENABLE_REMOTE=false:默认关闭远程资源加载。发票模板允许用户自定义 HTML 备注,开启后攻击者可借「生成发票」让服务器向内网发请求(SSRF),因此除非完全信任模板来源,保持 false;
  • PDF_DRIVER=gotenberg:切换到 Gotenberg 引擎(基于 Chromium 的独立渲染服务),排版还原度高于内置 dompdf,适合复杂版式与中文票据场景。启用需同时部署 Gotenberg 服务并在 GOTENBERG_HOST 指向它;
  • GOTENBERG_ALLOWED_PRIVATE_HOST:SSRF 防护的白名单例外项——Gotenberg 一般部署在内网,默认会被「禁止访问私网地址」的防护拦截,此键把唯一的 Gotenberg 主机加入豁免,其余内网目标继续拦截;
  • 不部署 Gotenberg 时以上 Gotenberg 键全部保持注释即可。

5.6 调度与定时任务:SCHEDULER_ENABLED / CRON_JOB_AUTH_TOKEN

周期发票生成、逾期标记、报价过期由 Laravel 调度器驱动(实测 schedule:list 列出三条任务:每日 check:invoices:status、check:estimates:status 与每分钟 recurring-invoices:generate)。.env.example 注释明确了三种驱动方式与对应参数:

  1. 打包形态内置调度器(默认):SCHEDULER_ENABLED=true,与 Web 服务同进程托管;多副本部署时只保留一个副本为 true,避免重复生成;
  2. 传统服务器 crontab:注释原文给出的标准写法为 * * * * * cd /path/to/invoiceshelf && php artisan schedule:run >> /dev/null 2>&1,手动部署(无内置调度器)时配置;
  3. 外部 HTTP 兜底:以上两种都不可用时,设 CRON_JOB_AUTH_TOKEN=<随机令牌>,由任意外部定时服务每分钟调用 GET /api/cron 并携带 x-authorization-token: <同一令牌> 请求头触发调度。

💡 说明:三种方式等价触发同一套调度任务,选其一即可,重复叠加会造成周期发票重复生成。判断当前由谁驱动的实用方法:php artisan schedule:list 看任务清单是否在、应用日志中每分钟是否有 recurring-invoices:generate 执行记录。

5.7 邮件发送:MAIL_* 系列

邮件传输层沿用 Laravel 标准参数(config/mail.php 读取,未列入 InvoiceShelf 的 .env.example,按 Laravel 13 惯例溯源)。实测默认态(部署后未配置邮件时):

php artisan config:show mail | head -8

实测回显:


  mail .......................................................................
  default ................................................................ log
  mailers ⇁ smtp ⇁ transport ............................................ smtp
  mailers ⇁ smtp ⇁ encryption ........................................... none
  mailers ⇁ smtp ⇁ scheme ............................................... null
  mailers ⇁ smtp ⇁ url .................................................. null
  mailers ⇁ smtp ⇁ host ............................................ 127.0.0.1
  mailers ⇁ smtp ⇁ port ................................................. 2525

解读与推荐配置:

  • 默认 MAIL_MAILER=log:发信内容写入日志而不真发,便于初始验证;真实发信需在 .env 增加:MAIL_MAILER=smtp、MAIL_HOST=smtp.example.com、MAIL_PORT=587、MAIL_USERNAME=…、MAIL_PASSWORD=…、MAIL_ENCRYPTION=tls、MAIL_FROM_ADDRESS=billing@example.com、MAIL_FROM_NAME="${APP_NAME}";
  • 业务侧邮件项不在 .env:发件展示地址(实测库内 notification_email=noreply@invoiceshelf.com 种子值)、发票/报价/收款的邮件正文模板、随信附件开关,都在后台设置中管理(存储于 company_settings 表,见第六章);
  • 配置后验证:先在后台用「发送测试邮件」功能,或临时把 MAIL_MAILER=log 观察日志内容核对收件人与正文模板是否生效。

5.8 打包形态专用变量

AUTORUN_ENABLED、AUTORUN_LARAVEL_MIGRATION、AUTORUN_LARAVEL_OPTIMIZE、PHP_OPCACHE_ENABLE、CONTAINERIZED 五个键只在随官方打包部署(由部署层注入环境变量)时被读取,用于控制启动自动迁移、启动优化与 OPcache(取值与行为逐项表见部署篇第八章)。手动部署的服务器上它们没有执行方,出现在 .env 中也不会产生效果——手动部署的等价操作是在启动脚本/系统服务单元里自行决定是否执行 php artisan migrate 与 php artisan optimize。

六、数据库配置层:settings 与 company_settings 实测

业务配置存在数据库两张表里,经 Web 后台修改,改它们不需要碰 .env,也不需要重启应用。以下为实测库内真实键值(SQLite 形态,PDO 直查):

全局表 settings(全应用一份)实测仅 3 键:

optionvalue(实测)说明
version2.4.7安装时的应用版本号(升级程序用它判断迁移)
profile_completeCOMPLETED安装向导完成标记
updater_channelstable应用内更新通道(stable/beta)

公司级表 company_settings(按公司隔离,多公司各有独立一份)实测业务键(节选):

optionvalue(实测)说明
invoice_auto_generate / payment_auto_generate / estimate_auto_generateYES发票/收款/报价单号自动编号开关
save_pdf_to_diskNO发送/生成时是否同时把 PDF 落盘存储
invoice_mail_bodyYou have received a new invoice from <b>{COMPANY_NAME}…发票邮件正文模板(支持占位符)
estimate_mail_body / payment_mail_body同构模板报价/收款邮件模板
notification_emailnoreply@invoiceshelf.com通知类邮件的发件展示地址(部署后应改为自有域名地址)
invoice_email_attachment / estimate_email_attachment / payment_email_attachmentNO各类邮件是否随信附 PDF
invoice_company_address_format<h3><strong>{COMPANY_NAME}…发票页眉公司地址块 HTML 模板
invoice_billing_address_format / invoice_shipping_address_format同构模板账单/收货地址块模板

实操含义:

  1. 后台「设置」页的每一项都能在这里找到对应键,改后台即改库;排障时可直接查表核对实际值(sqlite3 storage/app/database.sqlite "select option,value from company_settings where company_id=1;",MariaDB 形态用 mysql 客户端等价查询);
  2. 多公司形态下各公司的模板/编号规则互不影响——这是与 .env 全局参数的本质区别;
  3. 修改邮件模板时保留 {COMPANY_NAME}、{INVOICE_NUMBER} 类占位符结构,替换只动文案部分。

七、生产配置模板

适用场景:2 核 4GB 内存、NVMe SSD 的单机服务器,10 人以内财务/运营使用,日均百张级发票;SQLite 单文件形态(外部数据库形态仅替换 DB 段)。

APP_ENV=production
APP_DEBUG=false
APP_KEY=base64:8QnMAxAaH7J7ofagIaqXQj9SGY/nkqtuzyrc6bW7Hxk=

APP_NAME=InvoiceShelf
APP_TIMEZONE=UTC
APP_URL=https://invoice.example.com
APP_LOCALE=en

DB_CONNECTION=sqlite
DB_DATABASE=/var/www/html/storage/app/database.sqlite

SESSION_DOMAIN=invoice.example.com
SANCTUM_STATEFUL_DOMAINS=invoice.example.com
TRUSTED_PROXIES=10.89.0.0/16

CACHE_STORE=file
SESSION_DRIVER=file
SESSION_LIFETIME=240

DOMPDF_ENABLE_REMOTE=false

CRON_JOB_AUTH_TOKEN=

模板逐项要点:

  • APP_URL 换成正式 HTTPS 域名后,SESSION_DOMAIN/SANCTUM_STATEFUL_DOMAINS 同步为该域名(不带协议;SANCTUM 项多域时逗号分隔);
  • TRUSTED_PROXIES 收敛为反向代理实际网段(示例值按内网代理填写,直连无代理时保持默认 * 或留空);
  • APP_KEY 沿用安装时生成值(示例中的值仅作格式参考,请勿照抄他人密钥);
  • 外部数据库形态把 DB 段替换为 5.2 的 MariaDB 版块即可,其余不变;
  • 邮件按 5.7 的 MAIL_* 追加段配置;启用 Gotenberg 时按 5.5 追加三键。

八、常见问题

Q1:改了 .env 完全不生效。 两个检查点:先看 php artisan about 的 Config 是否 CACHED——是则先 php artisan config:clear;再确认修改的是部署层实际读取的那份配置(打包部署时变量以环境注入优先,见 3.3 生效规则其二)。

Q2:登录页正常,登录后跳回登录页或报 CSRF token mismatch.。 APP_URL/SESSION_DOMAIN/SANCTUM_STATEFUL_DOMAINS 三者与浏览器实际访问地址不一致所致,按 5.3 对齐即可。经反代 HTTPS 访问时三处统一用域名并检查 TRUSTED_PROXIES 是否覆盖代理网段。

Q3:周期发票不自动生成 / 逾期状态不更新。 按 5.6 排查驱动方式:schedule:list 有无任务、日志有无每分钟执行记录;多副本部署时确认仅一个副本启用内置调度器;手动部署确认 crontab 行存在(crontab -l)。

Q4:迁移服务器后老用户全部被登出、部分历史数据打不开。 APP_KEY 没有随迁移保留。旧 .env 的 APP_KEY 原样带回新环境即可恢复;无法找回时只能重置会话并重录加密数据,无法解密恢复。

Q5:邮件发了但收不到,后台也没报错。 默认 MAIL_MAILER=log 只写日志不真发(5.7 实测)。配置 SMTP 段后用后台测试邮件验证;仍失败时查应用日志中的发送异常,并核对服务器到 SMTP 服务器的 587/465 端口连通性。

Q6:想改发票邮件的正文与发件地址,改 .env 没找到对应键。 邮件正文模板与发件展示地址属业务配置层,在后台设置中修改(存储于 company_settings 表,实测键见第六章);.env 只管 SMTP 传输层。

Q7:DOMPDF_ENABLE_REMOTE 打开后发票里远程图片不显示/很慢。 远程加载受网络出口限制,且默认关闭的设计目的就是防 SSRF(5.5)。生产建议保持 false,改用把图片上传为本地附件的方式引用。

九、参考链接

  1. 上游 .env.example(2.4.7 tag):https://raw.githubusercontent.com/InvoiceShelf/InvoiceShelf/2.4.7/.env.example
  2. 官方文档站:https://docs.invoiceshelf.com
  3. 主仓库:https://github.com/InvoiceShelf/InvoiceShelf
  4. 官方打包部署仓库(打包形态变量注入说明):https://github.com/InvoiceShelf/docker
  5. Laravel 13 官方文档(MAIL_*/CACHE_STORE/QUEUE_CONNECTION 参数语义溯源):https://laravel.com/docs
  6. 会话域与登录问题官方专述(issue #213):https://github.com/InvoiceShelf/InvoiceShelf/issues/213
  7. 本专栏部署篇:《InvoiceShelf Docker Compose 部署指南》
  8. 本专栏认知篇:《InvoiceShelf 介绍与选型指南》