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

发布时间:2026/5/26 23:22:32

【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-A3Registry 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]️ 构建镜像在包含Dockerfile和HelloWorld.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 └── DockerfileDemoApplication.java示例packagecom.example;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;SpringBootApplicationRestControllerpublicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}GetMapping(/hello)publicStringhello(){returnHello 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 --frombuilder /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 CLIdockerscan yourusername/spring-demo:1.0或者使用开源工具 Trivytrivy image yourusername/spring-demo:1.0 使用 BuildKit 提升构建体验BuildKit 是 Docker 的新一代构建引擎支持并行构建、更好的缓存、更清晰的输出等。启用方式exportDOCKER_BUILDKIT1dockerbuild-tmyapp.或者在/etc/docker/daemon.json中全局启用{features:{buildkit:true}} 实战案例自动化构建脚本创建一个build.sh脚本来自动化整个流程#!/bin/bashset-e# 遇错即停APP_NAMEspring-demoVERSION1.0.0IMAGE_TAG$APP_NAME:$VERSIONREGISTRY_USERyour_dockerhub_usernameecho 正在打包 Maven 项目..../mvnw clean package-DskipTestsecho️ 正在构建 Docker 镜像...DOCKER_BUILDKIT1dockerbuild-t$IMAGE_TAG.echo 正在本地测试镜像...CONTAINER_ID$(dockerrun-d-p8080:8080 $IMAGE_TAG)sleep10# 等待应用启动ifcurl-shttp://localhost:8080/actuator/health|grep-qUP;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_PORT8080 ENV PORT$APP_PORT EXPOSE $APP_PORT构建时指定dockerbuild --build-argAPP_PORT9000-tmyapp. 自动化 CI/CD 集成虽然不能提供 GitHub Actions 示例但在 Jenkins、GitLab CI、Drone 等平台都可以轻松集成 Docker 构建。通用流程代码提交触发流水线拉取代码编译打包构建 Docker 镜像推送到仓库通知部署系统 性能优化建议✅ 合理安排 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.3Spring Boot 2.3 开始支持分层 jar可以进一步优化 Docker 层缓存在pom.xml中启用plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationlayersenabledtrue/enabled/layers/configuration/plugin然后在 Dockerfile 中FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application COPY target/demo-app.jar app.jar RUN java -Djarmodelayertools -jar app.jar extract FROM eclipse-temurin:17-jre-alpine WORKDIR application COPY --frombuilder application/dependencies/ ./ COPY --frombuilder application/snapshot-dependencies/ ./ COPY --frombuilder application/resources/ ./ COPY --frombuilder 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--filteruntil720h 私有镜像仓库搭建虽然 Docker Hub 很方便但企业通常需要私有仓库。推荐使用Harbor或Nexus Repository。快速启动 Harbor使用 docker-compose# docker-compose.yml 片段version:2.3services:harbor-core:image:goharbor/harbor-core:v2.7.0# ... 其他配置访问 https://goharbor.io 获取完整安装指南。 测试你的镜像✅ 健康检查在 Dockerfile 中加入健康检查HEALTHCHECK --interval30s --timeout3s --start-period10s --retries3 \ CMD curl -f http://localhost:8080/actuator/health || exit 1运行后查看状态dockerps--formattable {{.Names}}\t{{.Status}}✅ 集成测试编写测试脚本验证镜像功能#!/bin/bashIMAGE$1CONTAINERtest-containerdockerrun-d--name$CONTAINER-p8080:8080$IMAGEsleep15if!curl-shttp://localhost:8080/hello|grep-qDockerized;thenecho❌ 测试失败dockerlogs$CONTAINERexit1fiecho✅ 所有测试通过dockerrm-f$CONTAINER 推荐学习资源Docker 官方文档https://docs.docker.comSpring Boot Docker 指南https://spring.io/guides/gs/spring-boot-docker/Alpine Linux 包查询https://pkgs.alpinelinux.org 常见问题解答❓ 如何减小 Java 镜像体积使用jlink创建自定义 JREJava 9使用 Alpine 基础镜像多阶段构建分层 Jar❓ 构建很慢怎么办使用国内镜像加速器合理利用缓存调整 Dockerfile 顺序使用 BuildKit分层构建依赖❓ 容器启动后立即退出检查ENTRYPOINT或CMD是否正确查看日志docker logs container交互式运行调试docker run -it yourimage sh 进阶使用 Jib 工具无需 DockerfileGoogle 开发的 Jib 工具可以直接从 Maven/Gradle 构建 Docker 镜像无需编写 Dockerfile。在pom.xml中添加插件plugingroupIdcom.google.cloud.tools/groupIdartifactIdjib-maven-plugin/artifactIdversion3.3.1/versionconfigurationfromimageeclipse-temurin:17-jre-alpine/image/fromtoimageyour-dockerhub-username/spring-app/imagetagstaglatest/tagtag${project.version}/tag/tags/tocontainermainClasscom.example.DemoApplication/mainClassportsport8080/port/ports/container/configuration/plugin构建并推送./mvnw compile jib:buildJib 会自动优化层结构、处理依赖缓存是现代化 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! ☕ 感谢你读到这里 技术之路没有捷径但每一次阅读、思考和实践都在悄悄拉近你与目标的距离。 如果本文对你有帮助不妨 点赞、收藏、分享给更多需要的朋友 欢迎在评论区留下你的想法、疑问或建议我会一一回复我们一起交流、共同成长 关注我不错过下一篇干货我们下期再见✨

相关新闻