AML/docker-compose-local-dev
fengruixiang 1a7ab235cb fix: update SalesAdminID for local development and add seed script for agent plans 2026-07-23 13:55:49 +08:00
..
Dockerfile.local chore(docker): 本地开发栈迁至 monorepo 根目录并适配跨仓库构建上下文 2026-07-21 15:50:55 +08:00
Dockerfile.local.dockerignore chore(docker): 本地开发栈迁至 monorepo 根目录并适配跨仓库构建上下文 2026-07-21 15:50:55 +08:00
appsettings.local.json fix: update SalesAdminID for local development and add seed script for agent plans 2026-07-23 13:55:49 +08:00
docker-compose.local.yml chore(docker): 本地开发栈补齐 PAYG 配置与 .bak 架构补齐脚本 2026-07-22 11:12:01 +08:00
local-schema-catchup.sql chore(docker): 本地开发栈补齐 PAYG 配置与 .bak 架构补齐脚本 2026-07-22 11:12:01 +08:00
readme.md chore(docker): 本地开发栈补齐 PAYG 配置与 .bak 架构补齐脚本 2026-07-22 11:12:01 +08:00
seed-agent-plans.sql fix: update SalesAdminID for local development and add seed script for agent plans 2026-07-23 13:55:49 +08:00
seed-root-ou.sql chore(docker): 本地开发栈迁至 monorepo 根目录并适配跨仓库构建上下文 2026-07-21 15:50:55 +08:00

readme.md

AML_Backend 本地开发docker-compose使用说明

用 docker-compose 在本地一键拉起 iCON.Abp.FX.HttpApi.Host,包含 SQL Server 数据库容器,并自动完成数据库迁移与种子数据初始化,用于本地开发调试。

适用平台macOS含 Apple Silicon / arm64。相关文件均位于 AML_Backend/docker-compose-local-dev/ 目录下构建上下文build context是上一级的仓库根目录 AML_Backend/


1. 架构概览

docker-compose.local.yml 定义四个服务:

服务 作用 说明
mssql SQL Server 2022 数据库 arm64 上通过 platform: linux/amd64Rosetta 模拟)运行;数据持久化在命名卷 mssql-data
rabbitmq 消息队列(异步任务中枢) rabbitmq:3.13-managementarm64 原生);host/consumer 靠它跑数据采集、报告生成、AI 检测、门户订单等异步链路。宿主端口错开为 5673/15673(见第 8 节)
db-migrator 数据初始化 运行一次:执行 EF Core 迁移 + 种子数据完成后退出exit 0
httpapi-host 后端 API 主机 db-migrator 成功后才启动;对外暴露 44331;随宿主启动 RabbitMQConsumerService 消费上述队列

启动顺序由健康检查与 depends_on 保证:mssql + rabbitmq 健康 → db-migrator 跑完 → httpapi-host 启动。

配套文件(均在 docker-compose-local-dev/ 内):

  • Dockerfile.local:本地多阶段构建镜像(.NET 6),产出 hostmigrator 两个目标。
  • Dockerfile.local.dockerignore:本地构建专用忽略表(仅排除 bin/obj/.git。BuildKit 会优先采用「与 Dockerfile 同目录、同名 + .dockerignore」的这个文件,从而覆盖仓库根目录的 .dockerignore(根目录那个会把 appsettings.jsondocker-compose* 都排除掉,不适用于本地构建)。
  • appsettings.local.json本地专用、绕过 Nacos 的完整配置(见第 1.1 节),构建时会被覆盖进镜像的 appsettings.json

⚠️ 仓库自带的 CI 用 src/iCON.Abp.FX.HttpApi.Host/Dockerfile 已过时(写的是 .NET 5、且 COPY 一个不存在的 src/access-token.bin不要用它做本地构建,请使用 Dockerfile.local

1.1 配置来源:为什么要绕过 Nacos

最新代码已把配置中心切到 Nacossrc/iCON.Abp.FX.HttpApi.Host/appsettings.json 现在只剩一个 NacosConfig真正的配置连接串、AuthServer、AppConfig、RabbitMQ、任务开关等都从 Nacos 服务器 http://192.168.1.120:8848DataId aml.dev.json)拉取。

该 Nacos 地址是公司内网,本机通常不可达;且它指向的是共享 dev 环境(连接串指向远程 dev 库),与「本地自包含隔离栈」的目标冲突。

Program.cs 里 Nacos 是条件加载的——仅当配置里存在 NacosConfig 段才会 AddNacosV2Configuration。因此本地方案是:用 appsettings.local.json(一份不含 NacosConfig、但包含完整配置的文件)覆盖镜像里的 appsettings.jsonApp 便不再尝试连接 Nacos直接用本地配置启动再由 compose 的环境变量把连接串等指向本地 mssql 容器。

appsettings.local.json 取自 Nacos 改造前commit 297d3bb6 的父提交)那版完整 appsettings.json,是目前唯一可自包含运行的完整配置快照。若今后 Nacos 里新增了启动必需的配置项,需要手动同步补进这个文件。


2. 前置条件

  1. Docker Desktop 已安装并运行。
  2. 内存 ≥ 16 GBSQL Server 2022 在 Apple Silicon 上是 amd64 模拟运行,内存不足会 SIGSEGVexit 139
    • 在 Docker Desktop → Settings → Resources → Memory 调到 16 GB或编辑 ~/Library/Group Containers/group.com.docker/settings-store.json 加入 "MemoryMiB": 16384 后执行 docker desktop restart
  3. ABP 商业版授权令牌(关键,见下一节)。

3. ABP 授权令牌(必须,否则 API 起不来)

httpapi-host 依赖 ABP 商业模块LanguageManagement、Lepton Commercial、Account Pro 等)。 启动时若授权校验失败,进程会直接终止:exit 214 / ABP-LIC-0008。 appsettings 内置的 AbpLicenseCode 是 2021 年的旧授权(已过期),因此需要用 abp login 生成的令牌。

注:db-migrator 不强制校验授权,所以数据迁移/种子在没有令牌时也能成功,只有 httpapi-host 需要令牌。

生成令牌(一次即可,令牌持久化在 ~/.abp/cli/

本机若已安装 ABP CLI

abp login fengruixiang -o JustGroup -p <你的密码>

本机未安装 ABP CLI 时,可在容器内执行(令牌通过挂载落到宿主机 ~/.abp/cli/

mkdir -p "$HOME/.abp"
docker run --rm -v "$HOME/.abp:/root/.abp" \
  --entrypoint /bin/bash mcr.microsoft.com/dotnet/sdk:6.0 -lc '
    export PATH="$PATH:/root/.dotnet/tools"
    dotnet tool install --global Volo.Abp.Cli --version 6.0.3
    abp login fengruixiang -o JustGroup -p <你的密码>
  '

成功后会生成 ~/.abp/cli/access-token.bindocker-compose.local.yml 已把它只读挂载进容器:

volumes:
  - "${HOME}/.abp/cli:/root/.abp/cli:ro"

该令牌在运行时联网向 abp.io 校验授权,因此 httpapi-host 启动时需要网络。


4. 一键启动

cd AML_Backend/docker-compose-local-dev
docker compose -f docker-compose.local.yml up -d --build

也可在仓库根目录运行:cd AML_Backend && docker compose -f docker-compose-local-dev/docker-compose.local.yml up -d --build

首次构建较慢(需还原大量 ABP 商业 NuGet 包并编译约 40 个项目,并拉取 SQL Server 镜像)。 构建已做内存优化(-m:1 单项目编译 + NuGet 缓存挂载),避免 Roslyn 因内存不足被杀OOM / exit 137

启动后验证:

docker compose -f docker-compose.local.yml ps
# httpapi-host 为 Up、db-migrator 为 Exited(0)、mssql 为 Up(healthy)

5. 访问信息

项目 地址 / 凭据
Swagger http://localhost:44331/swagger FX API + AMLPortal API
OpenID 配置 http://localhost:44331/.well-known/openid-configuration
数据库 localhost,11433,用户 sa,密码 Aml@Local2026,库名 AbpAML
RabbitMQ 管理台 http://localhost:15673 ,用户 admin / 密码 123456vhost bthost
应用管理员 admin@abp.io / 1q2w3E*

种子数据包含管理员账号、249 个国家、155 种货币、转账类型、文本模板、检测阈值等(共约 124 张表)。


6. 常用操作

cd AML_Backend/docker-compose-local-dev

# 查看后端日志注意Release 构建日志写文件docker logs 可能为空,见下)
docker compose -f docker-compose.local.yml logs -f httpapi-host

# 停止(保留数据库卷)
docker compose -f docker-compose.local.yml down

# 重新启动
docker compose -f docker-compose.local.yml up -d

# 改了代码后重建并重启
docker compose -f docker-compose.local.yml up -d --build

# 仅重跑数据初始化(迁移+种子,幂等)
docker compose -f docker-compose.local.yml run --rm db-migrator

# 彻底重置数据库(删除数据卷后重来)
docker compose -f docker-compose.local.yml down -v
docker compose -f docker-compose.local.yml up -d --build

# 连接数据库执行 SQL
docker exec aml-mssql /opt/mssql-tools18/bin/sqlcmd \
  -S localhost -U sa -P "Aml@Local2026" -C -d AbpAML -Q "SELECT COUNT(*) FROM AbpUsers"

7. 本地开发已做的环境覆盖

httpapi-host 通过环境变量覆盖了若干配置,让本地能干净启动:

  • ASPNETCORE_URLS=http://+:44331App__SelfUrl / AuthServer__Authority=http://localhost:44331(保证 IdentityServer 颁发者与浏览器访问地址一致),AuthServer__RequireHttpsMetadata=false
  • ConnectionStrings__Default 指向 mssql 服务(覆盖 appsettings 里的 localhost)。
  • RabbitMQAppConfig__RabbitMQConfig__HostName=rabbitmq(指向 compose 内的 broker...__EnableConsumer=true(开启后台消费)。账号/vhostadmin/123456/bthost)沿用 appsettings.local.jsonrabbitmq 服务的 RABBITMQ_DEFAULT_* 一致。
  • iCSAppConfig__iCS__iCSRootUrl=https://stag-abp-api.iconsz.com/iCS 服务端不在本仓库,指向共享 stag 实例,让文档/问卷/检测引擎等功能可用。iCS 用的是 ZeroSSL/Sectigo 证书、且服务器只下发部分证书链;Dockerfile.localruntime-base 阶段刷新了容器 CA 库,否则 HttpClient 会因 PartialChain 握手失败(应用自带的证书旁路只作用于旧式 WebClient不管 HttpClient

    依赖 stag 那边的 iCS 凭证有效;若 stag 不可达或换了证书,相关功能会失败但不影响 host 启动。

  • 仍关闭 SanctionJob(依赖本地未部署的 ElasticsearchEngineListSyncJob 因 iCS 已指向 stag 而恢复默认启用。

仍有部分检测功能依赖 Elasticsearch192.168.1.120:9200 等)等远程/局域网服务,本 compose 未包含。如需本地联调,需另行配置对应服务地址。


8. 故障排查

现象 原因 解决
httpapi-host 反复重启 / exit 214日志含 ABP-LIC-0008 ABP 授权令牌缺失或过期 按第 3 节生成 ~/.abp/cli/access-token.bin,确认 compose 挂载,重启服务
mssql exit 139SIGSEGV、状态 unhealthy Apple Silicon 模拟下内存不足 把 Docker 内存调到 ≥16 GB第 2 节),docker desktop restart
构建时 csc.dll exited with code 137 / cannot allocate memory 编译 DbMigrations 大项目时 OOM 已用 -m:1 缓解;确保 Docker 内存充足,必要时串行构建
docker logs httpapi-host 为空但服务异常 Release 构建只写文件日志(#if DEBUG 才有控制台 sink日志在容器内 /app/Logs/<级别>/<日期>/ docker cp aml-httpapi-host:/app/Logs ./Logs 后查看,或临时用 --build-arg BUILD_CONFIGURATION=Debug 构建以获得控制台日志
访问 Swagger 401/跳转异常 AuthServer:Authority 与实际访问地址不一致 确认仍是 http://localhost:44331,端口映射 44331:44331 未改
启动报 Bind for 0.0.0.0:5672 failed: port is already allocated 宿主已有其它 RabbitMQ 占用 5672/15672 本 compose 已把宿主端口错开为 5673/15673;若仍冲突,改 rabbitmq.ports 即可(容器间通信走内部 5672不受影响
日志含 SSL connection could not be established ... PartialChain 容器 CA 库无法补全 iCS(stag) 的 ZeroSSL 证书链,且 HttpClient 不认应用的证书旁路 Dockerfile.localruntime-base 刷新 CA 库解决;若复现,确认镜像是最新构建(--build
iCS 功能报 401/token 失败(非 TLS stag 那边的 iCS 凭证/租户失效 与后端确认 AppConfig:iCS:Credential 在 stag 是否有效;非致命,不影响 host

9. 相关文件清单

AML_Backend/                                 # 构建上下文build context根目录
├─ NuGet.Config                              # ABP 商业源Dockerfile 会 COPY
├─ src/iCON.Abp.FX.HttpApi.Host/             # API 主机工程
└─ docker-compose-local-dev/                 # ← 本地开发相关文件都在这里
   ├─ docker-compose.local.yml               # 本地三服务编排(本说明对应文件)
   ├─ Dockerfile.local                       # 本地 .NET 6 多阶段构建host / migrator 两个目标)
   ├─ Dockerfile.local.dockerignore          # 本地构建忽略表(覆盖根目录 .dockerignore
   ├─ appsettings.local.json                 # 绕过 Nacos 的完整本地配置(覆盖进镜像)
   └─ docker-compose-local-dev.md            # 本说明文档