SolidInvoice 3.1.2 Docker Compose 部署指南

SolidInvoice 3.1.2 官方镜像 + MySQL 8.4 的 Docker Compose 完整部署指南:镜像选型、CLI 非交互安装、数据持久化、环境变量与运维命令。

SolidInvoice发票管理自托管PHP 应用2026/10/24

SolidInvoice 3.1.2 Docker Compose 部署指南

目标:在 Linux 服务器上用 Docker Compose 从零部署一套可生产的 SolidInvoice 3.1.2 计费/开票系统(官方镜像 + MySQL 8.4 数据库),完成应用安装(CLI 非交互路径为主)、数据持久化与日常运维闭环。全文命令与回显均在 Ubuntu 22.04.4 LTS(x86_64)+ Docker 29.8.1 + Docker Compose v5.5.1 环境实测通过,查询日期 2026-10-24。

一、环境信息

本次部署实测环境与关键信息如下:

  • 操作系统:Ubuntu 22.04.4 LTS(x86_64),内核自带 Docker 运行能力
  • Docker:29.8.1;Docker Compose:v5.5.1(docker compose version 实测输出)
  • SolidInvoice 版本:3.1.2(官方最新稳定版,2026-10-22 发布;GitHub Releases Atom 实查,查询日期 2026-10-24)
  • 官方镜像:solidinvoice/solidinvoice:3.1.2(Docker Hub solidinvoice/solidinvoice,多架构 amd64/arm64)
  • 数据库镜像:mysql:8.4(SolidInvoice 支持 MySQL/MariaDB/PostgreSQL/SQLite,本文以 MySQL 为生产主线)
  • 应用监听端口:8765(镜像内置 Web 服务器固定端口),宿主机映射为 8136
  • 部署目录:服务器工作目录下 solidinvoice/,其中 app-data/(应用配置)与 db-data/(数据库文件)为持久化目录
  • 示例账号:应用管理员 admin@example.com / q1w2e3r4;MySQL root 密码 q1w2e3r4(均为演示环境测试口令)

二、镜像选型说明

SolidInvoice 官方只提供一种自包含镜像,选型要点如下(镜像内置环境变量来自 docker inspect solidinvoice/solidinvoice:3.1.2 实测):

项实测值说明
镜像名solidinvoice/solidinvoice唯一官方镜像(Docker Hub),由仓库 docker/package.Dockerfile 构建
基础构成Alpine + 自包含单文件二进制二进制内嵌 PHP 运行时、Caddy/FrankenPHP Web 服务器与后台 worker,镜像内无 PHP-FPM/Nginx 等额外进程
入口ENTRYPOINT ["/usr/local/bin/solidinvoice"],CMD ["run", "--disable-https"]即"以纯 HTTP 模式运行应用"(生产建议前置反代终止 TLS 时保持默认;无反代时需自行改 HTTPS 参数,见第二章)
暴露端口8765(EXPOSE 8765)应用内置 Caddy 监听端口,映射时只能映射此端口
数据卷/etc/solidinvoice(VOLUME)存放应用密钥、安装状态与配置,必须持久化
内置环境变量SOLIDINVOICE_VERSION=3.1.2、SOLIDINVOICE_ENV=prod、SOLIDINVOICE_DEBUG=0、SOLIDINVOICE_CONFIG_DIR=/etc/solidinvoice、SOLIDINVOICE_DOCKER=true镜像构建时固化,无需手动设置

版本标签体系(来源:仓库 docker-bake.hcl):每个发布版本同时打 主版本、主.次版本、主.次.修订版本 三类语义化标签与 latest。生产建议锁定完整修订号(如 3.1.2)而非 latest,升级时显式改标签,便于回滚。

💡 技术拓展:自托管开票类 PHP 应用的镜像常见两种形态——「传统 LAMP 式」(镜像内 PHP-FPM + Nginx + 源码目录,需挂载源码与配置多处)与「自包含二进制式」(单文件内嵌运行时,仅一个数据卷)。SolidInvoice 3.x 采用后者,配置面收敛到 /etc/solidinvoice 一个目录与环境变量,运维面显著小于前者。本文因目标是一套可长期升级的生产部署,选择官方自包含镜像 + MySQL 外置数据库的组合。

三、前置条件

  • Linux 服务器(x86_64 或 arm64),已安装 Docker 24+ 与 Docker Compose v2+(docker compose version 可执行)。
  • 服务器可访问 Docker Hub 拉取镜像;网络受限环境可为 Docker 守护进程配置 HTTP 代理。
  • 规划端口:宿主机用于对外服务的端口(本文用 8136),确认未被占用:
ss -ltn | grep 8136 || echo '8136 端口空闲'

实测回显(端口空闲时):

8136 端口空闲
  • 建议内存 ≥ 2GB(MySQL 8.4 + SolidInvoice 双进程的最低舒适配置)。

四、部署步骤

主线流程:编写 Compose 文件 → 启动数据库与应用 → CLI 非交互安装应用 → 验证登录。全程命令行可复现,无需浏览器操作。

4.1 编写 docker-compose.yml

在部署目录创建 docker-compose.yml:

name: solidinvoice-3.1.2-stack

services:
  db:
    image: mysql:8.4
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: q1w2e3r4
    volumes:
      - ./db-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-pq1w2e3r4"]
      interval: 10s
      timeout: 5s
      retries: 10

  app:
    image: solidinvoice/solidinvoice:3.1.2
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "8136:8765"
    volumes:
      - ./app-data:/etc/solidinvoice

配置逐项说明:

  • name: solidinvoice-3.1.2-stack:显式声明 Compose 项目名,保证 docker compose down 等命令只作用于本栈,不影响同机其他 Compose 项目。
  • db.environment 只设 MYSQL_ROOT_PASSWORD:不要预设 MYSQL_DATABASE(原因见 4.3 与常见问题),数据库由 SolidInvoice 安装器自行创建。
  • db.healthcheck:用 mysqladmin ping 探活,app 通过 condition: service_healthy 等数据库真正就绪后再启动,避免安装时连接被拒。
  • app.ports "8136:8765":宿主机 8136 → 应用内置 Web 服务器 8765;8136 可按需替换为 80/443 等。
  • app.volumes ./app-data:/etc/solidinvoice:持久化应用配置目录(密钥、安装状态),是升级镜像不丢配置的关键。
  • 应用默认以纯 HTTP 监听(镜像 CMD 为 run --disable-https)。若该实例直接暴露公网且无反代终止 TLS,需在 app 服务下追加 command: ["run", "--domain=invoice.example.com", "--lets-encrypt"](Let's Encrypt 自动签证书,要求域名解析到本机且 80/443 可达);经 Nginx/云负载均衡终止 TLS 的场景保持默认即可。

4.2 启动栈

cd solidinvoice
docker compose up -d

实测回显:

[+] Running 3/3
 ✔ Network solidinvoice-312-stack_default  Created
 ✔ Container solidinvoice-312-stack-db-1   Healthy
 ✔ Container solidinvoice-312-stack-app-1  Started

确认两个服务状态:

docker compose ps

实测回显:

NAME                           STATUS
solidinvoice-312-stack-app-1   Up 30 seconds
solidinvoice-312-stack-db-1    Up 40 seconds (healthy)

此时应用进程已运行但尚未安装(无数据库配置),/health 健康端点已可用:

curl -s http://127.0.0.1:8136/health -w ' | HTTP %{http_code}\n'

实测回显:

OK | HTTP 200

4.3 执行应用安装(CLI 非交互方式)

官方安装形态有两种:浏览器访问 /install 安装向导(分步填数据库与管理员账号),或命令行一条命令完成。服务器部署推荐 CLI 方式(可脚本化、可复查),命令如下:

docker exec solidinvoice-312-stack-app-1 solidinvoice console solidinvoice:install \
  --database-driver=pdo_mysql \
  --database-host=db \
  --database-port=3306 \
  --database-name=solidinvoice \
  --database-user=root \
  --database-password=q1w2e3r4 \
  --admin-email=admin@example.com \
  --admin-password=q1w2e3r4 \
  --locale=en \
  --application-url=http://127.0.0.1:8136 \
  --disable-telemetry

实测回显:

Running step: Generating secret
Running step: Generating build id
Running step: Creating database
Running step: Creating database schema
Creating Admin User


  Application installed successfully!

五个安装步骤与官方 /install 向导的子步骤一一对应(生成应用密钥 → 生成安装 build id → 创建数据库 → 执行 Doctrine 迁移建表 → 创建管理员账号)。参数说明:

  • --database-host=db:Compose 网络内数据库服务名;若数据库在别机,填其 IP 或域名。
  • --database-user=root:安装器需要建库权限;由它自己创建 solidinvoice 库,因此 4.1 中不设 MYSQL_DATABASE。
  • --admin-email/--admin-password:应用管理员登录账号(本文演示用 admin@example.com / q1w2e3r4)。
  • --locale=en:界面语言(可选 en/fr/de/nl 等)。
  • --application-url:本实例对外访问 URL,用于发票链接与邮件中的地址生成。
  • --disable-telemetry:关闭匿名使用统计上报。

验证安装已写入配置目录:

ls ./app-data/

实测回显:

oauth
solidinvoice.decrypt.private.php
solidinvoice.encrypt.public.php
solidinvoice.list.php
solidinvoice.SOLIDINVOICE_APPLICATION_URL.170fd7.php
solidinvoice.SOLIDINVOICE_APP_SECRET.31f70b.php
solidinvoice.SOLIDINVOICE_BUILD_ID.276607.php
solidinvoice.SOLIDINVOICE_DATABASE_URL.86f089.php
solidinvoice.SOLIDINVOICE_ENABLE_TELEMETRY.3b5772.php
solidinvoice.SOLIDINVOICE_INSTALLED.c0d8a4.php
solidinvoice.SOLIDINVOICE_LOCALE.b96b2c.php

每个 SOLIDINVOICE_* 文件对应一项已安装配置(数据库连接、应用密钥、安装标记、语言、应用 URL 等),由安装器加密落盘——这就是 /etc/solidinvoice 必须持久化的原因。

4.4 验证访问

curl -s http://127.0.0.1:8136/health -w ' | HTTP %{http_code}\n'
curl -s -o /dev/null -w 'GET / => %{http_code} redirect=%{redirect_url}\n' http://127.0.0.1:8136/
curl -s -o /dev/null -w 'GET /login => %{http_code}\n' http://127.0.0.1:8136/login

实测回显:

OK | HTTP 200
GET / => 302 redirect=http://127.0.0.1:8136/login
GET /login => 200

浏览器打开 http://<服务器IP>:8136,会跳转登录页,用 admin@example.com / q1w2e3r4 登录即可进入控制台(仪表盘、客户、发票、报价等模块)。

⚠️ 注意:若希望通过浏览器走 /install 向导安装(而非 4.3 的 CLI),直接在安装完成前访问 http://<IP>:8136 会自动跳到向导首页,按界面提示逐步填写数据库与管理员信息即可;两种方式二选一,不要混用重复执行。

五、数据持久化说明

本方案的三类持久化数据与归宿:

数据存放位置(容器内)持久化到宿主机内容
应用配置与密钥/etc/solidinvoice./app-data/数据库连接、应用密钥、安装状态、加密密钥对、OAuth 密钥
MySQL 数据文件/var/lib/mysql./db-data/全部业务数据(客户、发票、支付、设置)
上传附件数据库内(BLOB)随 ./db-data/发票/报价附件随库持久化

重启与升级不丢数据验证(实测):重启应用进程后健康检查与登录页恢复正常,配置目录与数据库目录内容原样保留:

docker compose restart app
sleep 12
curl -s http://127.0.0.1:8136/health -w ' | HTTP %{http_code}\n'
curl -s -o /dev/null -w 'GET /login => %{http_code}\n' http://127.0.0.1:8136/login

实测回显:

 Container solidinvoice-312-stack-app-1  Started
OK | HTTP 200
GET /login => 200

⚠️ 注意:down 不带 -v 不会删除 bind mount 数据;但切勿执行 docker compose down -v 之外的 rm -rf ./db-data ./app-data 类清理操作,那会连同业务数据一起删除。备份策略见"九、常用运维命令"。

六、环境变量表

镜像内置变量(固定,不可改):

变量实测值作用
SOLIDINVOICE_VERSION3.1.2镜像内应用版本号
SOLIDINVOICE_ENVprod应用运行环境(镜像固定为 prod)
SOLIDINVOICE_DEBUG0调试开关,镜像固定关闭
SOLIDINVOICE_CONFIG_DIR/etc/solidinvoice配置目录,与 VOLUME 声明一致
SOLIDINVOICE_DOCKERtrue标记容器化运行形态,应用据此启用内置 worker 等行为

可选注入变量(经 app.services.environment 传入,控制数据库/邮件/队列/检索等,均可在安装后生效):

变量默认行为说明
SOLIDINVOICE_DATABASE_URL未设置时由安装向导/CLI 写入配置目录直接指定数据库连接(如 mysql://user:pass@host:3306/solidinvoice),设置后安装向导可跳过数据库步骤
SOLIDINVOICE_MAILER_DSN使用界面中配置的邮件设置Symfony Mailer DSN(如 smtp://user:pass@smtp.example.com:587),环境变量优先于界面配置
SOLIDINVOICE_MAILER_SENDER界面配置全局发件人地址,如 SolidInvoice <noreply@example.com>
SOLIDINVOICE_MESSENGER_DSNdoctrine://default(数据库队列)异步任务传输层,高吞吐可切 redis:// 或 amqp://
SOLIDINVOICE_MEILISEARCH_URL / _API_KEY留空禁用接入 Meilisearch 全文检索,留空回退数据库查询
SOLIDINVOICE_LOCALE安装时写入配置界面语言(en/fr/de/nl 等)
SOLIDINVOICE_ALLOW_REGISTRATION0(禁用)是否开放访客自助注册
SOLIDINVOICE_SENTRY_DSN留空禁用Sentry 错误监控接入
SOLIDINVOICE_ENABLE_METRICS / SOLIDINVOICE_METRICS_PORT关闭 / 9090开启 Prometheus /metrics 指标端点及端口
SOLIDINVOICE_LOG_FORMATconsole日志格式:console(人类可读)或 json(结构化)

💡 完整参数语义、配置目录文件结构与界面内设置项的逐项说明,见本专栏《SolidInvoice 3.1.2 配置参数详解》。

七、配置参数说明

  • 应用层配置:安装后集中在 /etc/solidinvoice(挂载为宿主机 ./app-data/)。文件为逐项独立的 PHP 配置片(solidinvoice.SOLIDINVOICE_<名称>.<指纹>.php)加一个 solidinvoice.list.php 清单文件,由应用管理,手工编辑易导致指纹校验失败,修改配置应走安装器、环境变量或管理界面(Settings)。
  • 数据库连接:由安装步骤写入;后续换库需修改 SOLIDINVOICE_DATABASE_URL 对应配置文件或重新安装(见常见问题)。
  • 邮件/通知/支付网关:登录管理界面后在 Settings 中配置(邮件 SMTP、Payum 支付网关如 Stripe/PayPal 的密钥),保存后即生效,无需重启进程。
  • Web 服务器与 TLS:镜像内 Caddy 的行为由 run 子命令参数控制(--domain、--lets-encrypt、--ssl-cert/--ssl-key、--disable-https),在 Compose 中通过覆盖 command 传入。

八、等价 docker run

与上述 Compose 等价的裸 docker run 启动方式(便于理解 Compose 背后的进程拓扑;生产仍建议 Compose):

# 1. 创建数据库网络
docker network create solidinvoice-net

# 2. 启动 MySQL 8.4
docker run -d --name solidinvoice-312-mysql \
  --network solidinvoice-net \
  -e MYSQL_ROOT_PASSWORD=q1w2e3r4 \
  -v /opt/solidinvoice/db-data:/var/lib/mysql \
  --restart unless-stopped \
  mysql:8.4

# 3. 启动 SolidInvoice 应用
docker run -d --name solidinvoice-312-app \
  --network solidinvoice-net \
  -p 8136:8765 \
  -v /opt/solidinvoice/app-data:/etc/solidinvoice \
  --restart unless-stopped \
  solidinvoice/solidinvoice:3.1.2

# 4. 应用安装(等价 4.3,注意 --database-host 改为 MySQL 容器名)
docker exec solidinvoice-312-app solidinvoice console solidinvoice:install \
  --database-driver=pdo_mysql --database-host=solidinvoice-312-mysql \
  --database-port=3306 --database-name=solidinvoice \
  --database-user=root --database-password=q1w2e3r4 \
  --admin-email=admin@example.com --admin-password=q1w2e3r4 \
  --locale=en --application-url=http://127.0.0.1:8136 --disable-telemetry

与 Compose 版的差别:需要手工管理网络与容器名、healthcheck 等待逻辑需自建(如启动脚本轮询 MySQL 就绪),其余行为完全一致。

九、常用运维命令

以下命令均在部署目录(含 docker-compose.yml)内执行:

# 服务状态(含健康检查结果)
docker compose ps

# 查看应用日志(内嵌 Caddy/FrankenPHP 与 Symfony 输出,生产建议配 SOLIDINVOICE_LOG_FORMAT=json)
docker compose logs -f app

# 重启单个服务
docker compose restart app

# 进入应用执行任意 Symfony 控制台命令(如清理缓存)
docker exec solidinvoice-312-stack-app-1 solidinvoice console cache:clear

# 查看应用版本与构建信息
docker exec solidinvoice-312-stack-app-1 solidinvoice version
docker exec solidinvoice-312-stack-app-1 solidinvoice build-info

# 数据库备份(业务数据全量导出)
docker exec solidinvoice-312-stack-db-1 sh -c 'mysqldump -uroot -pq1w2e3r4 solidinvoice' > solidinvoice-backup-$(date +%F).sql

# 数据库恢复
cat solidinvoice-backup-2026-10-24.sql | docker exec -i solidinvoice-312-stack-db-1 sh -c 'mysql -uroot -pq1w2e3r4 solidinvoice'

# 停止与销毁(保留数据卷)
docker compose down

version 与 build-info 实测回显:

3.1.2-FrankenPHP v2.11.7 h1:yj0Y4fYZGPkSvibBJ1sTWE33xC0fxztVyXEW5iIdUT4=
build   GOARCH=amd64
build   GOOS=linux
build   GOAMD64=v1
build   vcs=git
build   vcs.revision=278785b382d9b1b2e403b6b8383468e8791eed8a
build   vcs.time=2026-10-21T14:22:57Z
build   vcs.modified=false

💡 说明:version 输出中的 FrankenPHP v2.11.7 表明该二进制内嵌的 Caddy/FrankenPHP 运行时版本,build-info 中的 vcs.revision/vcs.time 对应官方构建的源码提交,可用于核对镜像与发行版一致性。

升级流程:修改 docker-compose.yml 中镜像标签(如 3.1.2 → 下一版本号)→ docker compose pull → docker compose up -d。应用配置与数据都在挂载目录中,升级不触碰;升级前建议先做数据库备份。

十、常见问题(FAQ)

Q1:安装时报 SQLSTATE[HY000] ... 1007 Can't create database 'solidinvoice'; database exists? 安装器的 Creating database 步骤会自行建库,若 MySQL 侧已预建同名库(如 Compose 里设了 MYSQL_DATABASE=solidinvoice)就会冲突。解法:Compose 中去掉 MYSQL_DATABASE(以及 MYSQL_USER/MYSQL_PASSWORD),只保留 MYSQL_ROOT_PASSWORD,让安装器建库;或清空 db-data/ 重建后重装。

Q2:CLI 安装报 The given driver "mysql" is unknown, Doctrine currently supports only the following drivers: pdo_mysql, ...? --database-driver 需要传 Doctrine 底层驱动名而非界面标签:MySQL/MariaDB 用 pdo_mysql,PostgreSQL 用 pdo_pgsql,SQLite 用 pdo_sqlite。界面向导里的 "MySQL" 标签对应 CLI 的 pdo_mysql。

Q3:CLI 安装在提问 Please enter a locale: 或 Please enter the application URL 后中断(Aborted)? 非交互执行(如脚本管道)下交互提问会直接中止。把 --locale 与 --application-url 两个参数补全即可全非交互安装(见 4.3 命令)。

Q4:安装前应用日志出现 SQLSTATE[HY000] [14] unable to open database file? 这是未安装时的正常现象:应用启动时会尝试按默认 SQLite 配置连接数据库做迁移检查,配置目录中还没有数据库文件故报错。完成安装后该错误不再出现,无需处理。

Q5:访问 8136 端口浏览器提示"不安全"? 镜像默认 --disable-https 纯 HTTP 模式。生产公网部署:前置 Nginx/云 LB 终止 TLS(保持默认),或在 Compose 中覆盖 command: ["run", "--domain=invoice.example.com", "--lets-encrypt"] 让内置 Caddy 自动签发 Let's Encrypt 证书(要求域名解析正确且 80/443 公网可达)。

Q6:后台任务(邮件发送、周期发票)需要另配 cron 吗? 不需要。Docker 形态的内置 worker 随主进程自动运行(官方文档明确 "Recurring tasks and async work (email sending) run automatically inside the container")。只有 Git 源码或发行包安装才需要按官方 cron-job-setup 指南另配定时任务。

Q7:想换数据库为 PostgreSQL? 用 --database-driver=pdo_pgsql --database-port=5432 执行安装,Compose 中把 db 服务镜像换成 postgres:16+ 并按需调整环境变量即可;已装好的 MySQL 实例换库属迁移操作,先导出数据再按新库重装。

十一、卸载与清理

cd solidinvoice
# 停止并移除服务与网络(保留 ./db-data ./app-data 数据目录)
docker compose down
# 确认无需保留数据后删除持久化目录
rm -rf ./db-data ./app-data
# 删除本地镜像(可选)
docker rmi solidinvoice/solidinvoice:3.1.2 mysql:8.4

实测回显(down 阶段):

 Container solidinvoice-312-stack-app-1  Removed
 Container solidinvoice-312-stack-db-1   Removed
 Network solidinvoice-312-stack_default  Removed

十二、参考链接