Skip to content

🖼️ 镜像管理

拉取和查看镜像

bash
# 从 Docker Hub 拉取镜像
docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest

# 拉取指定版本
docker pull nginx:1.24
docker pull python:3.11-slim
docker pull mysql:8.0

# 查看本地镜像
docker images
REPOSITORY   TAG          IMAGE ID       CREATED        SIZE
nginx        latest       605c77e624dd   2 weeks ago    141MB
nginx        1.24         a8758716bb6a   3 weeks ago    141MB
python       3.11-slim    f9a40a850103   1 week ago     137MB
mysql        8.0          3218b38490ce   3 weeks ago    516MB

# 搜索镜像
docker search redis
NAME       DESCRIPTION                    STARS   OFFICIAL
redis      Redis is an open source ...    11000   [OK]

删除镜像

bash
# 删除指定镜像
docker rmi nginx:1.24

# 强制删除(有容器在用也能删)
docker rmi -f nginx:latest

# 清理所有未使用的镜像(腾出空间)
docker image prune

# 先预览会删除哪些资源
docker system df

# 大范围清理:删除所有未使用的镜像、停止的容器、未使用的网络和构建缓存
docker system prune -a
# 不会默认删除 volume;如果加 --volumes,数据库卷也可能被删,生产环境不要随手加

理解镜像分层

Docker 镜像是一层一层叠加的,就像千层蛋糕 🍰。每一层只记录和上一层的差异。

bash
# 查看镜像的分层信息
docker history nginx:latest
镜像ID         创建时间       构建命令                                        大小
605c77e624dd   2 weeks ago   CMD ["nginx" "-g" "daemon off;"]                0B
<missing>      2 weeks ago   STOPSIGNAL SIGQUIT                              0B
<missing>      2 weeks ago   EXPOSE map[80/tcp:{}]                           0B
<missing>      2 weeks ago   ENTRYPOINT ["/docker-entrypoint.sh"]            0B
<missing>      2 weeks ago   COPY 30-tune-worker-processes.sh /docker...     4.62kB
<missing>      2 weeks ago   RUN /bin/sh -c set -x && addgroup -g 101...     61.1MB
<missing>      2 weeks ago   /bin/sh -c #(nop) ADD file:caec368f5a54f...     77.8MB

💡 提示: 💡 为什么分层很重要?多个镜像可以共享相同的层!比如 nginx 和 python 都基于 debian,那 debian 基础层只存一份,省磁盘空间。

用 Dockerfile 构建镜像

Dockerfile 就是镜像的食谱,告诉 Docker 一步步怎么"做菜"。

dockerfile
# 基础镜像
FROM python:3.11-slim

# 设置工作目录(相当于 cd /app)
WORKDIR /app

# 先复制依赖文件(利用缓存,依赖没变就不重新安装)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["python", "app.py"]
bash
# 构建镜像
docker build -t myapp:1.0 .
[+] Building 12.5s (10/10) FINISHED
 => [internal] load build definition from Dockerfile
 => [internal] load .dockerignore
 => [internal] load metadata for docker.io/library/python:3.11-slim
 => [1/5] FROM docker.io/library/python:3.11-slim@sha256:...
 => [2/5] WORKDIR /app
 => [3/5] COPY requirements.txt .
 => [4/5] RUN pip install --no-cache-dir -r requirements.txt
 => [5/5] COPY . .
 => exporting to image
 => => naming to docker.io/library/myapp:1.0

# 用构建的镜像运行容器
docker run -d -p 8000:8000 myapp:1.0

多阶段构建(进阶技巧)

多阶段构建就像先在厨房做好菜,然后只把菜端出去,不把锅碗瓢盆也带出去。可以大幅减小最终镜像体积。

dockerfile
# ===== 阶段 1:构建 =====
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# ===== 阶段 2:运行 =====
FROM nginx:alpine
# 只复制构建产物,不带 node_modules
COPY --from=builder /app/dist /usr/share/nginx/html

💡 提示: 💡 效果:Node.js 镜像约 900MB,nginx:alpine 只有 40MB。最终镜像小了 800MB+!