当前位置: 首页 > news >正文

Docker镜像操作:构建、推送、拉取与优化

上一章我们掌握了容器的全流程操作,而容器的“源头”是镜像——没有镜像,就无法创建容器。本章将深入镜像的核心操作:如何拉取和管理镜像、如何用Dockerfile自定义构建镜像、如何将镜像推送到仓库分享,以及关键的镜像优化技巧(让你的镜像更小、更高效)。

学会这些,你不仅能“用别人的镜像”,还能“造自己的镜像”,真正实现“一次构建,到处运行”的Docker核心价值。

一、镜像拉取:从仓库“下载”现成的镜像 📥

大多数时候,我们不需要从零构建镜像,而是直接使用仓库中现成的镜像(比如Nginx、MySQL)。拉取镜像用docker pull命令,简单直接。

核心语法:

docker pull [仓库地址/]镜像名称[:版本标签]
  • 仓库地址:默认是Docker Hub(可省略),国内仓库需指定(如registry.cn-hangzhou.aliyuncs.com/library/nginx);
  • 版本标签:默认拉取latest(最新版),生产环境建议指定具体版本(如nginx:1.25),避免自动更新导致兼容问题。

示例:

  1. 拉取Docker Hub的Nginx最新版:
docker pull nginx  # 等价于 docker pull docker.io/library/nginx:latest
  1. 拉取指定版本的MySQL(5.7版本):
docker pull mysql:5.7
  1. 从阿里云仓库拉取Nginx(速度更快):
docker pull registry.cn-hangzhou.aliyuncs.com/library/nginx:latest

二、镜像管理:查看、删除与标签操作 📋

拉取镜像后,需要学会管理本地镜像(查看列表、删除无用镜像、给镜像打标签等)。

1. 查看本地镜像列表

docker images(或docker image ls)命令:

docker images

输出结果包含:

  • REPOSITORY:镜像仓库名;
  • TAG:版本标签(latest表示最新);
  • IMAGE ID:镜像唯一ID(前3位即可区分);
  • SIZE:镜像体积。

2. 删除本地镜像

docker rmi(或docker image rm)命令,注意删除前需先删除依赖该镜像的所有容器(否则会报错)。

  • 语法:
docker rmi 镜像ID/镜像名:标签
  • 示例:

    # 先删除依赖该镜像的容器(假设容器名为my-nginx)
    docker rm -f my-nginx  
    # 再删除镜像
    docker rmi nginx:latest  
    # 或用镜像ID删除(更快捷,只需前3位)
    docker rmi 605c77e624dd  
    
  • 批量删除无标签镜像(俗称“虚悬镜像”,标签为<none>):

docker rmi $(docker images -f "dangling=true" -q)

3. 给镜像打标签(重命名)

镜像标签不仅是版本标识,还决定了推送仓库的路径(比如推送到个人仓库需用用户名/镜像名:标签格式)。用docker tag命令打标签:

  • 语法:
docker tag 原镜像名:原标签 新镜像名:新标签
  • 示例:
    把本地的nginx:latest标记为“准备推送到个人Docker Hub仓库的mynginx:v1”:
    docker tag nginx:latest 你的DockerHub用户名/mynginx:v1
    
    此时docker images会显示一个新镜像(实际与原镜像共享存储,体积不增加)。

三、Dockerfile:构建自定义镜像的“配方” 📝

如果现成的镜像不符合需求(比如需要预装特定工具、修改默认配置),就需要自定义构建镜像。而Dockerfile就是构建镜像的“配方文件”——用指令描述镜像的构建步骤。

1. Dockerfile基础语法(核心指令)

一个简单的Dockerfile由一系列指令组成,常用指令如下:

指令作用示例
FROM指定基础镜像(必须是第一条指令)FROM nginx:1.25
RUN执行命令(构建时运行)RUN apt-get update && apt-get install -y curl
COPY复制本地文件到镜像中COPY ./index.html /usr/share/nginx/html/
ADD类似COPY,但支持URL和自动解压ADD https://xxx.tar.gz /app/
WORKDIR设置工作目录(后续命令的执行目录)WORKDIR /app
EXPOSE声明容器运行时监听的端口(仅声明)EXPOSE 80 443
CMD容器启动时执行的命令(可被覆盖)CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT容器启动时执行的命令(不可被覆盖)ENTRYPOINT ["echo", "Hello"]

2. 编写第一个Dockerfile:自定义Nginx镜像

目标:基于官方Nginx镜像,替换默认首页为自定义的index.html

步骤:

  1. 新建一个文件夹(如mynginx),在文件夹内创建两个文件:

    • Dockerfile(无后缀)
    • index.html(自定义首页内容)
  2. index.html内容:

<h1>Hello, This is My Custom Nginx!</h1>
  1. Dockerfile内容:
# 基础镜像:官方Nginx 1.25版本
FROM nginx:1.25# 维护者信息(可选)
LABEL maintainer="yourname@example.com"# 复制本地index.html到容器的Nginx默认页面目录
COPY ./index.html /usr/share/nginx/html/index.html# 声明容器监听80端口(仅文档作用)
EXPOSE 80

四、构建镜像:用Dockerfile“烘焙”镜像 🔥

有了Dockerfile,就可以用docker build命令构建镜像了。

核心语法:

docker build -t 镜像名:标签 构建上下文路径
  • -t:指定镜像的名称和标签(必填);
  • 构建上下文路径:Dockerfile所在的目录(.表示当前目录),构建时会将该目录下的所有文件发送给Docker引擎,所以不要在上下文路径放无关文件(可通过.dockerignore排除)。

示例:构建自定义Nginx镜像

mynginx文件夹所在目录执行:

docker build -t my-custom-nginx:v1 .
  • 执行过程:Docker会逐条执行Dockerfile中的指令,每一步生成一个镜像层,最后输出镜像ID表示构建成功。
  • 验证:用docker images查看,会看到my-custom-nginx:v1镜像。

运行自定义镜像验证效果:

docker run -d -p 8080:80 --name test-custom-nginx my-custom-nginx:v1

访问localhost:8080,会看到自定义的“Hello, This is My Custom Nginx!”页面,说明构建成功。

五、推送镜像:把自己的镜像分享到仓库 📤

构建好的镜像默认只存在本地,若要分享给团队或在其他机器使用,需要推送到仓库(公有仓库如Docker Hub,或私有仓库)。

步骤1:登录仓库

  • 登录Docker Hub:
docker login  # 输入Docker Hub用户名和密码
  • 登录私有仓库(如阿里云):
docker login registry.cn-hangzhou.aliyuncs.com  # 输入仓库账号密码

步骤2:给镜像打符合仓库要求的标签

仓库要求镜像标签格式为仓库地址/用户名/镜像名:版本(Docker Hub可省略仓库地址)。

示例:准备推送到Docker Hub的个人仓库:

docker tag my-custom-nginx:v1 你的DockerHub用户名/my-custom-nginx:v1

步骤3:推送镜像

docker push 你的DockerHub用户名/my-custom-nginx:v1
  • 推送成功后,在Docker Hub的个人仓库中可看到该镜像,其他人通过docker pull 你的用户名/my-custom-nginx:v1即可拉取。

六、镜像优化:让你的镜像更小、更安全 🚀

镜像体积过大会导致拉取慢、存储占用高,甚至隐藏安全风险。掌握以下优化技巧,让你的镜像“瘦身”又安全。

技巧1:使用Alpine基础镜像(体积骤减)

Alpine是一个轻量级Linux发行版,基础镜像仅5-10MB(相比Ubuntu的100+MB、CentOS的200+MB)。

示例:用Alpine版Nginx替代官方版:

FROM nginx:1.25-alpine  # 体积约20MB,而nginx:1.25约180MB
COPY ./index.html /usr/share/nginx/html/

技巧2:多阶段构建(分离构建和运行环境)

对于编译型语言(如Java、Go),构建过程需要编译器和依赖,但运行时不需要。多阶段构建可只保留运行时环境,大幅减小体积。

示例:构建Java应用(Spring Boot):

# 第一阶段:编译代码(用包含JDK的镜像)
FROM maven:3.8-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests  # 编译打包得到jar包# 第二阶段:运行环境(仅保留JRE)
FROM openjdk:17-jre-slim
WORKDIR /app
# 从第一阶段复制jar包到当前镜像
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
  • 效果:最终镜像仅包含JRE和jar包,体积比单阶段构建小70%以上。

技巧3:合并RUN命令,清理缓存

每个RUN指令会创建一个镜像层,合并命令可减少层数;同时清理安装缓存(如apt-get clean)。

反例(差):

RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y vim  # 多层+未清理缓存

正例(优):

RUN apt-get update && \apt-get install -y curl vim && \apt-get clean && \  # 清理APT缓存rm -rf /var/lib/apt/lists/*  # 删除缓存文件

技巧4:使用.dockerignore文件

排除构建上下文路径中不需要的文件(如node_modules.git),减少发送给Docker引擎的文件量,加速构建。

在Dockerfile同级目录创建.dockerignore

node_modules
.git
*.log

七、避坑指南:镜像操作常见问题 ❌→✅

  1. 构建镜像时报“COPY failed: no such file or directory”
    → 原因:COPY的源文件路径错误,或文件不在构建上下文目录中。
    → 解决:确保文件存在,且路径相对于Dockerfile所在目录(上下文路径)。

  2. 删除镜像时报“image is referenced in multiple repositories”
    → 原因:一个镜像被打了多个标签(如nginx:latestmynginx:v1指向同一镜像)。
    → 解决:先删除所有标签对应的镜像名,或用镜像ID删除。

  3. 推送镜像时报“denied: requested access to the resource is denied”
    → 原因:未登录仓库,或标签格式不符合仓库要求(如推送到Docker Hub需用用户名/镜像名)。
    → 解决:先docker login,再按仓库要求打标签。

八、总结:镜像操作核心命令与流程 📌

操作命令
拉取镜像docker pull 镜像名:标签
查看镜像列表docker images
删除镜像docker rmi 镜像ID/镜像名:标签
给镜像打标签docker tag 原镜像 新镜像:标签
构建镜像docker build -t 镜像名:标签 .
推送镜像docker push 镜像名:标签

镜像作为Docker的“静态模板”,是容器运行的基础。下一章我们将学习如何让容器中的数据持久化(避免容器删除后数据丢失),这是部署数据库等应用的关键——毕竟,谁也不想重启容器后数据全没了~

小练习:用Dockerfile构建一个自定义Python镜像(基于python:3.11-alpine),预装requests库,然后推送到你的仓库。

http://www.dtcms.com/a/602026.html

相关文章:

  • 网站流量怎么做的丹阳网站建设哪家好
  • 做团餐 承包食堂的企业网站管理咨询项目
  • 什么是大数据迁移?
  • Paimon——追根溯源
  • 门户类网站图片百度账号购买网站
  • 做钓鱼网站视频教程网络营销是什么行业
  • 安全版三权分立及密码限制
  • 网站空间在线解压网页背景做的比较好的网站
  • GIT版本管理工具轻松入门 | TortoiseGit,分支的创建与合并,笔记06
  • 网站自身seo优化怎么做ssh实训做网站代码下载
  • 网络范围的流量矩阵(TM)多步预测
  • 国外黄冈网站推广软件有哪些单县城乡住房建设局网站
  • TDengine 字符串函数 LIKE_IN_SET 用户手册
  • Spring5基础教程(2)--代理模式/AOP/Mybatis-Spring
  • 嵌入式面试题:经典蓝牙(BR/EDR)和低功耗蓝牙(BLE)的核心区别
  • 国产化改造平替的主要组件
  • 济宁市中网站建设建材网站做环保类型思路
  • Linux网络编程—Socket编程
  • 考研408--操作系统--day4--进程同步互斥信息量机制
  • 竹子建设网站河北城乡建设厅网站
  • Node.js 模块系统选择-学习 CommonJS 和 ESM
  • 手机网站模板wordpress图片粘贴插件
  • 解决报错net.sf.jsqlparser.statement.select.SelectBody
  • 模板网站如何建站app网站建设多少钱
  • 网站建设主机的功能广告中国
  • HashMap相关问题详解
  • 快站建站教程网站dns解析设置
  • java线程变量ThreadLocal用法篇v1.1
  • 变分自编码器VAE
  • K8s网络之Ingress