学习地址:https://www.skillup.host/1/docker/mini.md
# Docker 镜像优化实用指南
## 简介
Docker 是一种容器引擎,可以在容器内运行应用程序。优化 Docker 镜像大小的好处:
- 减少安全风险
- 加快镜像传输速度
- 缩短部署时间
本指南提供 10 种减少 Docker 镜像大小的实用方法和可执行命令。
## 1. 最小化镜像层
### 原理
Dockerfile 中的每个 FROM、RUN、COPY 命令都会创建一个单独的层,增加镜像大小和构建时间。
### 优化前(多层)
```dockerfile
FROM ubuntu:latest
RUN apt update -y
RUN apt install unzip -y
RUN apt install curl -y
RUN apt install python3 -y
```
### 优化后(单层)
```dockerfile
FROM ubuntu:latest
RUN apt update -y && \
apt install unzip -y && \
apt install curl -y && \
apt install python3 -y
```
### 执行命令
```bash
# 构建优化后的镜像
docker build -t optimized-image:v1 .
# 查看镜像大小
docker images optimized-image:v1
# 查看镜像层信息
docker history optimized-image:v1
```
## 2. 使用 Docker Squash 减小镜像大小
### 原理
Docker 在构建镜像时创建很多层。压缩有助于在逻辑层中组织镜像,减少不必要的层。
### 安装 docker-squash
```bash
# 安装 docker-squash 工具
pip install docker-squash
```
### 使用命令
```bash
# 压缩现有镜像
docker-squash image:old -t image:new
# 示例:压缩 nginx 镜像
docker-squash nginx:latest -t nginx:squashed
# 比较压缩前后的大小
docker images | grep nginx
```
## 3. 使用较小的基础镜像
### 原理
选择更小的基础镜像是减小 Docker 镜像大小最直接的方法。
### 镜像大小对比
- `python:3.9` ≈ 1.3 GB
- `python:3.9-slim` ≈ 1 GB
- `python:3.9-alpine` ≈ 49 MB
### 查看镜像大小命令
```bash
# 拉取不同版本的 Python 镜像
docker pull python:3.9
docker pull python:3.9-slim
docker pull python:3.9-alpine
# 比较镜像大小
docker images | grep python
# 查看具体镜像信息
docker inspect python:3.9-alpine | grep Size
```
### Dockerfile 示例
```dockerfile
# 使用 Alpine 基础镜像
FROM python:3.9-alpine
# 安装依赖
RUN pip install --no-cache-dir flask
# 复制应用代码
COPY app.py /app/
WORKDIR /app
# 运行应用
CMD ["python", "app.py"]
```
## 4. 使用多阶段构建
### 原理
多阶段构建将 Dockerfile 分成多个阶段,只将必要的工件传递到最终镜像,显著减小镜像大小。
### Dockerfile 示例(Node.js 应用)
```dockerfile
# Stage 1: 构建阶段
FROM node:14.17-alpine3.14 as build
# 设置工作目录
WORKDIR /home/app
# 复制源代码
COPY public ./public/
COPY src ./src/
COPY package*.json ./
# 安装构建依赖
RUN apk add --no-cache g++ make python3
RUN npm install --silent
# 构建应用
RUN npm run build
# Stage 2: 运行阶段
FROM nginx:stable-alpine
# 复制 nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 从构建阶段复制构建结果
COPY --from=build /home/app/build /usr/share/nginx/html
# 暴露端口
EXPOSE 80
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
```