Dockerizing Spring Boot War

In this blog post, I will show you how to create Docker images of Spring Boot Applications which are deployed as war files in Tomcat.

In one of previous blog post, I have covered how to dockerize the Spring Boot Jar files.

Now Let’s see , How to dockerize the Spring Boot war file.

1. Create Sample Spring Boot application

Head over to start.spring.io and create sample application and select war as packaging.

For demonstration purpose, I have created sample controller which responds with “Hello World” when the path is /welcome/hello

If you have existing Spring Boot application which deployed as Jar file, You can convert to package as war file. You can find step by step guide here.

Run following command to create war file

mvn clean packageCode language: Java (java)

2. Writing Dockerfile

Since Spring Boot war file needs to be deployed in webserver, we will take Tomcat as base image for Docker image.

The default Tomcat environment in the image is:

CATALINA_BASE:   /usr/local/tomcat
CATALINA_HOME:   /usr/local/tomcat
CATALINA_TMPDIR: /usr/local/tomcat/temp
JRE_HOME:        /usr
CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jaCode language: Java (java)

To deploy our application, we need to copy our war file to /usr/local/tomcat/webapps folder

FROM docker.io/tomcat:9.0.68-jdk17

COPY /target/*.war /usr/local/tomcat/webapps/samplewarapp.war

RUN addgroup  springboot && adduser tomcat
RUN usermod -G springboot tomcat
RUN chown -R tomcat /usr/local/tomcat
USER tomcat

EXPOSE 8080Code language: Dockerfile (dockerfile)

Inside container default user will be root,it is not best practice to run the application with root user so I am running application under “tomcat” user

In above Docker file, we are copying our war file to samplewarapp file inside Tomcat webapps folder.

So the application context will be /samplewarapp

Building docker image

docker build . -f ./Dockerfile.multistage -t springboot-war-dockerCode language: Java (java)

Running the docker container

docker run -p 8080:8080 springboot-war-dockerCode language: Java (java)

When you enter following address in the browser, you should see “hello World” on the browser.

http://localhost:8080/samplewarapp/welcome/hello

Multistage Dockerfile

You can also use multistage docker file to deploy the war file.

In multistage file, instead of depending on tomcat to expand the war file, we manually extract and copy the project files to webapps folder.

FROM docker.io/tomcat:9.0.68-jdk17 as stage1

ARG WAR_FILE=target/*.war

RUN mkdir -p /app/samplewarapp

COPY ${WAR_FILE} /app/samplewarapp/samplewarapp.war

WORKDIR /app/samplewarapp
RUN jar -xf samplewarapp.war && rm samplewarapp.war


FROM docker.io/tomcat:9.0.68-jdk17
ARG PROJECT_DIR=app
COPY --from=stage1 ${PROJECT_DIR} /usr/local/tomcat/webapps/



RUN addgroup  springboot && adduser tomcat
RUN usermod -G springboot tomcat
RUN chown -R tomcat /usr/local/tomcat
USER tomcat

EXPOSE 8080
Code language: Java (java)

Following dockerfile is another version of multi stage docker file.

In this file we are copying individual folders after extracting the war file.

FROM docker.io/tomcat:9.0.68-jdk17 as stage1

ARG WAR_FILE=target/*.war

RUN mkdir -p /app/samplewarapp

COPY ${WAR_FILE} /app/samplewarapp/samplewarapp.war

WORKDIR /app/samplewarapp
RUN jar -xf samplewarapp.war


FROM docker.io/tomcat:9.0.68-jdk17
RUN mkdir /usr/local/tomcat/webapps/samplewarapp
ARG PROJECT_DIR=app/samplewarapp
COPY --from=stage1 ${PROJECT_DIR}/META-INF /usr/local/tomcat/webapps/samplewarapp/META-INF
COPY --from=stage1 ${PROJECT_DIR}/org /usr/local/tomcat/webapps/samplewarapp/org
COPY --from=stage1 ${PROJECT_DIR}/WEB-INF /usr/local/tomcat/webapps/samplewarapp/WEB-INF



RUN addgroup  springboot && adduser tomcat
RUN usermod -G springboot tomcat
RUN chown -R tomcat /usr/local/tomcat
USER tomcat

EXPOSE 8080
Code language: Java (java)

Building docker image

docker build . -f ./Dockerfile.multistage -t springboot-war-dockerCode language: Java (java)

Running the docker container

docker run -p 8080:8080 springboot-war-dockerCode language: Java (java)

Testing war file in Local Development.

When you are developing application, if you want to test your war application in docker container

you can use docker compose file to simplify the testing process instead of repeating docker commands to to create image and run the container.

We use the volume concept to copy the war file inside container.

volumes tag copies the war file to specified path inside container.

You can use following docker compose file

version: '3'

services:
  sb-war-app:
    image: 'docker.io/tomcat:9.0.68-jdk17'
    ports:
      - 8080:8080
    volumes:
      - ./target/sb-war-docker-0.0.1-SNAPSHOT.war:/usr/local/tomcat/webapps/samplewarapp.warCode language: Java (java)

If you have already built the image of your application, you can also use that image instead of tomcat image.

version: '3'

services:
  sb-war-app:
    image: 'sb-war-docker'
    ports:
      - 8080:8080
    volumes:
      - ./target/sb-war-docker-0.0.1-SNAPSHOT.war:/usr/local/tomcat/webapps/samplewarapp.warCode language: Java (java)

First build your applications

mvn clean packageCode language: Java (java)

Now , you can bring-up the container with your application deployed with below command.

docker-compose upCode language: Java (java)

You can stop the container with following command

docker-compose downCode language: Java (java)

Similar Posts