04-镜像操作-理解Docker的"蓝图"
镜像是Docker的核心
前几章我们说镜像是一个"模板",现在深入理解一下:镜像是Docker的核心,没有镜像就没有容器。
镜像的基本操作
1. 拉取镜像
从仓库下载镜像到本地:
# 基本用法
docker pull 镜像名
# 示例
docker pull nginx
docker pull python:3.11
docker pull mysql:8.0
镜像标签(Tag):
nginx:默认使用latest标签nginx:1.24:指定版本1.24python:3.11-alpine:使用alpine基础镜像(体积更小)
常用镜像源:
- Docker Hub(默认):
nginx - 阿里云:
registry.cn-hangzhou.aliyuncs.com/library/nginx
2. 查看本地镜像
# 列出所有镜像
docker images
# 只显示镜像ID
docker images -q
# 显示完整的镜像信息(包括层信息)
docker images --digests
输出说明:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 123456789abc 2 weeks ago 142MB
python 3.11 abcdef123456 3 days ago 1GB
mysql 8.0 123abc456def 1 month ago 542MB
REPOSITORY:镜像名称TAG:标签(版本)IMAGE ID:镜像唯一标识CREATED:创建时间SIZE:镜像大小
3. 删除镜像
# 删除指定镜像
docker rmi 镜像名
# 删除多个镜像
docker rmi nginx nginx:1.24 python:3.11
# 删除所有镜像(慎用)
docker rmi $(docker images -q)
# 强制删除镜像(即使有容器在使用)
docker rmi -f nginx
注意:删除镜像前要先删除基于这个镜像的容器。
4. 查看镜像详细信息
# 查看镜像详细信息
docker inspect 镜像名
# 查看镜像的层信息
docker history 镜像名
镜像的分层原理
什么是分层?
Docker镜像由多个只读层叠加而成,每层代表镜像构建的一个步骤:
┌────────────────────┐
│ 应用层(你的代码) │ ← 这层最小
├────────────────────┤
│ 依赖包层 │
├────────────────────┤
│ 运行环境层 │
├────────────────────┤
│ 基础系统层 │ ← 这层最大
└────────────────────┘
分层的好处
1. 节省空间: 多个镜像可以共享相同的层,例如:
nginx:latest ───┐
nginx:1.24 ───┼── 共享基础层(Alpine系统)
nginx:1.25 ───┘
2. 快速构建: 只重新构建变化的层,其他层直接复用。
3. 版本管理: 每层都有唯一的ID,可以精确回滚。
查看镜像的层
docker history nginx
输出示例:
IMAGE CREATED CREATED BY SIZE
123456789abc 2 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
abcdef123456 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
123abc456def 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGTERM 0B
456def789abc 2 weeks ago /bin/sh -c #(nop) COPY file:... in /etc/ngi… 5.89kB
...
IMAGE:层的IDCREATED BY:创建这一层的命令SIZE:这一层的大小
镜像的搜索
从Docker Hub搜索
# 搜索镜像
docker search 镜像名
# 示例
docker search nginx
输出说明:
NAME DESCRIPTION STARS OFFICIAL
nginx Official build of Nginx. 18000 OK
bitnami/nginx Bitnami nginx Docker Image 300
nginx-ingress-controller Ingress controller for NGIN… 2000
NAME:镜像名称DESCRIPTION:描述STARS:星标数(越多人用越好)OFFICIAL:是否官方镜像
建议优先使用官方镜像!
在Docker Hub网站搜索
访问 https://hub.docker.com,可以:
- 查看镜像详细介绍
- 查看Dockerfile
- 阅读使用文档
- 查看用户评价
构建自己的镜像
什么是Dockerfile?
Dockerfile是一个文本文件,包含构建镜像的指令:
# 基础镜像
FROM python:3.11
# 工作目录
WORKDIR /app
# 复制文件
COPY . /app
# 安装依赖
RUN pip install -r requirements.txt
# 启动命令
CMD ["python", "app.py"]
构建镜像
# 基本语法
docker build -t 镜像名:标签 Dockerfile所在目录
# 示例
docker build -t myapp:v1 .
docker build -t myapp:latest ./docker
参数说明:
-t:指定镜像名称和标签.:Dockerfile在当前目录-f:指定Dockerfile路径(如果不在当前目录)
Dockerfile常用指令
# 1. FROM - 指定基础镜像
FROM python:3.11
FROM ubuntu:20.04
# 2. WORKDIR - 设置工作目录
WORKDIR /app
# 3. COPY - 复制文件到镜像
COPY . /app
COPY requirements.txt /app/
# 4. ADD - 复制文件(支持URL和解压)
ADD https://example.com/file.tar.gz /app/
# 5. RUN - 执行命令(构建时)
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
# 6. CMD - 容器启动时执行的命令
CMD ["python", "app.py"]
# 7. ENTRYPOINT - 容器入口点(不可被覆盖)
ENTRYPOINT ["python", "app.py"]
# 8. ENV - 设置环境变量
ENV PYTHONUNBUFFERED=1
ENV PORT=8000
# 9. EXPOSE - 暴露端口
EXPOSE 8000
# 10. VOLUME - 声明数据卷
VOLUME /data
镜像的导出和导入
导出镜像
# 导出镜像为tar文件
docker save -o myapp.tar myapp:latest
# 导出多个镜像
docker save -o images.tar nginx mysql redis
导入镜像
# 从tar文件导入
docker load -i myapp.tar
# 导入并重命名
docker load < myapp.tar
场景: 在没有网络的机器上部署,可以提前导出镜像再复制过去。
镜像的标签管理
给镜像打标签
# 给镜像打新标签
docker tag nginx:latest nginx:v1.24
# 给镜像打多个标签
docker tag nginx:latest my-nginx:stable
docker tag nginx:latest registry.cn-hangzhou.aliyuncs.com/my/nginx:latest
场景: 一个镜像可以有多个标签,方便管理不同版本。
删除镜像的所有标签
# 删除镜像的所有标签
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep 'nginx')
实战:构建一个Python镜像
准备项目文件
# 创建项目目录
mkdir my-python-app
cd my-python-app
# 创建app.py
cat > app.py << 'EOF'
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, Docker!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
EOF
# 创建requirements.txt
cat > requirements.txt << 'EOF'
flask==2.3.0
EOF
# 创建Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
EOF
构建镜像
docker build -t my-python-app:latest .
运行容器
docker run -d -p 8000:8000 --name myapp my-python-app
访问验证
打开浏览器访问 http://localhost:8000,看到 “Hello, Docker!” 就成功了!
镜像优化技巧
1. 使用多阶段构建
传统方式(镜像体积大):
FROM python:3.11
COPY . /app
RUN pip install -r requirements.txt
# 最终镜像包含所有构建工具,体积大
多阶段构建(镜像体积小):
# 构建阶段
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 运行阶段
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["python", "app.py"]
2. 使用alpine基础镜像
# 传统基础镜像(900MB)
FROM python:3.11
# Alpine基础镜像(150MB)
FROM python:3.11-alpine
注意:Alpine使用musl libc而不是glibc,某些C扩展可能不兼容。
3. 合并RUN命令
# 不好(创建多个层)
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
# 好(只创建一个层)
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean
4. 清理缓存
RUN pip install --no-cache-dir -r requirements.txt
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
5. 利用构建缓存
Docker会缓存每一层,如果指令没变,就复用缓存。
优化Dockerfile顺序:
# 不好的顺序(经常变化的文件放在前面)
COPY . /app
RUN pip install -r requirements.txt
# 好的顺序(不常变化的文件放在前面)
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
常用镜像推荐
基础镜像
alpine:最轻量的Linux发行版(5MB)ubuntu:Ubuntu系统debian:Debian系统
语言运行时
python:Python环境node:Node.js环境openjdk:Java环境golang:Go语言环境
数据库
mysql:MySQL数据库postgres:PostgreSQL数据库mongo:MongoDB数据库redis:Redis缓存
Web服务器
nginx:高性能Web服务器httpd:Apache HTTP Server
本章小结
- 镜像操作:拉取、查看、删除、搜索
- 分层原理:镜像由多层叠加,节省空间
- 构建镜像:使用Dockerfile定义镜像
- 镜像优化:多阶段构建、使用alpine、合并指令、利用缓存
现在已经掌握了镜像操作,下一章我们来学习容器操作!
继续学下去,马上就能实战了!