AML/docs/AML_Backend/docker-compose本地开发.md

173 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# AML_Backend 本地开发docker-compose使用说明
用 docker-compose 在本地一键拉起 `iCON.Abp.FX.HttpApi.Host`,包含 SQL Server 数据库容器,并自动完成数据库迁移与种子数据初始化,用于本地开发调试。
> 适用平台macOS含 Apple Silicon / arm64。相关文件均位于 `AML_Backend/` 目录下。
---
## 1. 架构概览
`docker-compose.local.yml` 定义三个服务:
| 服务 | 作用 | 说明 |
|------|------|------|
| `mssql` | SQL Server 2022 数据库 | arm64 上通过 `platform: linux/amd64`Rosetta 模拟)运行;数据持久化在命名卷 `mssql-data` |
| `db-migrator` | 数据初始化 | 运行一次:执行 EF Core 迁移 + 种子数据完成后退出exit 0 |
| `httpapi-host` | 后端 API 主机 | 等 `db-migrator` 成功后才启动;对外暴露 `44331` |
启动顺序由健康检查与 `depends_on` 保证:`mssql` 健康 → `db-migrator` 跑完 → `httpapi-host` 启动。
配套文件:
- `Dockerfile.local`:本地多阶段构建镜像(**.NET 6**),产出 `host``migrator` 两个目标。
- `Dockerfile.local.dockerignore`:本地构建专用忽略表(保留 `appsettings.json`,仅排除 `bin/obj/.git` 等)。
> ⚠️ 仓库自带的 CI 用 `src/iCON.Abp.FX.HttpApi.Host/Dockerfile` 已过时(写的是 .NET 5、且 COPY 一个不存在的 `src/access-token.bin`**不要**用它做本地构建,请使用 `Dockerfile.local`。
---
## 2. 前置条件
1. **Docker Desktop** 已安装并运行。
2. **内存 ≥ 16 GB**SQL 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
```bash
abp login fengruixiang -o JustGroup -p <你的密码>
```
本机未安装 ABP CLI 时,可在容器内执行(令牌通过挂载落到宿主机 `~/.abp/cli/`
```bash
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.bin`。`docker-compose.local.yml` 已把它只读挂载进容器:
```yaml
volumes:
- "${HOME}/.abp/cli:/root/.abp/cli:ro"
```
> 该令牌在**运行时联网**向 abp.io 校验授权,因此 `httpapi-host` 启动时需要网络。
---
## 4. 一键启动
```bash
cd AML_Backend
docker compose -f docker-compose.local.yml up -d --build
```
首次构建较慢(需还原大量 ABP 商业 NuGet 包并编译约 40 个项目,并拉取 SQL Server 镜像)。
构建已做内存优化(`-m:1` 单项目编译 + NuGet 缓存挂载),避免 Roslyn 因内存不足被杀OOM / exit 137
启动后验证:
```bash
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` |
| 应用管理员 | `admin@abp.io` / `1q2w3E*` |
种子数据包含管理员账号、249 个国家、155 种货币、转账类型、文本模板、检测阈值等(共约 124 张表)。
---
## 6. 常用操作
```bash
cd AML_Backend
# 查看后端日志注意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://+:44331``App__SelfUrl` / `AuthServer__Authority=http://localhost:44331`(保证 IdentityServer 颁发者与浏览器访问地址一致),`AuthServer__RequireHttpsMetadata=false`。
- `ConnectionStrings__Default` 指向 `mssql` 服务(覆盖 appsettings 里的 `localhost`)。
- 屏蔽不可达的外部集成:`AppConfig__RabbitMQConfig__HostName=127.0.0.1`(快速失败)、`...__EnableConsumer=false`;关闭 `SanctionJob`、`EngineListSyncJob`。
> 仍有部分检测功能依赖 Elasticsearch / iCS 等远程或局域网服务,本 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` 未改 |
---
## 9. 相关文件清单
```
AML_Backend/
├─ docker-compose.local.yml # 本地三服务编排(本说明对应文件)
├─ Dockerfile.local # 本地 .NET 6 多阶段构建host / migrator 两个目标)
├─ Dockerfile.local.dockerignore # 本地构建忽略表(保留 appsettings.json
└─ src/iCON.Abp.FX.HttpApi.Host/ # API 主机工程
```