将WAR格式Web应用Docker化是否为良好实践?JavaWeb部署方案问询
问题解答
1. Docker容器中Tomcat+WAR部署模式是否为行业良好实践
该模式属于过渡阶段的常见实践,并非当前云原生场景下的最优实践,但也不属于错误方案:
- 适用场景:遗留系统需要依赖外置Tomcat的特殊配置、单容器部署多个WAR包、团队对Tomcat运维体系非常成熟无额外改造成本的场景可以继续使用
- 存在的缺陷:镜像体积普遍偏大(官方Tomcat镜像基础体积超过300M)、存在不必要的容器冗余功能、Tomcat配置和应用配置分离不利于版本管理、启动速度慢,不符合轻量化部署的趋势
2. 打JAR包内置容器的方案说明
该方案完全可行,且是当前Java Web应用部署的首选推荐方案:
- 优势:应用自包含Servlet容器(默认内置Tomcat,也可替换为Jetty、Undertow),无需依赖外置容器,最终镜像体积可缩减到原有Tomcat+WAR方案的1/3甚至更小,启动速度提升30%以上,配置统一在应用内管理,更适合Docker/K8s等云原生部署场景
- 可行性:Spring生态原生支持该模式,Spring Boot项目默认就是该打包和运行模式,传统Spring MVC项目也可以通过引入嵌入式Tomcat依赖实现
3. 可执行JAR包打包失败问题修复
报错no main manifest attribute, in mypersonalproject.jar是因为JAR包的META-INF/MANIFEST.MF文件中没有指定启动主类,按项目类型对应修复即可:
如果你使用的是Spring Boot项目
直接在pom.xml中引入Spring Boot专属打包插件即可自动生成正确的MANIFEST文件:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>对应你的Spring Boot版本号</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <!-- 如果主类不在默认扫描路径下,额外指定主类全限定名 --> <configuration> <mainClass>com.xxx.xxx.你的启动主类名</mainClass> </configuration> </plugin> </plugins> </build>
配置完成后执行mvn clean package即可生成可执行JAR包,直接用java -jar命令启动即可。
如果你使用的是传统Spring MVC项目
需要先引入嵌入式Tomcat依赖,再自行编写启动主类,最后配置Maven打包参数:
- 新增嵌入式Tomcat相关依赖到pom.xml
- 编写启动主类,示例代码如下:
package com.xxx.xxx; import org.apache.catalina.startup.Tomcat; public class AppMain { public static void main(String[] args) throws Exception { Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); tomcat.getHost().setAppBase("."); // 配置Spring上下文路径、应用资源路径等参数 tomcat.addWebapp("", "src/main/webapp"); tomcat.start(); tomcat.getServer().await(); } }
- 配置maven-jar-plugin指定主类,同时配置依赖打包插件将所有依赖打入JAR包生成fat jar,配置示例:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <configuration> <archive> <manifest> <mainClass>com.xxx.xxx.AppMain</mainClass> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
内容的提问来源于stack exchange,提问作者user1911
相关产品推荐
相关产品推荐

