Docker 全家桶系列写到这一篇,该做个总结了。
后台常驻 9 个容器,机器是 2014 款 Mac mini,i5-4278U,8G 内存。很多人问我同一个问题:这点内存,能跑这么多东西?
我这两天专门测了一遍:一个容器一个容器看内存、看 CPU、看温度、看功耗。
结论先放这儿:平时够用,一到转码就吃紧。
一、机器的底子
| 项目 | 参数 |
|---|---|
| 型号 | Mac mini Late 2014 |
| CPU | i5-4278U,双核四线程,2.6GHz |
| 内存 | 8G DDR3L 1600(板载,不可换) |
| 硬盘 | 原来 500G 机械,我换了 512G SSD |
| 系统 | Ubuntu 24.04 LTS |
| 核显 | Intel Iris 5100 |
| 功耗 | 空闲约 13W,满载约 30W |
8G 板载内存是这台机器最大的短板,也是所有优化的出发点。
二、9 个容器都跑了什么
| # | 容器 | 作用 | 内存限制 |
|---|---|---|---|
| 1 | immich-server | 手机相册 | 1G |
| 2 | immich-ml | 机器学习 | 1.5G |
| 3 | immich-postgres | 相册数据库 | 1G |
| 4 | immich-redis | 缓存 | 256M |
| 5 | vaultwarden | 密码库 | 256M |
| 6 | jellyfin | 影视库 | 1.5G |
| 7 | alist | 网盘聚合 | 256M |
| 8 | qbittorrent | 下载 | 512M |
| 9 | npm | 反代 | 512M |
另外还有 Portainer、Uptime Kuma、Watchtower 三个轻量的,加起来不到 200M。
三、实测内存占用(空闲状态)
开机跑了一天,没有任何人使用的情况下:
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
| 容器 | 实际内存 | CPU |
|---|---|---|
| immich-server | 412MB | 0.3% |
| immich-ml | 168MB(关 CLIP 后) | 0.1% |
| immich-postgres | 356MB | 0.2% |
| immich-redis | 28MB | 0.0% |
| vaultwarden | 44MB | 0.0% |
| jellyfin | 186MB | 0.4% |
| alist | 72MB | 0.1% |
| qbittorrent | 218MB | 1.2% |
| npm | 86MB | 0.1% |
| 其余三个 | 合计约 130MB | — |
| 合计 | 约 1.6G | — |
加上系统本身占的 900M 左右,整机内存占用约 2.5G / 8G。
空闲状态下非常宽裕。
四、压力测试:三个场景
场景一:朋友用 Jellyfin 看 1080P 电影
Jellyfin 转码是这堆服务里最吃 CPU 和内存的。
- 直接播放(不转码):内存 +80M,CPU 基本不动
- 转码成 720P:CPU 双核跑满,内存 +900M
- 同时两个人转码:内存 +1.6G,开始 swap
实测:单人转码时,整机内存 3.8G,还能跑。双人转码就接近 5.5G,开始卡。
场景二:手机上传 500 张照片
Immich 上传会触发缩略图生成和机器学习队列。
- 上传瞬间:immich-server +600M
- 缩略图生成:CPU 满,持续 20 分钟左右
- 人脸识别:immich-ml 从 168M 涨到 1.1G
这个过程整机内存峰值到过 6.3G,swap 用了 400M。
场景三:qBittorrent 同时下 5 个种子
这个反而温和,内存稳定在 350M 左右,CPU 5-10%。
磁盘 IO 是瓶颈,不是内存。
五、什么时候会出事
跑了半年,被 OOM Killed 过的容器:
| 容器 | 次数 | 原因 |
|---|---|---|
| jellyfin | 2 次 | 转码时同时有人上传照片 |
| immich-ml | 3 次 | 人脸识别队列堆积 |
| immich-server | 1 次 | 数据库迁移时内存不够 |
共同点:多个吃内存的任务撞在一起。
解决办法不是加内存(板载换不了),是错峰。
六、我做的五项优化
1. 每个容器限制内存
compose 里加 mem_limit。不限制的话,一个容器能吃掉全部内存,触发系统 OOM Killer 乱杀。
2. 关掉 Immich 的智能搜索
设置里关 CLIP 模型,内存从 700M 降到 168M。人脸识别保留,因为最常用。
3. 机器学习限单线程
environment:
- MACHINE_LEARNING_WORKERS=1
4. 加大 swap
8G 内存不够的时候,swap 是救命稻草。我开了 4G swap:
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
调整 swappiness,让它别太激进:
echo 'vm.swappiness=30' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
5. 错峰
在 crontab 里给 Immich 的维护任务定个时间,避开晚上看片的高峰:
30 4 * * * docker exec immich_server curl -s localhost:2283/api/jobs/...
其实更简单:告诉朋友"晚上八点到十一点别上传大相册"。这是我实际的解决方案。
七、温度与功耗
| 状态 | CPU 温度 | 风扇转速 | 整机功耗 |
|---|---|---|---|
| 空闲 | 42°C | 1800 rpm | 13W |
| 日常使用 | 52°C | 2000 rpm | 16W |
| 单人转码 | 68°C | 3200 rpm | 24W |
| 转码 + 上传 | 78°C | 4200 rpm | 29W |
最快转速 4300 rpm,没到过。
夏天室温 30 度的时候,满载能到 82°C,风扇声音明显,但没降频。
一年电费:按平均 18W、0.6 元/度算,约 95 块。
八、结论:这台机器能跑几个
按我的实测,分三档:
| 档位 | 容器数 | 状态 |
|---|---|---|
| 轻松 | 5 个以内(纯服务类) | 内存占用 2G 以下,随便跑 |
| 舒适 | 6-8 个(含影音、相册) | 内存 3-4G,偶尔吃紧 |
| 上限 | 9-10 个(含转码、机器学习) | 内存 5-6G,峰值会 OOM |
这台机器的天花板,是"转码 + 机器学习"同时跑。
如果只跑网盘、密码库、反代、下载这些,8G 完全够,还能再塞几个。
九、什么该换机器
我的判断:
- 一个人用、偶尔看片、主要存文件 → 这台够,不用换
- 两个人以上同时看片、要转码 → 换 M4 或者带核显的 N100
- 要跑本地大模型 → 这台别想,至少 32G 内存起步
我另外有一台 E5 2696V3,64G 内存,那台是干重活的。Mac mini 定位就是"静音、省电、常年开着"的轻服务器。
最后
从第一篇文章写到现在,这台 2014 年的 Mac mini 已经当了半年家庭服务器:网盘、相册、影视、密码、下载、监控,全在里面。
13W 的功耗,一本杂志大小的体积,放在书架最下层,一年 95 块电费。
有人问我值不值,我觉得值——不是因为省了多少钱,是因为这些数据在自己手里。
这个系列到这就写完了。后面还会继续折腾:备份策略、异地容灾、外网访问加速,有想看的可以留言。
---
如果你也在折腾这套服务,碰到卡住的地方,可以加我微信 lige0552 聊聊。白天要上班,消息回得慢,看到都会回。