7.3 KiB
| name | description |
|---|---|
| aml-local-refresh | Refresh the AML local dev stack - git pull AML_Backend, restore the newest AML-local-dev-*.bak into the mssql container as AbpAML, rebuild the httpapi-host image, and restart the API bypassing db-migrator. Use when asked to 更新/还原/重建/重启本地后端环境, "拉最新代码并还原数据库", "restore the latest bak", or when local portal endpoints 500 after the backend moved on. |
AML 本地环境刷新(拉代码 + 还原库 + 重启服务)
一条龙刷新 /Users/dev/projects/AML/docker-compose-local-dev/ 这套本地栈。栈本身的架构、配置来源(绕过 Nacos)、ABP 授权等背景见同目录 readme.md;本 skill 只讲刷新流程和必须踩对的顺序。
所有命令的工作目录都是:
cd /Users/dev/projects/AML/docker-compose-local-dev
铁律(顺序错了必炸)
- 还原库前先停 host,否则
RESTORE拿不到独占锁。 - 永远不要对还原库跑
db-migrator。.bak里没有__EFMigrationsHistory表,migrator 会从初始迁移重建表 →SqlException 2714→ exit 133;而 compose 里httpapi-host depends_on db-migrator: service_completed_successfully,migrator 一挂 host 就起不来。起 host 必须带--no-deps。 - 代码更新了就必须
build重建 host 镜像。旧二进制配新库 = 列类型对不上(历史事故:InvalidCastException: Decimal→Int32,所有门户端点 500)。 - 还原后
seed-root-ou.sql必跑(缺 root OU → 支付后建租户静默失败),local-schema-catchup.sql也跑一遍(幂等)。 seed-agent-plans.sql默认不要跑——先查活跃推薦人关联,有就跳过(见下)。
步骤
0. 前置检查
docker info >/dev/null 2>&1 || open -a Docker # 没起就拉起 Docker Desktop,等 docker info 通
Docker 内存需 ≥16 GB(mssql 在 Apple Silicon 上是 amd64 模拟,不够会 exit 139)。
1. 拉最新后端代码
cd /Users/dev/projects/AML/AML_Backend && git status -sb | head -5 && git pull
- 分支通常是
dev。工作区有改动先问用户,别自作主张 stash。 failed to get/store: -25308是 macOS keychain 的噪音,不影响 pull。- 拉完看一眼新迁移:
ls src/iCON.Abp.FX.EntityFrameworkCore.DbMigrations/Migrations/*.cs | grep -v Designer | tail -8,留着第 4 步核对。
2. 起基础设施 + 停 host
cd /Users/dev/projects/AML/docker-compose-local-dev
docker stop aml-httpapi-host
docker compose -f docker-compose.local.yml up -d mssql rabbitmq
# 等健康
until [ "$(docker inspect -f '{{.State.Health.Status}}' aml-mssql 2>/dev/null)" = healthy ]; do /bin/sleep 10; done
3. 还原最新 .bak
别写死文件名,用户会不定期换新的(文件名带日期戳,旧的会删):
BAK=$(ls -t *.bak | head -1); echo "using: $BAK"
docker cp "$BAK" aml-mssql:/var/opt/mssql/restore.bak
# 坑:docker cp 进去是 root:root 0600,sqlservr 读不到 → "Operating system error 5(Access is denied)"
docker exec -u root aml-mssql bash -lc 'chown mssql:root /var/opt/mssql/restore.bak && chmod 644 /var/opt/mssql/restore.bak'
docker exec aml-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'Aml@Local2026' -C -b -Q "
IF DB_ID('AbpAML') IS NOT NULL ALTER DATABASE [AbpAML] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE [AbpAML] FROM DISK='/var/opt/mssql/restore.bak'
WITH REPLACE, RECOVERY,
MOVE 'AML-local-dev' TO '/var/opt/mssql/data/AbpAML.mdf',
MOVE 'AML-local-dev_log' TO '/var/opt/mssql/data/AbpAML_log.ldf';
ALTER DATABASE [AbpAML] SET MULTI_USER;"
逻辑名恒为 AML-local-dev / AML-local-dev_log(不确定就先 RESTORE FILELISTONLY)。sqlcmd 在容器内路径是 /opt/mssql-tools18/bin/sqlcmd,必须带 -C。
4. 补数据 + 对齐 schema
docker exec -i aml-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'Aml@Local2026' -C -d AbpAML -b -i /dev/stdin < seed-root-ou.sql
docker exec -i aml-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'Aml@Local2026' -C -d AbpAML -b -i /dev/stdin < local-schema-catchup.sql
local-schema-catchup.sql 输出可能是乱码(中文编码),看 exit code 即可。
然后拿第 1 步列出的最新几条迁移,逐个查库里缺不缺(缺了就往 local-schema-catchup.sql 追加幂等 DDL —— 注意 ALTER TABLE ADD 与引用该新列的语句不能同批次,回填要包在 EXEC(N'...') 里):
docker exec aml-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'Aml@Local2026' -C -d AbpAML -h -1 -W -Q "
SELECT 'SomeTable='+ISNULL(CAST(OBJECT_ID('SomeTable') AS varchar),'MISSING')
+' | SomeCol='+ISNULL(CAST(COL_LENGTH('SomeTable','SomeCol') AS varchar),'MISSING');"
查表存在性别用
SELECT COUNT(*) FROM 该表——表不存在会在编译期报 208。一律OBJECT_ID/COL_LENGTH+ISNULL(CAST(... AS varchar),'MISSING')。 Edition 表叫SaasEditions(不是AbpEditions)。
推薦人脚本判断:
docker exec aml-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'Aml@Local2026' -C -d AbpAML -h -1 -W \
-Q "SELECT COUNT(*) FROM AMLPortal_AgentUserPlans WHERE IsDeleted=0;"
0 才考虑
seed-agent-plans.sql;非 0(新库自带真实关联)跳过——该脚本会先软删 agent_A 的现有关联,且它预期的 agentTest2/3 已不存在(RAISERROR 中止)。
5. 重建 host 镜像
docker compose -f docker-compose.local.yml build httpapi-host
- 全量重建约 10–20 分钟(restore 大量 ABP 商业包 + 编译 ~40 个项目)。建议
run_in_background跑,别用| tail管道——那会把失败的 exit code 吃掉,看起来像成功。 - 常见失败
error NU1301: Unable to load the service index for source https://www.myget.org/...:sdk 镜像 CA 过期。Dockerfile.local的build阶段已加ca-certificates刷新修好;若再复现,同样手法排查(docker run --rm mcr.microsoft.com/dotnet/sdk:6.0 bash -lc 'curl -sS https://www.myget.org/F/blazorise/api/v3/index.json')。 - 编译 OOM(exit 137):确认 Docker 内存 ≥16 GB。
6. 起 host(绕过 migrator)
docker compose -f docker-compose.local.yml up -d --no-build --no-deps httpapi-host
7. 冒烟验证
docker compose -f docker-compose.local.yml ps
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:44331/swagger/index.html
# 门户端点是 POST,GET 返 405
curl -s -X POST http://localhost:44331/api/amlPortal/Order/portal/GetEditionList -H 'Content-Type: application/json' -d '{}' | head -c 300
curl -s -X POST http://localhost:44331/api/amlPortal/plan/portal/GetPlanList -H 'Content-Type: application/json' -d '{}' | head -c 300
期望 {"code":0,...}。
- 一律
http://localhost:44331,https会报tlsv1 alert protocol version/000,看着像挂了其实只是协议不对。 - host 起不来先看日志:Release 构建只写文件,
docker logs是空的 →docker cp aml-httpapi-host:/app/Logs ./Logs。 - exit 214 /
ABP-LIC-0008= ABP 授权令牌缺失,见readme.md第 3 节。
报告给用户
刷新完说清楚四件事:拉到的 commit、用的 .bak 文件名、库里的数量(表 / Plans / Editions / Tenants)、以及冒烟结果。