Docker镜像优化
1.BASE 镜像优化
使用busybox 或者alpine等轻量级linux (5MB) 的发行版
2.RUN命令优化
RUN命令尽量写为一条命令,可以减少镜像体积
如
RUN yum -y install wget &&
yum -y install net-tool
yum -y install nginx
3.清理无用文件
RUN yum install -y nginx &&
# 清理YUM缓存(/var/cache/yum/ 存放下载的rpm包)
yum clean all &&
rm -rf /var/cache/yum/* /tmp/* /var/tmp/*
4.多阶段构建
核心作用:通过多阶段构建,只保留运行时必需的文件,剔除构建过程中的临时依赖(如编译工具、源码等),大幅减小最终镜像体积。
# 第一阶段:构建阶段(使用包含Maven和JDK的镜像)
FROM maven:3.8.8-openjdk-17 AS builder
WORKDIR /app
# 复制pom.xml并下载依赖(利用Docker缓存,依赖不变时无需重复下载)
COPY pom.xml .
RUN mvn dependency:go-offline # 提前下载所有依赖到本地缓存
# 复制源代码并编译打包(生成jar/war包)
COPY src ./src
RUN mvn package -DskipTests # 跳过测试加速构建,生成target/*.jar
# 第二阶段:运行阶段(使用仅含JRE的轻量镜像,约200MB,比JDK小50%以上)
FROM eclipse-temurin:17-jre-alpine # 推荐使用temurin(Adoptium)的JRE,稳定且轻量
WORKDIR /app
# 从构建阶段复制打包好的jar包(仅保留运行必需的产物)
# 注意:根据实际打包路径调整(通常在target目录下)
COPY --from=builder /app/target/*.jar ./app.jar
# 非root用户运行(安全优化)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 启动命令(Java应用常规启动方式)
CMD ["java", "-jar", "app.jar"]
5. 合理使用.dockerignore文件
作用:排除构建上下文(docker build时传递给 Docker daemon 的文件)中不需要的文件(如源码、日志、本地配置等),减少构建上下文大小,加速构建过程,同时避免敏感文件被打包进镜像。
实例
# 排除版本控制文件
.git
.gitignore
# 排除本地开发依赖
node_modules
venv
.env
.env.local
# 排除日志和临时文件
logs/
tmp/
# 排除构建产物(如果多阶段构建中已处理,可再次排除避免重复)
dist/
build/
6. 减少镜像层数
Docker 镜像由多层文件系统组成,每层对应一个指令(FROM、RUN、COPY、ADD等),层数过多会增加镜像体积和构建时间。
7. 使用更具体的镜像标签(避免:latest)
风险:latest标签指向的镜像版本会动态更新,可能导致构建的镜像版本不一致,甚至引入兼容性问题。优化:使用具体版本标签(如alpine:3.18而非alpine:latest,nginx:1.25.3而非nginx:latest),确保构建可重复性。
优化原则:
- 合并多条RUN指令;
- 避免不必要的COPY/ADD指令(例如:不要分多次复制文件,尽量合并为一条COPY);
- 注意:FROM指令会创建新层(多阶段构建中不可避免,但最终镜像仅保留最后阶段的层)。