dc_fix_oom
修复 Docker 内存溢出故障
补充说明
dc_fix_oom 解决 fnOS 内置 Docker Compose V2 在同时使用 mem_limit 与 memswap_limit 参数时丢失物理内存限制(MemoryLimit=null)的 Bug。该 Bug 导致容器无物理内存上限,持续吃满宿主机内存,触发系统 OOM、杀掉系统进程、机器卡死断连。
问题根源
mem_limit+memswap_limit双参数 → 丢失MemoryLimit=null,仅 Swap 限制生效deploy资源限制仅 Swarm 模式有效,单机 Compose 完全无效- 终极方案:使用
--compatibility兼容模式启动
最终完整版 docker-compose.yml
支持:物理内存 1.5G 上限 + 总内存(内存 + Swap)2G 上限 + 1 核 CPU 限制。
services:
xunlei:
container_name: xunlei
image: cnk3x/xunlei
network_mode: bridge
restart: always
privileged: true
hostname: mynas
ports:
- 2345:2345
volumes:
- ./config:/xunlei/data
- /vol2/1000/downloads/xunlei:/xunlei/downloads
mem_limit: 1500m # 容器最大物理内存上限 1.5GB
memswap_limit: 2000m # 物理内存 + Swap 总上限 2GB
cpus: "1.0" # 限制容器最多占用 1 个 CPU 核心
临时生效启动命令
必须携带 --compatibility 参数,否则内存限制失效:
docker compose down && docker compose --compatibility up -d
永久根治:全局自动兼容
写入 Shell 函数,全局拦截 docker compose 命令,自动拼接兼容参数:
cat >> ~/.bashrc <<'EOF'
docker() {
if [[ "$1" == "compose" ]]; then
shift
command docker compose --compatibility "$@"
else
command docker "$@"
fi
}
EOF
source ~/.bashrc
配置后直接使用原生命令,底层自动启用兼容模式:
# 等价于 docker compose --compatibility up -d
docker compose up -d
# 正常销毁、重启、日志命令全部兼容
docker compose down
docker compose restart
docker compose logs -f
配置校验命令
docker inspect xunlei | jq '.[0].HostConfig | {Memory,MemorySwap,NanoCpus}'
✅ 正常输出示例:
{
"Memory": 1572864000,
"MemorySwap": 2097152000,
"NanoCpus": 1000000000
}
- Memory: 1572864000 = 1500M 物理内存上限 ✅
- MemorySwap: 2097152000 = 2000M 总内存上限 ✅
- NanoCpus: 1000000000 = 1 核 CPU 上限 ✅
关键原理
- 单纯重启容器不会失效:只要不执行
down销毁容器,原有限制一直保留 - 销毁重建必带兼容参数:
docker compose down后重建,不加参数会复现 Bug - 全局 Shell 函数配置后,永久无需手动加参数
整套操作流程
# 1. 写入全局兼容函数
cat >> ~/.bashrc <<'EOF'
docker() {
if [[ "$1" == "compose" ]]; then
shift
command docker compose --compatibility "$@"
else
command docker "$@"
fi
}
EOF
source ~/.bashrc
# 2. 销毁重建迅雷容器
docker compose down && docker compose up -d
# 3. 校验全部限制生效
docker inspect xunlei | jq '.[0].HostConfig | {Memory,MemorySwap,NanoCpus}'