Docker 内存限制 + 日志轮转:2核2G 小机器跑 5 个容器Docker 内存限制 + 日志轮转:2核2G 小机器跑 5 个容器

5 阅读2分钟

背景 2核2G 的小服务器,跑了 5 个容器:MariaDB、Adminer、两个 Flask、Uptime Kuma。

某天 SSH 上去,docker ps 发现一个容器不见了。日志里看到:

Killed process (mysqld) total-vm:xxxkB

OOM Killer 把 MariaDB 杀了。 原因 两个问题:

没有内存限制——每个容器都能吃光整机内存,互相抢占,最后 Linux 触发 OOM Killer 随机杀进程

日志没限制——Docker 默认把容器日志存在 /var/lib/docker/containers/,不轮转、不清理。跑几个月,几十 GB 没了 解决 内存限制 在 docker-compose.yml 里给每个服务加 mem_limit:

services:
  db:
    image: mariadb:latest
    mem_limit: 512m          # 数据库给多点

  adminer:
    image: adminer:latest
    mem_limit: 128m          # 管理界面,少点

  dashboard_a:
    build: .
    mem_limit: 256m

  dashboard_b:
    build: .
    mem_limit: 256m

  uptime-kuma:
    image: louislam/uptime-kuma:1
    mem_limit: 256m

加起来约 1.4G,给系统留了 600M 空间,不会再 OOM。 日志轮转 每个服务加 logging 配置:

logging:
  driver: "json-file"
  options:
    max-size: "10m"    # 单个日志文件最大 10M
    max-file: "3"      # 最多保留 3 个

效果:每个容器日志最多占 30M(10M × 3),5 个容器总共 150M 封顶。不会无限增长。 重启生效

docker compose up -d
docker compose ps

验证 看内存限制生效:

docker stats --no-stream

输出里 MEM LIMIT 列会显示每个容器的上限。 看日志轮转生效:

# 查看某个容器的日志文件
sudo ls -lh /var/lib/docker/containers/<CONTAINER_ID>/

*-json.log 文件不会超过 10M,而且会有 .1、.2 的备份文件。 三个坑 坑 1:只在 docker run 时加了限制,忘了 compose

docker run 用 --memory=256m,compose 用 mem_limit: 256m。两套语法不一样,别混。

坑 2:忘了给数据库留大内存

MariaDB 默认要吃几百 M 的 InnoDB 缓冲池。给它 256M 会一直 OOM。数据库至少 512M。

坑 3:日志配置只改了部分服务

全部服务都要加 logging,包括 Nginx、数据库、Uptime Kuma。只改一个没用——其他容器照样把磁盘吃满。

生活糗事:今天爬山,爬到半山腰,肚子突然一阵翻江倒海。实在顶不住,我找了个自以为够隐蔽的角落,纸巾都掏出来了,裤腰带也解开了。结果下一秒,身后突然来了一波人。我只能当场把那股洪荒之力硬生生憋回去。成年人的世界,简直比异世界还不好玩。😭😭😭