Repository navigation
deploy(cortex-cloud): pin container memory to 2g with no swap - #16
Conversation
Co-authored-by: Alvin Tang <alvinttang@users.noreply.github.com>
只读审查(PR #16:
|
| 路径 | 文件 | 结论 |
|---|---|---|
| 重建 / redeploy | deploy/cortex-cloud/deploy.sh:36-40 |
docker rm -f 后 docker run,新 flags 在镜像名之前,位置正确。这是生产唯一会丢掉 docker update 现场限额的路径,本 PR 补上了。 |
| 重启 / restart | 同文件 :37 的 --restart unless-stopped |
docker restart、daemon 重启、主机 reboot 复用同一容器的 HostConfig,限额会保留。无第二条 recreate 脚本。 |
| compose | — | 仓库无 compose 文件。 |
| systemd 备选 | deploy/cortex-cloud/cortex-cloud.service:6-24 |
文档里的「其它主机」路径。无 MemoryMax / MemorySwapMax,仍不受 2g 约束。 |
| 证书续期 | deploy/cortex-cloud/renew-cortex-cert.sh |
只 reload nginx,不碰容器。 |
CI release-docker.yml |
构建 cortex-http 镜像 |
与 cortex-cloud 部署无关。 |
| 回滚笔记 | RELEASE_2026-10-07.md:52-56 |
docker start 旧 rollback 容器,不会带上本 PR 的 flags(历史路径,非日常部署)。 |
Docker 标志
deploy/cortex-cloud/deploy.sh:39 的 --memory 2g --memory-swap 2g 正确:
--memory-swap是 RAM+swap 合计。两者相等 ⇒ 容器 swap 配额为 0,符合无 swap 主机。- cgroup v2 上应对应
memory.max=2g、memory.swap.max=0。 - 若只写
--memory不写--memory-swap,Docker 默认合计 2×(即 4g),在这台无 swap 机器上没有意义;显式写等值是对的。 - 内核若没有 swap accounting,Docker 会警告并忽略
--memory-swap,--memory 2g仍生效,docker run不应失败。 - 未改
--restart/--network host/ volume / env;原先也没有--cpus/--pids-limit,没有 limit 回退。
文档
没有文档写过「容器无内存上限」,因此没有直接矛盾。但 deploy/cortex-cloud/README.md:20-26 描述生产容器时仍不提已批准的 2g;systemd 示例同样不提。不算错误,只是部署合同不完整。
RSS 是否装进 2g
稳态:能装下,余量够。
- 共享 embedder 只加载一次(
cortex-cloud/src/main.rs:303-308、:896;cortex-core/src/embedder.rs:14-16)。设计文档写单模型约 90MB;磁盘上 all-MiniLM-L6-v2 约 30MB,加上 ORT 后常见 RSS 约 90–400MB,远小于 2g。 - 租户 LRU=64(
main.rs:45),每租户 ≤1000 条 export;HNSW 阈值 1000(memory_index.rs:104),向量索引懒加载。 - SQLCipher
cache_size=-64000/mmap_size=256MB(cortex-core/src/storage/sqlite.rs:137-138)是上限不是预留;加密库通常不真正 mmap。租户库很小,页缓存跟文件走。 - PR 称生产已
docker update到 2g 且仍在跑——本环境无法核验,但与稳态估算一致。
峰值(残余风险,不是 flags 写错):API_LANE=64(main.rs:56)× MAX_EXPORT_BODY=24MiB(cortex-mcp-server/src/gateway/cloud.rs:29)≈ 1.5GiB 仅 body 缓冲,再加 JSON / SQLCipher / 模型,理论上能顶穿 2g。无 swap 时会直接 OOM-kill。需要同时有许多已认证租户并打满并发 export,正常负载不像这个样子。
Findings
-
[OK]
deploy/cortex-cloud/deploy.sh:39
--memory 2g --memory-swap 2g语义正确、位置正确、两者相等。redeploy 会钉死限额;restart 走同一 HostConfig。 -
[MEDIUM]
deploy/cortex-cloud/cortex-cloud.service:6-24
文档列出的 systemd 路径没有等价的MemoryMax=2G+MemorySwapMax=0。生产走 Docker,不挡这次合并;若 2g 是服务级政策,这条路径仍裸奔。 -
[MEDIUM]
cortex-cloud/src/main.rs:56+cortex-mcp-server/src/gateway/cloud.rs:29
2g 硬顶 + 无 swap,使「64 路满额 export」从「吃主机内存」变成「容器 OOM」。flags 本身没错,是限额下的残余容量风险。 -
[LOW]
deploy/cortex-cloud/README.md:20-26
生产docker run现已带 2g,README /docs/design/muse-cloud.md未记录。不矛盾,部署合同不完整。 -
[INFO] 无 compose;
renew-cortex-cert.sh不重建容器;其它 limit 无回退。
本环境未测生产 RSS。
APPROVE
模型 B 审只读独立复核:PR 仅改
结论:参数语义、位置及当前生产部署覆盖均正确。A 的 systemd 备注应降为 LOW;64 路 export 备注维持 MEDIUM,但两者都不构成本 PR 的回归或合并阻断。 APPROVE |
What & why
Pins the boss-approved memory plan for the
cortex-cloudcontainer into the deploy config.cortex-clouda 2g memory limit. Until then it had no limit.docker update. This PR changes no live state. It only makes the nextdeploy.shrun recreate the container with the same limit, so a redeploy doesn't remove it.deploy/cortex-cloud/deploy.shnow passes--memory 2g --memory-swap 2gtodocker run, before the image name. The host has no swap, so--memory-swapis set equal to--memory, which means the container gets no swap.No other files changed. No test or doc said the container had no limit, so nothing else needed updating.
Type of change
Checklist
cargo fmt --allclean (no Rust changes)cargo clippy --workspace --all-targets -- -D warningsclean (no Rust changes)cargo test --workspacepasses (no Rust changes)bash -n deploy/cortex-cloud/deploy.shandgit diff --check)cargo benchnumbers belowDraft only. Do not merge or deploy as part of this PR.