title: Deploy .war on tomcat Docker container
body: <p>I'm trying to automatize the process of deploying tomcat webapps' .war on docker containers. To this goal, I devleoped a sample spring boot application to use as a test. Since my final goal is to apply the process to old existing war applications, I configured the application to produce a war file instead of a jar with tomcat embedded.</p>
  
  <p>The sample application is just a sample Spring MVC application with a <code>/greeting?id=&lt;id&gt;</code> endpoint that just returns a page with a "Hello " message, where  is a string read from a table on a mysql db. The application is deployed on a Docker container based on the base tomcat image, while the database is deployed on a separate mysql container.</p>
  
  <p>When launching the two containers via a <code>docker-compose</code> script, the deployment seems to have success: The two containers are running, the tomcat instance is active, no error message is visible in cotainer logs, and I can see the webapp deployed and marked as running in the tomcat manager interface at <code>http://&lt;IP&gt;:8082/manager/html</code>. The problem is that at <code>http://&lt;IP&gt;:8082/myapp-sample-webapp/greeting?id=&lt;id&gt;</code> I get a 404 error. I tested putting a <code>test.html</code> static file inside the web app, and this is visible at <code>http://&lt;IP&gt;:8082/myapp-sample-webapp/test.html</code>. </p>
  
  <p>Note also that if I configure the application as a tomcat-embedded jar application (of course changing also Dockerfile configuration accordingly) I can access the <code>/greeting?id=&lt;id&gt;</code> endpoint without problems.</p>
  
  <p>A side problem is that I cannot see any application generated log (neither on the docker container's log with <code>docker logs ...</code>, nor in the <code>/usr/local/tomcat/logs/myapp-sample-webapp.log</code> log file that I configure for the app logging (see <code>application.properties</code> below), and this is preventing me to check whether the problems are somehow related to failing the connection to the mysql database.</p>
  
  <p>This is the pom.xml file for the application is the following:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;eu.myapp&lt;/groupId&gt;
      &lt;artifactId&gt;myapp-sample-webapp&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      &lt;packaging&gt;war&lt;/packaging&gt;
  
      &lt;name&gt;myapp-sample-webapp&lt;/name&gt;
      &lt;description&gt;Project created for testing Docker packaging of a .war web application&lt;/description&gt;
  
      &lt;parent&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
          &lt;version&gt;1.4.0.RELEASE&lt;/version&gt;
          &lt;relativePath /&gt; &lt;!-- lookup parent from repository --&gt;
      &lt;/parent&gt;
  
      &lt;properties&gt;
          &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
          &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
          &lt;java.version&gt;1.8&lt;/java.version&gt;
          &lt;docker.image.prefix&gt;myapp-h2020&lt;/docker.image.prefix&gt;
      &lt;/properties&gt;
  
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;mysql&lt;/groupId&gt;
              &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
              &lt;scope&gt;runtime&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
              &lt;artifactId&gt;lombok&lt;/artifactId&gt;
              &lt;version&gt;1.16.10&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-rest&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
              &lt;optional&gt;true&lt;/optional&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;finalName&gt;${project.artifactId}&lt;/finalName&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
                  &lt;artifactId&gt;exec-maven-plugin&lt;/artifactId&gt;
                  &lt;version&gt;1.2.1&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;mainClass&gt;${main.class}&lt;/mainClass&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
              &lt;/plugin&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;com.spotify&lt;/groupId&gt;
                  &lt;artifactId&gt;docker-maven-plugin&lt;/artifactId&gt;
                  &lt;version&gt;0.2.3&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;imageName&gt;${docker.image.prefix}/${project.artifactId}:${project.version}&lt;/imageName&gt;
                      &lt;dockerDirectory&gt;src/main/docker&lt;/dockerDirectory&gt;
                      &lt;resources&gt;
                          &lt;resource&gt;
                              &lt;targetPath&gt;/&lt;/targetPath&gt;
                              &lt;directory&gt;${project.build.directory}&lt;/directory&gt;
                              &lt;include&gt;${project.build.finalName}.war&lt;/include&gt;
                          &lt;/resource&gt;
                      &lt;/resources&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  
      &lt;repositories&gt;
          &lt;repository&gt;
              &lt;id&gt;spring-snapshots&lt;/id&gt;
              &lt;name&gt;Spring Snapshots&lt;/name&gt;
              &lt;url&gt;https://repo.spring.io/snapshot&lt;/url&gt;
              &lt;snapshots&gt;
                  &lt;enabled&gt;true&lt;/enabled&gt;
              &lt;/snapshots&gt;
          &lt;/repository&gt;
          &lt;repository&gt;
              &lt;id&gt;spring-milestones&lt;/id&gt;
              &lt;name&gt;Spring Milestones&lt;/name&gt;
              &lt;url&gt;https://repo.spring.io/milestone&lt;/url&gt;
              &lt;snapshots&gt;
                  &lt;enabled&gt;false&lt;/enabled&gt;
              &lt;/snapshots&gt;
          &lt;/repository&gt;
      &lt;/repositories&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>This is the main controller class:</p>
  
  <pre><code>@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" ;
      }
  
  }
  </code></pre>
  
  <p>This is the main application (the commandline runner was written when initially testing the application in tomcat embedded mode):</p>
  
  <p><strong>edit</strong>: I updated the class as suggested by Alex's comment</p>
  
  <pre><code>@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);
          }
  }
  </code></pre>
  
  <p>This is the application.properties for my file:</p>
  
  <pre><code># 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://&lt;IP OF HOST MACHINE&gt;: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
  </code></pre>
  
  <p>This is the Dockerfile used through <code>mvn build:docker</code> to generate the image for my application:</p>
  
  <pre><code>FROM tomcat
  ADD tomcat-users.xml /usr/local/tomcat/conf
  ADD myapp-sample-webapp.war /usr/local/tomcat/webapps/
  CMD ["catalina.sh", "run"]
  </code></pre>
  
  <p>And finally, the <code>docker-compose</code> file launching the two containers:</p>
  
  <pre><code># 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
  </code></pre>