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 package
Code 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.ja
Code 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 8080
Code 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-docker
Code language: Java (java)

Running the docker container

docker run -p 8080:8080 springboot-war-docker
Code 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-docker
Code language: Java (java)

Running the docker container

docker run -p 8080:8080 springboot-war-docker
Code 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.war
Code 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.war
Code language: Java (java)

First build your applications

mvn clean package
Code language: Java (java)

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

docker-compose up
Code language: Java (java)

You can stop the container with following command

docker-compose down
Code language: Java (java)

Similar Posts