BitzOrcas.AppHost 是本地开发入口,不进入生产制品。它把“容器已启动”“schema 已初始化”“Host 正在运行”拆成可观察资源,避免 API 抢跑后才暴露表不存在或 Quartz 未初始化。
实际资源图
启动顺序:
docker ps预检查,最多等待 10 秒;超时会终止探针子进程;- 启动 SQL Server、RabbitMQ、Redis、MinIO;
schema-initializer默认执行 API--init-schema --no-seed;BITZORCAS_ASPIRE_SEED_DEMO=true改为--seed-demo;BITZORCAS_ASPIRE_RESET_SCHEMA=true改为--reset-schema --force(可再叠加 seed)。不要对 AppHost 传-- --reset-schema,那些参数进不了 initializer;quartz-schema-initializer执行 JobHost--init-quartz-schema;- API 等待业务 schema,JobHost 等待 Quartz schema;
- LicenseSigner 独立启动;未配置 KMS 时保持失败关闭;
- Vite 前端与后端初始化并行启动,代理地址使用本次 AppHost 分配的 API 端口,API 尚未就绪时短暂代理失败属于预期。
必需的本地参数
把开发值写入 AppHost user-secrets,或使用等价的 Parameters__<ParameterName> 环境变量:
# 把 AppHost 管理的基础设施参数保存到仓库外。dotnet user-secrets set "Parameters:sqlserver-password" "<strong-password>" \ --project src/Hosts/BitzOrcas.AppHostdotnet user-secrets set "Parameters:rabbitmq-user" "bitzorcas" \ --project src/Hosts/BitzOrcas.AppHostdotnet user-secrets set "Parameters:rabbitmq-password" "<strong-password>" \ --project src/Hosts/BitzOrcas.AppHostdotnet user-secrets set "Parameters:redis-password" "<strong-password>" \ --project src/Hosts/BitzOrcas.AppHostdotnet user-secrets set "Parameters:minio-access-key" "bitzorcas-dev" \ --project src/Hosts/BitzOrcas.AppHostdotnet user-secrets set "Parameters:minio-secret-key" "<strong-password>" \ --project src/Hosts/BitzOrcas.AppHost
# PII 搜索摘要密钥必须稳定保存,不能在重启时随机变化。dotnet user-secrets set "Parameters:pii-search-hash-key" "<stable-random-key>" \ --project src/Hosts/BitzOrcas.AppHostAPI 自身仍需 Jwt:* 等 Host 配置。AppHost 只注入它明确声明的参数和资源引用,不会把任意业务 Secret 自动复制到 API/JobHost。
scripts/local/bootstrap.sh aspire 在首次缺少 Parameters:demo-user-password 时生成 10 字符策略密码
(与 GenerateSecurePassword 默认一致),以后不会自动轮换,因此它是本机固定值而不是仓库统一明文。
当前值写在被忽略且权限为 0600 的 .bitzorcas/demo-credentials。
重启 AppHost 不会改这个 secret,也不会重写提示文件。
已有 44 字符 Bitz!…Aa1 旧值不会被脚本擅自覆盖。要换成 10 字符生成器,先删除该 secret 再跑 bootstrap;
persist / fast 库还要把十个演示账号对齐到新值,步骤见
演示数据与种子参考。
启动
从仓库根目录执行。先补缺失的 AppHost / API user-secrets,再选一条启动命令:
# ① 只补缺失值,不覆盖已有 Secret,也不签发 Licensescripts/local/bootstrap.sh aspirescripts/local/doctor.sh aspire
# ② 证明 Docker daemon 可用;AppHost 自己也会做同类预检查docker ps
# ③ 默认:建业务表 + Quartz 表,不播种演示账号dotnet run --project src/Hosts/BitzOrcas.AppHost
# ④ 首次需要本地 admin / host-admin 等演示账号BITZORCAS_ASPIRE_SEED_DEMO=true \dotnet run --project src/Hosts/BitzOrcas.AppHost
# ⑤ 日常开发:复用 SQL Server 与 MinIO,RabbitMQ / Redis 仍是干净会话BITZORCAS_ASPIRE_SEED_DEMO=true \dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fast
# ⑥ 库已暖、不再重复写字典时去掉播种开关dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fastfast launch profile 会设置 ASPIRE_PERSIST_SQLSERVER=true 与 ASPIRE_PERSIST_MINIO=true。不要用 --no-launch-profile 启动 AppHost,除非自行导出 DOTNET_ENVIRONMENT=Development,否则 user-secrets 不会加载。若无 profile 仍把 Dashboard 绑到 HTTP 6888,还必须导出 ASPIRE_ALLOW_UNSECURED_TRANSPORT=true。
Dashboard 固定为 http://localhost:6888;仓库 launch profile 已允许该明文口,不要删掉 ASPIRE_ALLOW_UNSECURED_TRANSPORT。AppHost SQL 首选 localhost,14333:fast / persist 硬钉该口,默认会话在空闲时也优先占用,被另一套 AppHost 或残留容器占用才回退动态口。编排前端空闲时用 5860。不要把动态回退后的随机口写进仓库配置。首次镜像拉取与首次 schema 初始化会比普通 Host 重启慢;观察各资源时间,不要把总耗时都归因于 API。演示密码写在被忽略的 .bitzorcas/demo-credentials(权限 0600),不要提交或复制到共享环境。
默认值与显式开关
| 开关 | 默认 | 设为 true 后 |
|---|---|---|
ASPIRE_PERSIST_VOLUMES | 关闭 | SQL、RabbitMQ、Redis、MinIO 使用持久卷 |
ASPIRE_PERSIST_SQLSERVER | 关闭 | 只让 SQL Server 使用持久卷 |
ASPIRE_PERSIST_RABBITMQ | 关闭 | 只让 RabbitMQ 使用持久卷 |
ASPIRE_PERSIST_REDIS | 关闭 | 只让 Redis 使用持久卷 |
ASPIRE_PERSIST_MINIO | 关闭 | 只让 MinIO 使用持久卷 |
BITZORCAS_ASPIRE_SEED_DEMO | 关闭 | 初始化 schema 并播种本地演示身份与数据 |
BITZORCAS_ASPIRE_USE_REMOTE_AGILECONFIG | 关闭 | API/JobHost/初始化器读取各自配置的远程节点 |
BITZORCAS_AGILECONFIG_CONTAINER | 关闭 | 启动本地 AgileConfig,并放行客户端 |
LicenseManagement:Development:SigningWorkerEnabled | 关闭 | API 后台处理签发/吊销队列 |
默认关闭远程 AgileConfig 是为了隔离开发机遗留的 Nodes/Secret 和网络波动。它不是生产配置建议。
演示播种也默认关闭。普通启动只建 schema,不会悄悄创建账号;打开 BITZORCAS_ASPIRE_SEED_DEMO 后,demo-user-password 只注入一次性初始化进程,常驻 API、JobHost 和数据库不会保存明文。
持久卷
默认会话生命周期适合普通开发和复现。日常开发建议使用 fast,让 SQL 文件元数据与 MinIO
对象一起保留,同时让 RabbitMQ 和 Redis 保持干净:
dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fastfast profile 等价于只持久化 SQL Server 与 MinIO。需要保留全部基础设施状态时,再使用 ASPIRE_PERSIST_VOLUMES=true;也可以用四个资源级开关精确选择。启用持久卷后,对应资源密码
必须保持不变。关闭开关不会删除以前创建的卷;删除卷仍是独立、破坏性操作。
先列出目标:
docker ps -a --filter "label=aspire-resource-name"docker volume ls不要使用 docker system prune --volumes 代替项目级清理。
AgileConfig
普通数据库调试不需要 AgileConfig。联调团队已有节点:
BITZORCAS_ASPIRE_USE_REMOTE_AGILECONFIG=true \ dotnet run --project src/Hosts/BitzOrcas.AppHost自包含演示才启动本地容器:
BITZORCAS_AGILECONFIG_CONTAINER=true \ dotnet run --project src/Hosts/BitzOrcas.AppHost当前镜像为 linux/amd64,在 Apple Silicon 上可能经 QEMU 运行失败。此问题与 SQL Server、RabbitMQ、Redis 主路径分开诊断。
LicenseSigner
AppHost 总会显示 license-signer,并自动生成/持久化 API 与签名宿主共享的服务 Bearer。它不会生成 KMS 私钥、公钥或默认开启工作器。
因此有两种正常状态:
- 普通业务/数据库调试:Signer 未就绪可以独立处理;
- 许可证签发联调:必须配置版本化 Azure 密钥 URI、匹配公钥与工作器。
完整步骤见在线许可证签发与分发。
“启动成功”的判断
| 资源/端点 | 期望 |
|---|---|
schema-initializer | 成功完成并退出 |
quartz-schema-initializer | 成功完成并退出 |
| SQL/RabbitMQ/Redis/MinIO | Healthy |
API /health/live | 200 |
API /health/ready | 已选择的运行能力就绪;无 License 时可明确失败关闭 |
JobHost /health/live | 200 |
LicenseSigner /health/live | 200;签发时还要验证控制面 readiness |
只看到进程 Running 不等于应用 ready;License readiness 失败也不等于进程启动失败。
常见故障
| 现象 | 首先检查 |
|---|---|
| AppHost 立即退出 | Docker Desktop、docker ps、参数 Secret |
| schema 初始化失败 | 初始化器的首个异常、连接串、数据库资源 |
| API 未启动 | schema-initializer 是否成功完成 |
| JobHost 未启动 | quartz-schema-initializer 是否成功完成 |
| 重启后认证失败 | 是否显式复用持久卷但改变了参数密码 |
| 远程 AgileConfig 报错 | 是否误开远程开关;Nodes/Secret 是否属于对应 Host |
| LicenseSigner 503 | 是否需要签发;需要时检查 KMS、回执目录和公钥 |
| 附件拿到 URL 但上传失败 | MinIO 是否 Healthy;预签名 URL 是否能被浏览器访问 |
cap.Published 不存在 | 更新到会在 seed 前初始化 CAP 的版本,再重跑 demo seed |
| persist 库脏了想整库重来 | 先停 AppHost,再开 BITZORCAS_ASPIRE_RESET_SCHEMA=true(需要演示账号时同时开 BITZORCAS_ASPIRE_SEED_DEMO=true);成功后关掉 RESET_SCHEMA。不要对 AppHost 传 -- --reset-schema |
persist 库显式 reset
BITZORCAS_ASPIRE_RESET_SCHEMA=true 是 AppHost 唯一合法的破坏性 reset 入口。它会让 schema-initializer 执行 --reset-schema --force,删除业务表、审计分表和 CAP 表后重建。Quartz 表不会被删除。不能与 BITZORCAS_ASPIRE_RESET_DEMO_PASSWORDS 同时使用。Production / Staging 拒绝。launch profile 默认关闭。
BITZORCAS_ASPIRE_RESET_SCHEMA=true \BITZORCAS_ASPIRE_SEED_DEMO=true \dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fast完整语义与失败门见数据库初始化与迁移。
API 与 JobHost 会在启动时幂等创建 bitzorcas-files bucket。MinIO 修复的是聊天、工单、AI 等既有
Files 附件链路;知识库 PDF/Word 的上传接口仍未交付,不能把该页面的限制误判为 MinIO 故障。
与生产的差异
| 本地 AppHost | 生产必须另行提供 |
|---|---|
| 本机 Docker 网络 | 私有网络、DNS、TLS、防火墙 |
| User Secrets/参数 | Secret Store、工作负载身份、轮换审计 |
| 会话资源或本地卷 | 托管存储、备份、RPO/RTO |
| Aspire Dashboard | 受控 OTel backend 与访问控制 |
| 单机资源 | 多副本、故障域、容量、回滚 |
| 开发 schema 初始化器 | 正式迁移审批、备份和回滚计划 |
AppHost 成功证明开发拓扑可运行,不替代生产 IaC、Commercial GA、恢复演练或负载测试。