Skip to content

deploy(cortex-cloud): pin container memory to 2g with no swap - #16

Merged
alvinttang merged 1 commit into
mainfrom
cursor/cortex-cloud-memory-2g
Oct 17, 2026
Merged

alvinttang merged 1 commit into
mainfrom
cursor/cortex-cloud-memory-2g

Conversation

@alvinttang

Copy link
Copy Markdown
Collaborator

What & why

Pins the boss-approved memory plan for the cortex-cloud container into the deploy config.

  • Approval: On 2026-10-16 at 21:36 ET, the boss approved giving cortex-cloud a 2g memory limit. Until then it had no limit.
  • Already live: The running container was already changed to 2g with docker update. This PR changes no live state. It only makes the next deploy.sh run recreate the container with the same limit, so a redeploy doesn't remove it.
  • Change: deploy/cortex-cloud/deploy.sh now passes --memory 2g --memory-swap 2g to docker run, before the image name. The host has no swap, so --memory-swap is 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

  • Bug fix
  • New feature
  • Performance
  • Docs
  • Refactor / internal (deploy config)

Checklist

  • cargo fmt --all clean (no Rust changes)
  • cargo clippy --workspace --all-targets -- -D warnings clean (no Rust changes)
  • cargo test --workspace passes (no Rust changes)
  • Added/updated tests for the change (no test covers deploy.sh; checked with bash -n deploy/cortex-cloud/deploy.sh and git diff --check)
  • No new telemetry or third-party data egress; local-first preserved
  • (If perf-sensitive) included before/after cargo bench numbers below

Draft only. Do not merge or deploy as part of this PR.

Open in Web Open in Cursor 

Co-authored-by: Alvin Tang <alvinttang@users.noreply.github.com>
@cursor

cursor Bot commented Oct 17, 2026

Copy link
Copy Markdown

只读审查(PR #16:--memory 2g --memory-swap 2g)

审查范围:全部部署入口(redeploy / restart / compose / systemd)、--memory-swap 是否等于 --memory、其它 limit 是否回退、文档是否自洽、以及 cortex-cloud 真实 RSS 是否装得进 2g。上下文:宿主机 32GB、cgroup v2、无 swap;老板已批准 cortex-cloud 2g。本环境无法登录生产机测实时 RSS,结论来自代码与 Docker 语义。

部署路径

路径 文件 结论
重建 / 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

  1. [OK] deploy/cortex-cloud/deploy.sh:39
    --memory 2g --memory-swap 2g 语义正确、位置正确、两者相等。redeploy 会钉死限额;restart 走同一 HostConfig。

  2. [MEDIUM] deploy/cortex-cloud/cortex-cloud.service:6-24
    文档列出的 systemd 路径没有等价的 MemoryMax=2G + MemorySwapMax=0。生产走 Docker,不挡这次合并;若 2g 是服务级政策,这条路径仍裸奔。

  3. [MEDIUM] cortex-cloud/src/main.rs:56 + cortex-mcp-server/src/gateway/cloud.rs:29
    2g 硬顶 + 无 swap,使「64 路满额 export」从「吃主机内存」变成「容器 OOM」。flags 本身没错,是限额下的残余容量风险。

  4. [LOW] deploy/cortex-cloud/README.md:20-26
    生产 docker run 现已带 2g,README / docs/design/muse-cloud.md 未记录。不矛盾,部署合同不完整。

  5. [INFO] 无 compose;renew-cortex-cert.sh 不重建容器;其它 limit 无回退。
    本环境未测生产 RSS。


APPROVE

@cursor

cursor Bot commented Oct 17, 2026

Copy link
Copy Markdown

模型 B 审

只读独立复核:PR 仅改 deploy/cortex-cloud/deploy.sh;CI 的 Rust 测试、Clippy、隐私检查均通过。本环境无法读取生产容器的实时 RSS/cgroup 指标,以下容量判断基于代码上界,不把“已经 live”当作实测证据。

  1. [PASS] deploy/cortex-cloud/deploy.sh:36-40
    docker rm -f 后唯一的生产重建命令在镜像名前传入 --memory 2g --memory-swap 2g,CLI 位置正确。Docker 中 --memory-swap 表示 RAM+swap 总额;与 --memory 相等即 swap 额度为 0。在 cgroup v2 上预期为 memory.max=2G、memory.swap.max=0,符合 32GB、无 swap 宿主机及已批准的 2g 容器上限。

  2. [PASS] deploy/cortex-cloud/deploy.sh:37
    --restart unless-stopped、docker restart、daemon/主机重启都复用同一容器 HostConfig,不会丢失限额。仓库没有 compose 配置;证书续期脚本只 reload nginx;未发现第二个当前生产 recreate 路径,也没有其它既有限额被覆盖或回退。

  3. [LOW] deploy/cortex-cloud/cortex-cloud.service:6-24
    A 指出的 systemd 缺口真实存在:替代部署单元没有等价的 MemoryMax=2G / MemorySwapMax=0。但 README 将它限定为 “Any other host”,老板批准和本 PR 的目标明确是生产 Docker 容器;这是既存、非生产路径,不应阻塞本 PR。若 2g 要成为所有安装方式的服务级政策,应单独补齐。

  4. [INFO] deploy/cortex-cloud/RELEASE_2026-10-07.md:52-55
    历史发布报告的回滚命令会 docker start 当时保留的旧容器,因此沿用旧 HostConfig,不能保证有 2g 限额。不过当前 deploy.sh 已不自动保留该回滚容器,README 也明确这是历史记录,不属于当前 redeploy 流程。

  5. [MEDIUM] cortex-cloud/src/main.rs:51-58,413-420,599-609;cortex-mcp-server/src/gateway/cloud.rs:27-29
    A 的并发 export 风险成立,而且 64 × 24MiB = 1.5GiB 只是 body 缓冲本身:解析期间还会分配 String/Vec<f32>,再叠加模型、租户缓存和 SQLite,因此 64 个不同租户同时提交接近上限的 export 足以触碰 2GiB 并被 OOM kill。每租户锁不能限制跨租户并发。建议后续增加 export 专用 semaphore 或做峰值压测;但这是既存并发/请求上限在硬隔离下暴露出的容量风险,本 PR 没有扩大它,反而把最坏影响限制在容器内,故不作为本次阻塞项。

  6. [LOW] cortex-cloud/src/main.rs:45,300-333,888-905;cortex-core/src/storage/sqlite.rs:130-159
    稳态从结构上看能装进 2GiB:MiniLM 模型由所有租户共享一份;租户 LRU 最多 64;每租户仅 writer+1 reader。SQLite 的 64MiB page cache 与 256MiB mmap 是按连接上限/虚拟映射,不是启动即常驻分配,而每租户最多 1000 条 export。结论是“稳态有合理余量”,不是实测保证;合并后仍应以 docker stats、memory.current、memory.events 验证峰值和 OOM 记录。

结论:参数语义、位置及当前生产部署覆盖均正确。A 的 systemd 备注应降为 LOW;64 路 export 备注维持 MEDIUM,但两者都不构成本 PR 的回归或合并阻断。

APPROVE

@alvinttang
alvinttang marked this pull request as ready for review October 17, 2026 02:46
@alvinttang
alvinttang merged commit 00f0e38 into main Oct 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants