我试图自动化在Docker容器上部署tomcat webapps'.war的过程。为了实现这个目标,我开发了一个样本弹簧启动应用程序来作为测试。由于我的最终目标是将该流程应用于旧的现有战争应用程序,因此我将该应用程序配置为生成war文件而不是使用嵌入tomcat的jar。在tomcat Docker容器上部署.war
示例应用程序只是一个示例Spring MVC应用程序,它带有一个/greeting?id=<id>
端点,该端点只返回带有“Hello”消息的页面,其中是从MySQL数据库的表中读取的字符串。该应用程序部署在基于Tomcat映像的Docker容器上,而数据库部署在单独的mysql容器上。
通过docker-compose
脚本启动两个容器时,部署似乎已成功:两个容器正在运行,tomcat实例处于活动状态,cotainer日志中没有可见的错误消息,我可以看到部署的webapp并且标记为在http://<IP>:8082/manager/html
的tomcat管理器界面中运行。问题是在http://<IP>:8082/myapp-sample-webapp/greeting?id=<id>
我得到一个404错误。我测试了将一个test.html
静态文件放入网络应用程序中,这在http://<IP>:8082/myapp-sample-webapp/test.html
处可见。
另请注意,如果我将应用程序配置为嵌入tomcat的jar应用程序(当然也会相应地更改Dockerfile配置),我可以毫无问题地访问/greeting?id=<id>
端点。
A面的问题是,我看不到任何应用程序生成的日志(既不在泊坞窗容器的日志,docker logs ...
,也不是我配置的应用程序日志中/usr/local/tomcat/logs/myapp-sample-webapp.log
日志文件(见下文application.properties
),这是阻止我要检查问题是否某种程度上与未能MySQL数据库的连接
这是应用程序的pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.myapp</groupId>
<artifactId>myapp-sample-webapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>myapp-sample-webapp</name>
<description>Project created for testing Docker packaging of a .war web application</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<docker.image.prefix>myapp-h2020</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>${main.class}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.2.3</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}:${project.version}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.war</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
这是主控制器类:
@Controller
public class GreetingController {
@Autowired
private RecordRepository repository;
@RequestMapping("/greeting")
public String greeting(@RequestParam(value="id", required=true) Integer id, Model model) {
Record record = repository.findById(id);
String name = (record == null ? "World" : record.getName());
model.addAttribute("name", name);
return "greeting" ;
}
}
这是最主要的应用程序(命令行亚军是在最初的测试在Tomcat中嵌入模式的应用程序写入):
编辑:我更新了类由Alex的评论的建议
@SpringBootApplication
public class MyAppSampleWebappApplication extends SpringBootServletInitializer {
private static final Logger log = LoggerFactory.getLogger(MyAppSampleWebappApplication.class);
// JAR
public static void main(String[] args) {
System.out.println("Starting MyAppSampleWebappApplication (JAR)...");
log.debug("Starting MyAppSampleWebappApplication (JAR)...");
SpringApplication.run(MyAppSampleWebappApplication.class, args);
}
//WAR
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
System.out.println("Starting MyAppSampleWebappApplication (WAR)...");
log.debug("Starting MyAppSampleWebappApplication (WAR)...");
return application.sources(MyAppSampleWebappApplication.class);
}
}
这是我的文件的application.properties:
# datasource
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.driverClassName=com.mysql.jdbc.Driver
# for the moment I hardcoded references to mysql database, to replace with info from
# environment variable on "real" version
spring.datasource.url=jdbc:mysql://<IP OF HOST MACHINE>:3306/myapp-demo
spring.datasource.username=myapp
spring.datasource.password=myapp
spring.jpa.hibernate.ddl-auto=update
spring.data.jpa.repositories.enabled=true
spring.jpa.show-sql=true
logging.level.=DEBUG
logging.file=/usr/local/tomcat/logs/myapp-sample-webapp.log
这是通过mvn build:docker
使用Dockerfile生成我的应用程序的图像:
FROM tomcat
ADD tomcat-users.xml /usr/local/tomcat/conf
ADD myapp-sample-webapp.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]
最后,docker-compose
文件启动两个容器:
# container for an external mysql service
sample-mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: p4SSW0rd
MYSQL_DATABASE: myapp-demo
MYSQL_USER: myapp
MYSQL_PASSWORD: myapp
ports:
- 3306:3306
# myapp-sample-webapp web application container:
myapp-sample-webapp:
image: myapp-h2020/myapp-sample-webapp:0.0.1-SNAPSHOT
ports:
- 8082:8080
“扩展SpringBootServletInitializer”就是答案。没有这个,你的战争甚至不会在本地的tomcat容器中工作。 –