摘要:在当今互联网大厂后端开发的快节奏环境中,高效部署应用是保障业务快速迭代与拓展的关键。Spring Boot3 凭借其强大功能深受开发者青睐,而将 spring Boot3 应用打包成 Docker 镜像,更能实现 “一次构建,到处运行” 的便捷部署,极大提升开
在当今互联网大厂后端开发的快节奏环境中,高效部署应用是保障业务快速迭代与拓展的关键。Spring Boot3 凭借其强大功能深受开发者青睐,而将 spring Boot3 应用打包成 Docker 镜像,更能实现 “一次构建,到处运行” 的便捷部署,极大提升开发与运维效率。本文将深入剖析这一关键流程,助你轻松掌握。
Spring Boot3 优势
Spring Boot3 极大地简化了开发流程,其自动配置机制堪称开发利器。以往在开发 Java 应用时,开发人员往往需要花费大量时间和精力去编写繁琐的 XML 配置文件,来配置各种 Bean、数据源、事务管理等。而 Spring Boot3 的自动配置功能,能够根据项目中引入的依赖,自动推断并配置相应的 Bean。例如,当我们在项目中引入了spring-boot-starter-data-JPA和数据库驱动依赖后,Spring Boot3 会自动配置好数据源、JPA 相关的 Bean,开发者无需手动编写复杂的 XML 配置,只需在application.properties或application.yml文件中进行简单的属性配置即可。这使得开发人员能够将更多的时间和精力投入到核心业务逻辑的开发中,显著提升了开发效率。
Docker 容器化魅力
Docker 通过创新的容器化技术,将应用及其所有依赖项封装在一个独立的容器中。这就好比将一个完整的 “小世界” 装进了一个盒子里,这个 “小世界” 包含了应用运行所需的一切,从操作系统的运行时环境、各种依赖库,到应用程序本身。在传统的开发与部署模式下,应用在开发环境中运行良好,但在测试环境或生产环境中却可能因为环境差异而出现各种问题,例如依赖库版本不一致、操作系统配置不同等。
Docker 的出现彻底改变了这一局面,它实现了环境的一致性和隔离性。无论在开发人员的本地机器、测试服务器,还是生产环境的服务器上,只要安装了 Docker,相同的 Docker 镜像就能够以完全相同的方式运行,确保了应用在不同环境中的行为一致性。同时,容器之间相互隔离,一个容器内的应用出现问题,不会影响到其他容器中的应用,极大地提高了应用的稳定性和可靠性。此外,Docker 镜像的可移植性也非常强,可以轻松地在不同的操作系统和硬件平台上运行,使得应用的部署和迁移变得前所未有的便捷。
安装 Docker
Windows 系统:
首先,打开浏览器,访问 Docker 官方网站(https://www.docker.com/ )。在官网首页找到适合 Windows 系统的 Docker Desktop 下载链接,点击下载安装程序。下载完成后,运行安装程序,按照安装向导的提示进行操作,一路点击 “下一步”,接受许可协议等。安装过程中可能会提示需要启用 Hyper-V 等虚拟化功能,根据提示进行相应设置。安装完成后,在开始菜单中找到 Docker Desktop 并打开。首次启动时,Docker 可能会进行一些初始化配置,等待初始化完成。验证安装是否成功,打开命令提示符(CMD),输入命令 “docker version”。如果能够正确显示 Docker 的客户端和服务器版本信息,则说明安装成功。MacOS 系统
同样在浏览器中进入 Docker 官方网站。
找到针对 MacOS 的 Docker Desktop 下载链接,下载安装包。下载完成后,双击安装包,将 Docker 图标拖曳到 “应用程序” 文件夹中进行安装。安装完成后,打开 “应用程序” 文件夹,启动 Docker Desktop。启动过程中,系统可能会提示输入管理员密码以完成一些必要的系统配置。在终端中输入 “docker version” 命令,若能正常显示版本信息,表明安装无误。Linux 系统(以 Ubuntu 为例):
打开终端,通过以下命令更新系统软件包列表:
sudo apt update接着安装一些必要的依赖包,用于后续安装 Docker:
sudo apt install apt - transport - https ca - certificates curl software - properties - common添加 Docker 官方的 GPG 密钥,确保软件源的安全性:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker - archive - keyring.gpg添加 Docker 软件源:
echo "deb [arch=$(dpkg --print - architecture) signed - by=/usr/share/keyrings/docker - archive - keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release - cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null再次更新软件包列表:
sudo apt update最后安装 Docker 引擎:
sudo apt install docker - ce docker - ce - cli containerd.io安装完成后,使用以下命令验证安装结果:
sudo docker run hello - world如果能看到 “Hello from Docker!” 等相关提示信息,说明 Docker 在 Linux 系统上安装成功。
在将 Spring Boot3 应用打包成 Docker 镜像之前,必须确保项目已经开发完成并且在本地能够稳定、正确地运行。首先,利用 Maven 或 Gradle 等构建工具对项目进行打包。如果使用 Maven,在项目根目录下打开命令行终端,执行以下命令:
mvn clean package这条命令会先清理项目之前构建生成的文件,然后重新编译项目代码,将项目打包成一个可执行的 JAR 包。打包完成后,生成的 JAR 包通常位于项目的 “target” 目录下。例如,如果项目名称为 “spring - boot - 3 - app”,那么生成的 JAR 包可能名为 “spring - boot - 3 - app - 0.0.1 - SNAPSHOT.jar”。确保该 JAR 包能够在本地通过命令 “java - jar target/spring - boot - 3 - app - 0.0.1 - SNAPSHOT.jar” 成功运行,并且项目的各项功能都能正常使用,没有报错或异常行为。如果项目依赖数据库等外部资源,要确保在本地测试时,项目能够正确连接并操作这些资源。
选择基础镜像
在构建 Docker 镜像时,选择合适的基础镜像是至关重要的第一步。推荐使用 OpenJDK 的精简版镜像,比如 “openJDK:11 - jre - slim”。这类镜像具有诸多优势,首先,它极大地减少了镜像的体积。传统的完整 JDK 镜像包含了大量开发工具和文档等不必要的文件,体积往往较大。而 “openjdk:11 - jre - slim” 镜像只包含了运行 Java 应用所需的最小运行时环境,去除了大量冗余内容,使得镜像体积大幅减小。这不仅在镜像的存储和传输过程中节省了大量的空间和带宽,还能加快镜像的下载和部署速度。其次,精简版镜像有助于提升性能,因为其占用的系统资源更少,容器启动和应用运行时的资源开销也相应降低。
当然,在实际项目中,还需要根据项目的特定需求来选择基础镜像。例如,如果项目对 Java 版本有特殊要求,比如必须使用 Java 17,那么就需要选择对应的 OpenJDK 17 的基础镜像,如 “openjdk:17 - jre - slim”。或者,如果项目依赖一些特定的操作系统环境或库,可能需要选择包含这些依赖的定制化基础镜像。
复制 JAR 包到容器内
当确定了基础镜像后,接下来要做的是将本地生成的 Spring Boot3 项目的 JAR 包复制到容器内部。在 Dockerfile 中,可以使用以下指令来实现:
COPY target/your - spring - boot - app.jar /app/这里,“target/your - spring - boot - app.jar” 需要替换为实际生成的 JAR 包路径和名称。例如,如果实际生成的 JAR 包名称为 “spring - boot - 3 - app - 1.0.0.jar”,且位于项目根目录下的 “target” 目录中,那么指令应写为 “COPY target/spring - boot - 3 - app - 1.0.0.jar/app/”。而 “/app/” 表示将 JAR 包复制到容器内的 “/app” 目录下。这个目录可以根据个人习惯和项目需求进行调整,但通常建议选择一个简洁、易于管理的目录路径。在后续容器启动和运行应用时,将基于这个目录来定位和执行 JAR 包。
设置工作目录
使用 “WORKDIR” 指令可以设置容器内的工作目录,其在 Dockerfile 中的用法如下:
WORKDIR /app这行指令的作用是将容器内的当前工作目录设置为 “/app”。设置工作目录的重要性在于,后续在容器内执行的命令,如运行 JAR 包、执行脚本等,都将基于这个目录。例如,当我们使用 “ENTRYPOINT” 指令来定义容器启动时运行 JAR 包的命令时,如果工作目录设置为 “/app”,且 JAR 包已复制到该目录下,那么命令可以简洁地写为 “ENTRYPOINT ["java", "-jar", "your - jar - name.jar"]”。如果不设置工作目录,在执行命令时就需要指定 JAR 包的完整路径,这会使命令变得复杂且容易出错。同时,统一的工作目录也有助于提高 Dockerfile 的可读性和可维护性,方便开发人员和运维人员理解和管理容器内的文件操作。
暴露端口
Spring Boot3 应用在运行时会监听特定的端口,以便外部能够访问应用提供的服务。在 Dockerfile 中,需要使用 “EXPOSE” 指令来暴露容器内应用所使用的端口。假设 Spring Boot3 应用运行在 8080 端口,那么在 Dockerfile 中添加如下指令:
EXPOSE 8080这行指令告诉 Docker,当容器运行时,要将容器内部的 8080 端口暴露出来,使得外部可以通过相应的端口映射来访问容器内的应用。如果应用实际监听的端口不是 8080,而是其他端口,比如 9090,那么 “EXPOSE” 指令中的端口号也需要相应地修改为 9090。在后续运行容器时,需要通过端口映射将容器内暴露的端口与宿主机的某个端口关联起来,这样才能从宿主机外部访问到容器内运行的 Spring Boot3 应用。
定义启动命令
最后,在 Dockerfile 中需要定义容器启动时要执行的命令,以确保容器启动后能够正确运行 Spring Boot3 应用的 JAR 包。使用 “ENTRYPOINT” 指令可以实现这一目的,示例如下:
ENTRYPOINT ["java", "-jar", "/app/your - jar - name.jar"]这里,“/app/your - jar - name.jar” 需要替换为实际复制到容器内的 JAR 包路径和名称。例如,如果 JAR 包名为 “spring - boot - 3 - app - 1.0.0.jar” 且位于 “/app” 目录下,那么指令应写为 “ENTRYPOINT ["java", "-jar", "/app/spring - boot - 3 - app - 1.0.0.jar"]”。“ENTRYPOINT” 指令定义的命令会在容器启动时作为主进程运行,容器的生命周期也与这个主进程相关联。一旦这个主进程结束,容器也会随之停止。通过这种方式,确保了容器启动后能够自动运行 Spring Boot3 应用,为外部提供服务。
执行构建命令
在完成 Dockerfile 的编写后,接下来就可以在项目根目录下构建 Docker 镜像了。使用以下命令进行镜像构建:
docker build -t your - image - name.在这个命令中,“-t” 参数用于指定镜像的名称和标签。建议采用 “项目名:版本号” 的格式来命名镜像,这样能够清晰地标识镜像所对应的项目和版本信息。例如,如果项目名称为 “spring - boot - 3 - app”,当前版本为 “1.0.0”,那么可以将镜像命名为 “spring - boot - 3 - app:1.0.0”。最后的 “.” 表示构建镜像时使用当前目录下的 Dockerfile 文件。执行该命令后,Docker 会读取 Dockerfile 中的指令,按照指令顺序依次执行各项操作,如下载基础镜像(如果本地不存在)、复制文件、设置环境变量、执行命令等,最终构建出我们所需的包含 Spring Boot3 应用的 Docker 镜像。
构建过程解析
在执行 “docker build” 命令后,Docker 的构建过程会经历多个步骤。首先,如果本地没有指定的基础镜像,Docker 会从 Docker Hub 等镜像仓库下载基础镜像。这个过程的耗时取决于基础镜像的大小以及网络状况。在网络良好的情况下,较小的基础镜像可能在短时间内就能下载完成,而较大的基础镜像则可能需要几分钟甚至更长时间。
下载完成基础镜像后,Docker 会根据 Dockerfile 中的指令,逐步复制文件到镜像中。例如,将本地项目生成的 JAR 包复制到容器内指定目录。接着,执行其他指令,如设置工作目录、暴露端口、定义启动命令等。在构建过程中,可以通过命令行输出的构建日志来查看进度。构建日志会详细显示每一步操作的执行情况,包括指令的执行结果、文件复制的进度等。如果在构建过程中出现错误,如 Dockerfile 语法错误、文件复制失败等,构建日志也会准确地提示错误信息,方便开发者定位和解决问题。构建过程的总时长不仅受网络状况影响,还与项目的复杂度相关。项目中包含的文件越多、依赖越复杂,构建所需的时间通常也就越长。
启动容器命令
当成功构建出 Docker 镜像后,就可以使用以下命令来运行镜像并启动容器:
docker run -d -p 8080:8080 --name your - container - name your - image - name在这个命令中,各个参数都有着重要的作用。“-d” 参数表示让容器在后台运行,这样在启动容器后,命令行终端不会被容器的输出占用,我们可以继续执行其他命令。“-p” 参数用于进行端口映射,将容器内的端口映射到宿主机的端口。这里 “8080:8080” 表示将容器内的 8080 端口映射到宿主机的 8080 端口。
如果 Spring Boot3 应用在容器内监听的是其他端口,或者希望将容器端口映射到宿主机的不同端口,只需相应地修改 “-p” 参数后的端口号即可。例如,如果容器内应用监听 9090 端口,想映射到宿主机的 8888 端口,那么参数应写为 “-p 8888:9090”。“--name” 参数用于为容器指定一个名称,方便后续对容器进行管理和操作。这里 “your - container - name” 可以替换为自定义的容器名称,比如 “spring - boot - 3 - app - container”。最后的 “your - image - name” 则是之前构建镜像时指定的镜像名称,如 “spring - boot - 3 - app:1.0.0”。通过这个命令,Docker 会根据指定的镜像创建并启动一个容器,容器内的 Spring Boot3 应用也会随之运行起来。
访问应用
容器启动后,我们可以通过浏览器访问宿主机对应的端口来验证 Spring Boot3 应用是否正常运行。假设宿主机的 IP 地址为 “192.168.1.100”,并且在启动容器时将容器内应用的 8080 端口映射到了宿主机的 8080 端口,那么在浏览器地址栏中输入 “http://192.168.1.100:8080”,如果应用运行正常,浏览器将会显示 Spring Boot3 应用的页面内容。
需要注意的是,如果 Spring Boot3 应用依赖其他资源,如数据库、缓存等,在容器运行时,必须确保容器能够正确连接到这些资源。如果应用连接的是外部数据库,要确保数据库的地址、端口、用户名、密码等配置正确,并且数据库服务器的网络是可达的。例如,如果应用使用 MySQL 数据库,在 Spring Boot3 项目的配置文件(如 “application.properties” 或 “application.yml”)中,数据库连接配置可能如下:
spring.datasource.url=jdbc:MySQL://192.168.1.101:3306/your - database - namespring.datasource.username=your - usernamespring.datasource.password=your - password这里 “192.168.1.101” 是数据库服务器的 IP 地址,“3306” 是 MySQL 默认端口,“your - database - name”“your - username”“your - password” 都需要替换为实际的数据库名称、用户名和密码。如果数据库服务器在容器内部署,可能还需要进行额外的网络配置,确保容器之间能够相互通信。
来源:从程序员到架构师一点号