2016-09-26 148 views
1

我试图自动化在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 
+0

“扩展SpringBootServletInitializer”就是答案。没有这个,你的战争甚至不会在本地的tomcat容器中工作。 –

回答

4

我想我已经找到了解决办法:

在我Dockerfile,我建立了tomcat基本映像我的应用程序的形象(“FROM tomcat”)

我发现这个图像是基于JRE 7,而在我的pom.xml中,我的版本为1.8(<java.version>1.8</java.version>

通过用更具体的版本“FROM tomcat:7-jre8”替换Dockerfile的第一行,我现在可以看到由我的控制器生成的页面。

+0

你可以接受你自己的答案。 – alexbt

-1

我不是100%肯定不看进入日志文件。

您的MVC的视图层是如何配置的?我想春天找不到“问候”的视图表示。你有什么JSP,Velocity等模板?

或者尝试篡改@ResponseBody方法。

+0

我首先将应用程序作为独立的tomcat嵌入式web应用程序进行测试,然后将配置转换为war文件以部署到生产tomcat上。在前一种情况下,一切正常,所以我很确定这些问题与MVC层配置无关。谢谢在任何情况下 – chrx