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

【Linux】Docker 镜像的拉取 制作与上传

👋 大家好,欢迎来到我的技术博客!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕Linux这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!


文章目录

  • 🐳【Linux】Docker 镜像的拉取、制作与上传 —— 从零到精通的完整指南
    • 🔍 什么是 Docker 镜像?
    • ⬇️ 第一部分:拉取 Docker 镜像
      • ✅ 基础命令:`docker pull`
      • 🌐 拉取私有仓库或第三方镜像
      • 🚀 加速镜像拉取 —— 配置镜像加速器
      • 📦 实战:拉取 Java 运行环境镜像
    • 🛠️ 第二部分:制作 Docker 镜像
      • 📄 编写你的第一个 Dockerfile
      • 🏗️ 构建镜像
      • ▶️ 运行你的镜像
    • 🧩 深入 Dockerfile —— 更复杂的 Java 应用
      • 📁 项目结构示例
      • 🐳 编写优化版 Dockerfile
      • 🔄 多阶段构建的优势
      • 📊 镜像大小对比图表
    • 🧪 构建并测试 Spring Boot 镜像
    • 🧹 清理无用镜像和容器
    • 📤 第三部分:上传 Docker 镜像
      • 🔐 登录 Docker Hub 或私有仓库
      • 🏷️ 标记镜像
      • ⬆️ 推送镜像
    • 🔐 安全最佳实践
      • ✅ 使用非 root 用户
      • ✅ 固定基础镜像版本
      • ✅ 扫描镜像漏洞
    • 📦 使用 BuildKit 提升构建体验
    • 🎯 实战案例:自动化构建脚本
    • 🌿 使用 .dockerignore 优化构建
    • 🧰 调试技巧
      • 🔍 查看镜像历史
      • 🕵️ 进入容器调试
      • 🧾 查看镜像详细信息
    • 🧩 高级技巧:使用 Build Args 和 ENV
    • 🔄 自动化 CI/CD 集成
    • 📈 性能优化建议
      • ✅ 合理安排 Dockerfile 指令顺序
      • ✅ 使用 .jar 分层(Spring Boot 2.3+)
    • 🧭 镜像管理策略
      • 📅 版本控制
      • 🧹 生命周期管理
    • 🌐 私有镜像仓库搭建
    • 🧪 测试你的镜像
      • ✅ 健康检查
      • ✅ 集成测试
    • 📚 推荐学习资源
    • 🧩 常见问题解答
      • ❓ 如何减小 Java 镜像体积?
      • ❓ 构建很慢怎么办?
      • ❓ 容器启动后立即退出?
    • 🎓 进阶:使用 Jib 工具(无需 Dockerfile)
    • 📊 镜像构建时间优化前后对比
    • 🧭 总结

🐳【Linux】Docker 镜像的拉取、制作与上传 —— 从零到精通的完整指南

在现代软件开发和部署中,容器化技术已经成为不可或缺的一部分。Docker 作为最流行的容器平台,其核心概念之一就是“镜像”。本文将带你深入理解 Docker 镜像的本质,掌握在 Linux 环境下如何拉取、制作并上传 Docker 镜像,并结合 Java 应用场景给出实用示例。


🔍 什么是 Docker 镜像?

Docker 镜像是一个轻量级、独立的、可执行的软件包,它包含了运行某个软件所需的一切:代码、运行时环境、系统工具、系统库和配置文件。镜像采用分层结构,每一层都是只读的,当容器启动时,会在镜像之上添加一个可写层(容器层)。

你可以把 Docker 镜像想象成一个“应用快照”,无论部署到哪台机器上,只要支持 Docker,就能保证一致的运行环境。

# 查看本地已有的镜像dockerimages

输出示例:

REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest abc123def456 2 weeks ago 142MB hello-world latest def789ghi012 3 months ago 13.3kB

⬇️ 第一部分:拉取 Docker 镜像

✅ 基础命令:docker pull

最简单的拉取方式是使用docker pull命令:

dockerpull nginx:latest

这会从 Docker Hub(默认注册中心)拉取最新版的 Nginx 镜像。

你也可以指定特定版本:

dockerpull openjdk:17-jdk-slim

这个命令会拉取 OpenJDK 17 的精简版镜像,非常适合运行 Java 应用。


🌐 拉取私有仓库或第三方镜像

如果你使用的是阿里云、腾讯云等国内镜像加速服务,或者公司内部私有仓库,可以这样拉取:

dockerpull registry.cn-hangzhou.aliyuncs.com/library/nginx:1.21

或者登录后拉取私有镜像:

dockerlogin myregistry.example.comdockerpull myregistry.example.com/myapp:1.0.0

🚀 加速镜像拉取 —— 配置镜像加速器

在国内,直接访问 Docker Hub 可能较慢。推荐配置镜像加速器。

编辑/etc/docker/daemon.json(若不存在则新建):

{"registry-mirrors":["https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com","https://mirror.baidubce.com"]}

重启 Docker 服务:

sudosystemctl daemon-reloadsudosystemctl restartdocker

验证是否生效:

dockerinfo|grep-A3"Registry Mirrors"

📦 实战:拉取 Java 运行环境镜像

我们来拉取一个适合运行 Spring Boot 应用的镜像:

dockerpull eclipse-temurin:17-jre-alpine

这个镜像是基于 Alpine Linux 的轻量级 JRE 17 镜像,体积小,安全补丁更新及时,是生产环境的理想选择。


🛠️ 第二部分:制作 Docker 镜像

制作镜像的核心是编写Dockerfile—— 一个定义镜像构建步骤的文本文件。


📄 编写你的第一个 Dockerfile

假设我们有一个简单的 Java 控制台程序:

// HelloWorld.javapublicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello, Dockerized Java World! 🐳");System.out.println("Current time: "+java.time.LocalDateTime.now());}}

编译它:

javac HelloWorld.java

现在创建Dockerfile

# 使用官方 OpenJDK 17 JRE 镜像作为基础镜像 FROM eclipse-temurin:17-jre-alpine # 设置工作目录 WORKDIR /app # 将编译好的 class 文件复制进镜像 COPY HelloWorld.class . # 设置容器启动时执行的命令 CMD ["java", "HelloWorld"]

🏗️ 构建镜像

在包含DockerfileHelloWorld.class的目录下执行:

dockerbuild-tmy-java-app:1.0.

参数说明:

  • -t:指定镜像名称和标签
  • .:表示当前目录为构建上下文(context)

构建成功后,查看镜像:

dockerimages|grepmy-java-app

▶️ 运行你的镜像

dockerrun--rmmy-java-app:1.0

你应该看到输出:

Hello, Dockerized Java World! 🐳 Current time: 2025-04-05T10:30:45.123

🎉 成功!你已经制作并运行了第一个 Java Docker 镜像!


🧩 深入 Dockerfile —— 更复杂的 Java 应用

现实中的 Java 应用通常是打包成.jar文件的 Spring Boot 项目。我们来看看如何为这类应用构建镜像。


📁 项目结构示例

my-spring-app/ ├── src/ │ └── main/ │ └── java/ │ └── com/example/DemoApplication.java ├── pom.xml └── Dockerfile

DemoApplication.java示例:

packagecom.example;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}@GetMapping("/hello")publicStringhello(){return"Hello from Dockerized Spring Boot! 🐳";}}

使用 Maven 打包:

mvn clean package

生成target/demo-app.jar


🐳 编写优化版 Dockerfile

# 第一阶段:构建阶段 FROM maven:3.8.6-eclipse-temurin-17 AS builder WORKDIR /app # 复制 pom.xml 并下载依赖(利用缓存) COPY pom.xml . RUN mvn dependency:go-offline -B # 复制源码并打包 COPY src ./src RUN mvn package -DskipTests # 第二阶段:运行阶段 FROM eclipse-temurin:17-jre-alpine # 安装时区数据(可选但推荐) RUN apk add --no-cache tzdata # 创建非 root 用户提高安全性 RUN addgroup -g 1001 -S appgroup && \ adduser -u 1001 -S appuser -G appgroup WORKDIR /app # 从构建阶段复制 jar 包 COPY --from=builder /app/target/demo-app*.jar app.jar # 更改文件所有者 RUN chown appuser:appgroup app.jar # 切换到非 root 用户 USER appuser # 暴露端口 EXPOSE 8080 # 启动应用 ENTRYPOINT ["java", "-jar", "app.jar"]

🔄 多阶段构建的优势

上述 Dockerfile 使用了多阶段构建(multi-stage build),好处包括:

  • 最终镜像不包含 Maven、源码等构建工具,体积更小
  • 安全性更高(没有多余工具可被攻击者利用)
  • 构建层缓存更高效(pom.xml 不变则跳过依赖下载)

📊 镜像大小对比图表

62%20%18%镜像体积对比 (MB)单阶段含Maven多阶段仅JREAlpine优化版

可以看到,通过多阶段构建和使用 Alpine 基础镜像,体积减少了约 70%!


🧪 构建并测试 Spring Boot 镜像

# 构建镜像dockerbuild-tspring-demo:1.0.# 运行容器,映射端口dockerrun-d-p8080:8080--namemyapp spring-demo:1.0# 查看日志dockerlogs-fmyapp# 测试接口curlhttp://localhost:8080/hello

预期输出:

Hello from Dockerized Spring Boot! 🐳

🧹 清理无用镜像和容器

构建过程中会产生中间镜像,定期清理很有必要:

# 删除停止的容器dockercontainer prune# 删除未被使用的镜像dockerimage prune-a# 删除所有未使用的资源(谨慎!)dockersystem prune-a

📤 第三部分:上传 Docker 镜像

制作好的镜像,通常需要推送到远程仓库,便于团队共享或部署到生产环境。


🔐 登录 Docker Hub 或私有仓库

dockerlogin

输入你的用户名和密码(或访问令牌)。如果是私有仓库:

dockerlogin myregistry.corp.com

🏷️ 标记镜像

推送前,必须给镜像打上符合目标仓库格式的标签:

# 格式:[仓库地址/]用户名/镜像名:标签dockertag spring-demo:1.0 yourusername/spring-demo:1.0# 如果是私有仓库:dockertag spring-demo:1.0 myregistry.corp.com/yourteam/spring-demo:1.0

⬆️ 推送镜像

dockerpush yourusername/spring-demo:1.0

推送成功后,其他人就可以通过docker pull yourusername/spring-demo:1.0拉取使用了!


🔐 安全最佳实践

✅ 使用非 root 用户

前面的 Dockerfile 中我们创建了appuser,这是非常推荐的做法:

RUN adduser -u 1001 -S appuser USER appuser

避免容器内以 root 身份运行应用,降低安全风险。


✅ 固定基础镜像版本

不要使用latest标签:

# ❌ 不推荐 FROM eclipse-temurin:latest # ✅ 推荐 FROM eclipse-temurin:17.0.8_7-jre-alpine

这样可以确保构建的可重复性和稳定性。


✅ 扫描镜像漏洞

可以使用docker scan(需安装 Docker Desktop 或 Snyk CLI):

dockerscan yourusername/spring-demo:1.0

或者使用开源工具 Trivy:

trivy image yourusername/spring-demo:1.0

📦 使用 BuildKit 提升构建体验

BuildKit 是 Docker 的新一代构建引擎,支持并行构建、更好的缓存、更清晰的输出等。

启用方式:

exportDOCKER_BUILDKIT=1dockerbuild-tmyapp.

或者在/etc/docker/daemon.json中全局启用:

{"features":{"buildkit":true}}

🎯 实战案例:自动化构建脚本

创建一个build.sh脚本来自动化整个流程:

#!/bin/bashset-e# 遇错即停APP_NAME="spring-demo"VERSION="1.0.0"IMAGE_TAG="$APP_NAME:$VERSION"REGISTRY_USER="your_dockerhub_username"echo"📦 正在打包 Maven 项目..."./mvnw clean package-DskipTestsecho"🏗️ 正在构建 Docker 镜像..."DOCKER_BUILDKIT=1dockerbuild-t$IMAGE_TAG.echo"🧪 正在本地测试镜像..."CONTAINER_ID=$(dockerrun-d-p8080:8080 $IMAGE_TAG)sleep10# 等待应用启动ifcurl-shttp://localhost:8080/actuator/health|grep-q"UP";thenecho"✅ 应用健康检查通过"elseecho"❌ 应用启动失败"dockerlogs$CONTAINER_IDdockerstop$CONTAINER_IDexit1fidockerstop$CONTAINER_IDecho"🏷️ 正在标记镜像..."dockertag$IMAGE_TAG$REGISTRY_USER/$IMAGE_TAGecho"🔐 正在登录 Docker Hub..."echo"$DOCKER_PASSWORD"|dockerlogin-u"$REGISTRY_USER"--password-stdinecho"📤 正在推送镜像..."dockerpush$REGISTRY_USER/$IMAGE_TAGecho"🎉 镜像发布完成!"

💡 提示:敏感信息如密码应使用环境变量或密钥管理工具,不要硬编码在脚本中。


🌿 使用 .dockerignore 优化构建

类似.gitignore.dockerignore用于排除不需要复制到构建上下文的文件:

.git .gitignore README.md *.md target/ !target/*.jar logs/ *.log .env .DS_Store

放在项目根目录,与Dockerfile同级。


🧰 调试技巧

🔍 查看镜像历史

dockerhistorymyimage:tag

可以了解每一层做了什么、大小多少。


🕵️ 进入容器调试

如果容器启动失败,可以这样进入调试:

# 启动临时容器并进入 shelldockerrun-it--rmmyimage:tagsh# 或者针对已运行的容器dockerexec-itcontainer_namesh

🧾 查看镜像详细信息

dockerinspect myimage:tag

返回 JSON 格式的完整元数据,包括环境变量、挂载点、网络配置等。


🧩 高级技巧:使用 Build Args 和 ENV

可以在构建时传入参数:

ARG APP_PORT=8080 ENV PORT=$APP_PORT EXPOSE $APP_PORT

构建时指定:

dockerbuild --build-argAPP_PORT=9000-tmyapp.

🔄 自动化 CI/CD 集成

虽然不能提供 GitHub Actions 示例,但在 Jenkins、GitLab CI、Drone 等平台都可以轻松集成 Docker 构建。

通用流程:

  1. 代码提交触发流水线
  2. 拉取代码
  3. 编译打包
  4. 构建 Docker 镜像
  5. 推送到仓库
  6. 通知部署系统

📈 性能优化建议

✅ 合理安排 Dockerfile 指令顺序

经常变动的指令(如 COPY 源码)应放在后面,不变的指令(如安装系统包)放在前面,以便充分利用缓存。

# 👍 好的顺序 FROM ... RUN apt-get update && apt-get install -y some-package COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src # ← 经常变动放最后

✅ 使用 .jar 分层(Spring Boot 2.3+)

Spring Boot 2.3 开始支持分层 jar,可以进一步优化 Docker 层缓存:

pom.xml中启用:

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><layers><enabled>true</enabled></layers></configuration></plugin>

然后在 Dockerfile 中:

FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application COPY target/demo-app.jar app.jar RUN java -Djarmode=layertools -jar app.jar extract FROM eclipse-temurin:17-jre-alpine WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/resources/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

这样,只有业务代码变更时才会重建最后一层,大幅提升构建速度。


🧭 镜像管理策略

📅 版本控制

推荐使用语义化版本:

  • myapp:1.0.0—— 生产稳定版
  • myapp:1.0.0-beta—— 预发布版
  • myapp:sha-abc123—— Git Commit 对应版
  • myapp:latest—— 最新版(慎用于生产)

🧹 生命周期管理

制定镜像保留策略:

  • 开发环境:保留最近 10 个版本
  • 测试环境:保留带标签的所有版本
  • 生产环境:保留所有上线过的版本

可以编写脚本定期清理:

# 删除 30 天前未使用的镜像dockerimage prune-a--filter"until=720h"

🌐 私有镜像仓库搭建

虽然 Docker Hub 很方便,但企业通常需要私有仓库。

推荐使用HarborNexus Repository

快速启动 Harbor(使用 docker-compose):

# docker-compose.yml 片段version:'2.3'services:harbor-core:image:goharbor/harbor-core:v2.7.0# ... 其他配置

访问 https://goharbor.io 获取完整安装指南。


🧪 测试你的镜像

✅ 健康检查

在 Dockerfile 中加入健康检查:

HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD curl -f http://localhost:8080/actuator/health || exit 1

运行后查看状态:

dockerps--format"table {{.Names}}\t{{.Status}}"

✅ 集成测试

编写测试脚本验证镜像功能:

#!/bin/bashIMAGE=$1CONTAINER=test-containerdockerrun-d--name$CONTAINER-p8080:8080$IMAGEsleep15if!curl-shttp://localhost:8080/hello|grep-q"Dockerized";thenecho"❌ 测试失败"dockerlogs$CONTAINERexit1fiecho"✅ 所有测试通过"dockerrm-f$CONTAINER

📚 推荐学习资源

  • Docker 官方文档:https://docs.docker.com
  • Spring Boot Docker 指南:https://spring.io/guides/gs/spring-boot-docker/
  • Alpine Linux 包查询:https://pkgs.alpinelinux.org

🧩 常见问题解答

❓ 如何减小 Java 镜像体积?

  • 使用jlink创建自定义 JRE(Java 9+)
  • 使用 Alpine 基础镜像
  • 多阶段构建
  • 分层 Jar

❓ 构建很慢怎么办?

  • 使用国内镜像加速器
  • 合理利用缓存(调整 Dockerfile 顺序)
  • 使用 BuildKit
  • 分层构建依赖

❓ 容器启动后立即退出?

  • 检查ENTRYPOINTCMD是否正确
  • 查看日志:docker logs <container>
  • 交互式运行调试:docker run -it yourimage sh

🎓 进阶:使用 Jib 工具(无需 Dockerfile)

Google 开发的 Jib 工具可以直接从 Maven/Gradle 构建 Docker 镜像,无需编写 Dockerfile。

pom.xml中添加插件:

<plugin><groupId>com.google.cloud.tools</groupId><artifactId>jib-maven-plugin</artifactId><version>3.3.1</version><configuration><from><image>eclipse-temurin:17-jre-alpine</image></from><to><image>your-dockerhub-username/spring-app</image><tags><tag>latest</tag><tag>${project.version}</tag></tags></to><container><mainClass>com.example.DemoApplication</mainClass><ports><port>8080</port></ports></container></configuration></plugin>

构建并推送:

./mvnw compile jib:build

Jib 会自动优化层结构、处理依赖缓存,是现代化 Java 项目的推荐方案。


📊 镜像构建时间优化前后对比

-55855814400秒-49544467200秒-43233033600秒-36921686400秒-30610252800秒-24298905600秒-17987472000秒-11676124800秒-5364691200秒946656000秒编译源码打包Jar构建镜像分层构建镜像下载依赖复用缓存依赖编译源码优化前优化后Docker 镜像构建时间优化对比

通过缓存复用和分层构建,总构建时间从 300 秒降至 85 秒!


🧭 总结

掌握 Docker 镜像的拉取、制作与上传,是现代开发者必备技能。本文从基础命令讲起,逐步深入到 Java 应用的实战构建、安全加固、性能优化和自动化部署,希望能为你提供完整的知识体系。

记住几个关键点:

  • ✅ 使用多阶段构建减小镜像体积
  • ✅ 固定基础镜像版本确保一致性
  • ✅ 使用非 root 用户提升安全性
  • ✅ 合理利用缓存加速构建
  • ✅ 自动化测试确保镜像质量

容器化不是终点,而是持续交付和云原生架构的起点。继续探索 Kubernetes、Helm、服务网格等技术,让你的应用真正“生于云、长于云”。


🐳 “Dockerize all the things!” —— 但请记得,工具是手段,不是目的。始终关注业务价值和系统稳定性。

Happy Dockering! 🚢☕


🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍点赞、📌收藏、📤分享给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

http://www.jsqmd.com/news/893094/

相关文章:

  • Galanin Message Associated Peptide (1-41) amide (Preprogalanin-NH2 (65-105))
  • 从RNN到BERT:句子级情感分类模型原理、实战与选型指南
  • 具身智能(Embodied AI):当 Agent 拥有了身体
  • FreeRTOS临界区失效剖析:从vPortExitCritical卡死到中断优先级配置陷阱
  • 北京地区2026年京牌租赁注意事项:郭子车务理性分析 - 企业深度横评dyy6420
  • 智慧农业农机农用机器设备检测数据集VOC+YOLO格式7376张7类别
  • 终极Pyfa船舰装配工具:3个步骤快速提升EVE Online游戏胜率
  • 终极教程:在PyTorch-NPU/vit_base_patch16_224中实现NPU与CPU/GPU无缝切换
  • 【图像检测】基于交互多模型IMM过滤进行自动驾驶异常行为检测附Matlab代码
  • DSP+MatLAB联调避坑指南:CCS7导出的.dat文件头怎么处理?
  • Unity编辑器扩展:Selection类批量处理实战指南
  • 如何快速掌握开源7自由度协作机器人OpenArm:开发者终极指南
  • 2025企业邮箱安全报告发布:AI攻击升级,技术与管理协同成防护趋势
  • Lovable社区架构设计全图谱(含用户增长漏斗+UGC激励引擎+实时互动协议)
  • 基于BART与局部全局聚焦的方面级情感分析模型详解
  • 《Foundation 选项卡:设计与实现指南》
  • Kubernetes性能优化与资源管理:提升集群运行效率
  • 热红外相机标定+红外图像温度反演+作物水分应力指数CWSI计算无人机热红外遥感→反演地表温度→评估植被干旱水分状况附matlab代码
  • 对比自行搭建taotoken聚合api在github项目中的成本管理体验
  • 终极指南:5分钟上手IwrQk,打造你的专属Iwara视频体验
  • 【限时解密】Lovable高级权限矩阵配置指南:如何用3层RBAC策略守住敏感项目数据(含权限审计脚本)
  • 【AI搜索工具学生党生存指南】:20年教育技术专家亲测的5款免费神器,90%学生还不知道?
  • Windows虚拟光驱终极指南:开源免费的ISO文件挂载工具完整解析
  • 【SLAM】扩展卡尔曼滤波同步定位与地图构建的仿真程序,模拟移动机器人在包含路标、墙壁的环境中,沿着预设航点运动时的 SLAM 过程matlab代码
  • 【JavaSE - 网络部分07】TCP 收尾:面向字节流(粘包问题)与异常场景处理【传输层】
  • 高效精简答辩筹备!Okbiye 智能 AI PPT 助力毕业生完成论文宣讲展示
  • 叠氮酸介绍
  • Cisco Packet Tracer交换机进阶实战:堆叠、聚合、绑定与DHCP配置全解析
  • 用 AI 复刻潮语深情,声线 App 让人人会念 “阿嬷的情书”
  • ChatGPT辅助定量研究:Stata/Python代码生成、回归结果解读、稳健性检验提示链(附GitHub可验证代码库)