Docker Desktop 本身不控制 Compose 服务资源,真正起作用的是 docker-compose.yml 配置 + 宿主机 cgroups;但若未限制 WSL2(Windows)或 HyperKit(macOS)全局资源上限,容器仍会吃光整机内存和 CPU。

直接说结论:Docker Desktop 本身不控制 Compose 服务的资源,真正起作用的是 docker-compose.yml 配置 + 宿主机内核的 cgroups 机制;但如果你在 Windows/macOS 上用 Docker Desktop,默认的 WSL2 或虚拟机资源上限没调低,docker-compose up 的服务照样能吃光你整台电脑的内存和 CPU。
为什么 docker-compose.yml 里写了 limits 却没生效?
常见错误现象是:配置了 deploy.resources.limits.memory: 512M,运行后 docker stats 显示容器用了 2GB 内存也没被杀。这是因为:
-
deploy块只在 Docker Swarm 模式下(即docker stack deploy)才被完整解析;用docker-compose up启动时,deploy字段会被忽略 - 正确写法是把限制提到服务顶层,不用
deploy包裹:mem_limit: 512m和cpus: '0.5' - macOS 上 Docker Desktop 使用 HyperKit 虚拟机,Windows 上默认走 WSL2 —— 这两个“底层 VM”本身没设上限,容器即使有单个限制,也会让整个 VM 把宿主机资源拉满
Windows 下必须改 .wslconfig 才能治卡顿
WSL2 不是 Docker Desktop 的子进程,而是一个独立的轻量 Linux 发行版实例。Docker Desktop 只是它的客户端。你不手动限制 WSL2,它就会动态扩张到占满你物理内存(比如 32GB 主机跑出 28GB WSL2 内存占用)。
在 %UserProfile%\.wslconfig 中写入:
#[wsl2] memory=6GB processors=4 swap=1GB localhostForwarding=true
改完后必须执行:wsl --shutdown,再重启 Docker Desktop 才生效。注意:memory 是 WSL2 整体上限,不是给某个容器的 —— 所有容器共享这个池子。
macOS 上直接调 Docker Desktop 设置最省事
点击菜单栏 ? → Settings → Resources → Advanced,三个关键滑块要动:
-
CPUs:建议设为物理核心数的 60%,比如 M2 Pro 10 核就填6 -
Memory:建议不超过总内存的 40%,比如 16GB 就设6GB;低于 4GB 容易触发容器 OOM -
Disk image size:默认 64GB,但镜像 + 构建缓存实际可能撑到 100GB+,建议拉到128GB并定期docker system prune -a
这些设置改完点 Apply & Restart,会重建虚拟机,不是热更新。
Compose 文件里该用 mem_limit 还是 deploy.resources?
看你用什么命令启动:
- 日常开发、本地调试、CI 测试环境 → 用
docker-compose up→ 必须用顶层字段:mem_limit: 1g、cpus: '1.2' - 生产部署、多节点集群、需要滚动更新 → 用
docker stack deploy→ 才启用deploy.resources.limits - 别混用:比如在
deploy里写cpus,又用up启动,等于白写
示例(兼容 up 的写法):
version: '3.8'
services:
api:
image: myapp:latest
mem_limit: 1g
cpus: '1.2'
mem_reservation: 512m
mem_reservation 是软限制,只影响调度器分配意愿,不阻止超用;mem_limit 是硬边界,超了直接被 OOM killer 杀掉进程。
最容易被忽略的点:WSL2 或 macOS 虚拟机的全局资源上限,永远优先于 Compose 单容器限制。先锁住“厨房总闸”,再分灶台火候,顺序错了,再细的配置也压不住卡顿。











