镜像瘦身节省住宅主机硬盘存储空间
为什么你的住宅主机硬盘越来越满?
很多人在家里用旧电脑或 NAS 跑 Docker 容器,时间一长就会发现硬盘空间被吃光。
罪魁祸首往往是Docker 镜像——每次拉取、构建都会留下多层缓存和废弃镜像,占掉几十甚至上百 GB。
这篇文章会手把手教你给镜像瘦身,把硬盘空间抢回来。
准备工作:先摸清家底
在动手之前,先确认你满足以下条件:
- 已安装 Docker(命令行执行
docker --version能看到版本号) - 有 root 或 sudo 权限(执行
sudo docker info不报错) - 知道自己的 Docker 数据目录(默认是
/var/lib/docker,可以通过docker info | grep "Docker Root Dir"查看)
如果你用的是宝塔面板或群晖 DSM 的 Docker 管理器,也能按本文思路操作,只是命令要换成点按钮。
三招给镜像瘦身,释放存储空间
第一招:一键清理“僵尸”镜像和缓存
这个方法最直接,零基础也能执行。
# 清理未被任何容器使用的镜像、网络、构建缓存
sudo docker system prune -a --volumes
这条命令会删除:
- 所有停止的容器
- 所有未被容器引用的镜像(包括 dangling 镜像)
- 所有未使用的网络
- 构建缓存(
/var/lib/docker/overlay2里的临时层) - 未被容器使用的匿名卷
执行后系统会提示你将释放多少空间,输入 y 确认即可。
如果你的主机上运行着重要容器,记得先确认它们不会受影响——-a 参数会删除所有未被容器引用的镜像,但不会动正在运行或停止态容器正在用的镜像。
第二招:构建镜像时只用“小号”基础镜像
很多人习惯用 ubuntu:latest(约 200MB)或 python:3.11(约 800MB),但你也许只需要一个瘦身版的 Alpine Linux。
优化方法: 在 Dockerfile 里把基础镜像换成 Alpine 或 Slim 版本。
# 原来的写法:
FROM python:3.11
# 改为:
FROM python:3.11-alpine
Alpine 版的 Python 镜像只有 50MB 左右,比完整版小了十几倍。
对于大多数 Web 服务,Alpine 完全够用。
如果必须用 Debian 系,可以用 slim 标签:
FROM node:18-slim
第三招:多阶段构建,只留运行产物
这是最优雅的镜像瘦身技术——把编译环境和运行环境分开,最终镜像只包含运行所需的二进制文件和依赖。
# 第一阶段:编译
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 第二阶段:运行
FROM alpine:3.19
WORKDIR /app
COPY --from=builder /app/myapp .
EXPOSE 8080
CMD ["./myapp"]
这样最终镜像只有几十 MB,而不是把 Go 编译器也打包进去。
如果你是用 Docker Compose,也可以在每个服务对应的 Dockerfile 中使用多阶段构建。
避坑指南:别把空间省没了,还把服务搞挂
- 不要随意删除被你正在使用的镜像:
docker system prune -a不会删除正在运行的容器引用的镜像,但如果你有停止的容器依赖某个镜像,那个镜像会被清理。如果你后续想重启那个容器,需要重新拉取。 - Alpine 基础镜像的兼容性问题:有些 C 库(如
glibc)在 Alpine 里是简化版(musl),部分应用可能报错。测试后再上生产。 - 构建缓存别一删了之:如果你经常迭代构建,缓存能大幅加速。建议只在硬盘吃紧时执行
prune,平时用docker builder prune只清理废弃的构建缓存层。 - 住宅主机可能同时在跑其他磁盘敏感服务(如 BT 下载、NAS 文件同步),清理镜像前先用
df -h确认哪个分区最紧张,别盲目清理。
验证效果:看清理后省了多少空间
运行清理命令后,你可以用以下命令确认结果:
# 查看 Docker 磁盘使用详情
docker system df
# 查看具体镜像占用的空间(从大到小排列)
docker images --format "table {{.Repository}} {{.Tag}} {{.Size}}" | sort -k3 -hr
执行 docker system prune -a 后,我的一台住宅主机从 28GB 占用降到了 6GB。
如果配合多阶段构建重建关键镜像,还能再省 2-3GB。
如果你正在处理镜像瘦身问题,建议先跑一遍 prune 命令,再逐一检查常用镜像的 Dockerfile 是否能用 Alpine 或多阶段构建优化。
遇到容器启动失败时,先回看上面的避坑说明,重点检查基础镜像兼容性。