A simple quick guide to deploy Spring Boot Application in Docker using docker and docker-compose. You can consider this same guide to Deploy a simple Spring Boot microservice in Docker.
1. Deploy Spring Boot Application in Docker
We Just need to do following simple steps to deploy your Spring Boot app in docker.
Step 1 : Create a simple Spring Boot app or download it from our git repository SpringBoot Helloworld
Step 2 : Create a Dockerfile in root directory of your application, and add commands to build docker image.
Step 3 : Create Docker image for your Spring Boot application and start container using docker or docker-compose commands.
1.1. Spring Boot Application
Let’s have a look into following example, which is a basic Spring boot microservice application.
Project Structure :
application.properties :
Application starts in port 8181 with /helloworld
context path.
server.port=8181 server.servlet.context-path=/helloworld
HelloController :
A simple REST controller that mapped to GET request path /hello
and it returns a simple message.
@RestController public class HelloController { @GetMapping("hello") public String sayHello() { return "Hello Developer, you are awesome!"; } }
1.2. Create Dockerfile
To deploy an application in docker we need to build a docker-image first. Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. In simple, Dockerfile is a text configuration file and it contains instructions to build docker-image. Following Dockerfile illustrates the instructions to build a simple Spring Boot Application.
#FROM java:8 FROM adoptopenjdk/openjdk11:alpine-jre LABEL maintainer="[email protected]" WORKDIR /myapp COPY target/spring-boot-docker-example-0.0.1-SNAPSHOT.jar /myapp/my-app.jar ENTRYPOINT ["java","-jar","my-app.jar"]
FROM : Instruction to specify a parent or base image from which you are building. In our case we need Java Runtime Environment to start our Spring Boot Application. We are using adoptopenjdk/openjdk11:alpine-jre
as base image. Docker get it from Docker Hub which is a official repository for public docker images.
LABEL : Label is just to specify developer or organization information or url or email to represent whom it belongs.
WORKDIR : Instruction to specify working directory. This directory will be created in the container and run the specified commands from this directory.
COPY : Instruction to copy files from local source to container target.
ENTRYPOINT : Instruction to run specified commands once image successfully deployed and container is booted up.
1.3. Create Docker Image and run Container for Spring Boot App
A Docker image is a binary that includes all of the requirements for running a single Docker container, as well as metadata describing its needs and capabilities. You can think of it as a packaging technology.
Docker container is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings.
There are several ways to create docker image, Let’s have a look into how to create docker images using docker and docker-compose commands. Select the “Deploy Using Docker-Compose” from the following tabs if you would like to see deployment steps for using docker-compose.
1.3.1. Navigate to application root directory and run command docker build -t image-name:tag .
, observe the dot at end of command, if you missed it you will get error.
$ docker build -t spring-boot-image:1.0 . Sending build context to Docker daemon 17.7MB Step 1/5 : FROM adoptopenjdk/openjdk11:alpine-jre ---> aa00f19e5b22 Step 2/5 : LABEL maintainer="[email protected]" ---> Using cache ---> 47702e062067 Step 3/5 : WORKDIR /myapp ---> Using cache ---> b90566ce5c6d Step 4/5 : COPY target/spring-boot-docker-example-0.0.1-SNAPSHOT.jar /myapp/my-app.jar ---> Using cache ---> b0c2fd9d66c0 Step 5/5 : ENTRYPOINT ["java","-jar","my-app.jar"] ---> Using cache ---> 39253544ef45 Successfully built 39253544ef45 Successfully tagged spring-boot-image:1.0
Verify Created images using $ docker images
command :
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE spring-boot-image 1.0 39253544ef45 6 minutes ago 166MB adoptopenjdk/openjdk11 alpine-jre aa00f19e5b22 3 weeks ago 149MB
1.2.2. Now, our spring-boot-image is ready. we need to create and run a container using it. run command
$ docker run --name <container-name> -p <host-port:container-port> -t <image-name:tag>
$ docker run --name spring-boot-container -p 8080:8181 -t spring-boot-image:1.0 . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.2.RELEASE) 2020-05-27 11:22:27.385 INFO 1 --- [ main] c.j.d.SpringBootHelloWorldApplication : Starting SpringBootHelloWorldApplication v0.0.1-SNAPSHOT on 5a5873dc878a with PID 1 (/myapp/my-app.jar started by root in /myapp) 2020-05-27 11:22:27.400 INFO 1 --- [ main] c.j.d.SpringBootHelloWorldApplication : No active profile set, falling back to default profiles: default 2020-05-27 11:22:30.925 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8181 (http) 2020-05-27 11:22:30.984 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2020-05-27 11:22:30.988 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29] 2020-05-27 11:22:31.343 INFO 1 --- [ main] o.a.c.c.C.[.[localhost].[/helloworld] : Initializing Spring embedded WebApplicationContext 2020-05-27 11:22:31.364 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3590 ms 2020-05-27 11:22:33.217 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2020-05-27 11:22:34.228 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8181 (http) with context path '/helloworld' 2020-05-27 11:22:34.273 INFO 1 --- [ main] c.j.d.SpringBootHelloWorldApplication : Started SpringBootHelloWorldApplication in 8.556 seconds (JVM running for 9.996)
Make sure you already installed Docker Compose in your environment.
1.3.1. Docker Compose is a tool that provides a way to orchestrate multiple containers that work together. For example you have multiple applications, rest-api, web-application and database … etc. We nee to run multiple docker containers such scenarios. we can use Docker Compose for defining and running multi-container Docker applications.
We need create a docker-compose.yml
file in the root directory of application like following. The configuration properties are self explanatory.
version: '3' services: spring-boot-docker-app: image: spring-boot-docker-image build: context: ./ dockerfile: Dockerfile ports: - 8080:8181 volumes: - /storage/my-app
1.3.2. Once you created docker-compose.yml
file run command $ docker-compose up
$ docker-compose up Creating network "spring-boot-docker-example_default" with the default driver Building spring-boot-docker-app Step 1/5 : FROM adoptopenjdk/openjdk11:alpine-jre alpine-jre: Pulling from adoptopenjdk/openjdk11 cbdbe7a5bc2a: Pull complete 525f2e30780d: Pull complete 29bfc0a3c5fd: Pull complete Digest: sha256:f92b946306c1f17be5578a84f61482766c4a47d6c75a2b49a49b7ef321cc750f Status: Downloaded newer image for adoptopenjdk/openjdk11:alpine-jre ---> aa00f19e5b22 Step 2/5 : LABEL maintainer="[email protected]" ---> Running in 710b85a52743 Removing intermediate container 710b85a52743 ---> 246aa42d0219 Step 3/5 : WORKDIR /myapp ---> Running in 7e0a3ed07870 Removing intermediate container 7e0a3ed07870 ---> d732b42efffa Step 4/5 : COPY target/spring-boot-docker-example-0.0.1-SNAPSHOT.jar /myapp/my-app.jar ---> ceaaed6ffa5a Step 5/5 : ENTRYPOINT ["java","-jar","my-app.jar"] ---> Running in 4fa0a0954493 Removing intermediate container 4fa0a0954493 ---> 66fc515e4bd9 Successfully built 66fc515e4bd9 Successfully tagged spring-boot-docker-image:latest WARNING: Image for service spring-boot-docker-app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating spring-boot-docker-example_spring-boot-docker-app_1 ... done Attaching to spring-boot-docker-example_spring-boot-docker-app_1 spring-boot-docker-app_1 | spring-boot-docker-app_1 | . ____ _ __ _ _ spring-boot-docker-app_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ spring-boot-docker-app_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ spring-boot-docker-app_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) ) spring-boot-docker-app_1 | ' |____| .__|_| |_|_| |_\__, | / / / / spring-boot-docker-app_1 | =========|_|==============|___/=/_/_/_/ spring-boot-docker-app_1 | :: Spring Boot :: (v2.2.2.RELEASE) spring-boot-docker-app_1 | spring-boot-docker-app_1 | 2020-05-27 11:53:52.186 INFO 1 --- [ main] c.j.d.SpringBootHelloWorldApplication : Starting SpringBootHelloWorldApplication v0.0.1-SNAPSHOT on c8c8addb7d62 with PID 1 (/myapp/my-app.jar started by root in /myapp) spring-boot-docker-app_1 | 2020-05-27 11:53:52.204 INFO 1 --- [ main] c.j.d.SpringBootHelloWorldApplication : No active profile set, falling back to default profiles: default spring-boot-docker-app_1 | 2020-05-27 11:53:55.806 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8181 (http) spring-boot-docker-app_1 | 2020-05-27 11:53:55.848 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] spring-boot-docker-app_1 | 2020-05-27 11:53:55.878 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29] spring-boot-docker-app_1 | 2020-05-27 11:53:56.211 INFO 1 --- [ main] o.a.c.c.C.[.[localhost].[/helloworld] : Initializing Spring embedded WebApplicationContext spring-boot-docker-app_1 | 2020-05-27 11:53:56.211 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3594 ms spring-boot-docker-app_1 | 2020-05-27 11:53:58.226 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' spring-boot-docker-app_1 | 2020-05-27 11:53:59.140 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8181 (http) with context path '/helloworld' spring-boot-docker-app_1 | 2020-05-27 11:53:59.151 INFO 1 --- [ main] c.j.d.SpringBootHelloWorldApplication : Started SpringBootHelloWorldApplication in 8.588 seconds (JVM running for 10.15)
That’s all, your application will be started.
1.3.3. Some useful docker commands :
docker-compose up --build -d
– If you have updated Dockerfile or .yml
, to rebuild and run your containers. Use option-d
to run docker container in detached mode.docker-compose stop
– To stop all running containers.docker-compose start
– To start all of your inactive containers.docker ps -a
ordocker-compose ps -a
– To list all of docker containers.docker images
ordocker-compose images
– To List all of docker images.docker history <image-name>
– To see layered view of docker image how it build.docker logs <image-name>
ordocker-compose logs <image-name>
to see logs of your application
2. Test the application
Enter url in browser http://localhost:8181/helloworld/hello
. On successful run of Spring Boot Application you will get following screen.
3. Conclusion
In this tutorial we walked through a simple Spring Boot example and we have covered a simple quick guide to deploy Spring Boot Application in Docker using docker and docker-compose commands, also you can consider this guide to deploy Spring Boot microservice in Docker.
You can checkout source code from our github repository.
You also might interested in following Articles :