Spring Boot is great for running inside a Docker container. Spring Boot applications ‘just run’. A Spring Boot application has an embedded servlet engine making it independent of application servers. There is a Spring Boot Maven plugin available to easily create a JAR file which contains all required dependencies. This JAR file can be run with a single command-line like ‘java -jar SpringBootApp.jar’. For running it in a Docker container, you only require a base OS and a JDK. In this blog post I’ll give examples on how to get started with different OSs and different JDKs in Docker. I’ll finish with an example on how to build a Docker image with a Spring Boot application in it.
Getting started with Docker
Installing Docker
Of course you need a Docker installation. I’ll not get into details here but;
Oracle Linux 7
yum-config-manager --enable ol7_addons yum-config-manager --enable ol7_optional_latest yum install docker-engine systemctl start docker systemctl enable docker
Ubuntu
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" apt-get update apt-get install docker-ce
You can add a user to the docker group or give it sudo docker rights. They do allow the user to become root on the host-OS though.
Running a Docker container
See below for commands you can execute to start containers in the foreground or background and access them. For ‘mycontainer’ in the below examples, you can fill in a name you like. The name of the image can be found in the description further below. This can be for example for an Oracle Linux 7 image container-registry.oracle.com/os/oraclelinux:7 when using the Oracle Container Registry or store/oracle/serverjre:8 for for example a JRE image from the Docker Store.
If you are using the Oracle Container Registry (for example to obtain Oracle JDK or Oracle Linux docker images) you first need to
- go to container-registry.oracle.com and enable your OTN account to be used
- go to the product you want to use and accept the license agreement
- do docker login -u username -p password container-registry.oracle.com
If you are using the Docker Store, you first need to
- go to store.docker.com and create an account
- find the image you want to use. Click Get Content and accept the license agreement
- do docker login -u username -p password
To start a container in the foreground
docker run --name mycontainer -it imagename /bin/sh
To start a container in the background
docker run --name mycontainer -d imagename tail -f /dev/null
To ‘enter’ a running container:
docker exec -it mycontainer /bin/sh
/bin/sh exists in Alpine Linux, Oracle Linux and Ubuntu. For Oracle Linux and Ubuntu you can also use /bin/bash. ‘tail -f /dev/null’ is used to start a ‘bare OS’ container with no other running processes to keep it running. A suggestion from here.
Cleaning up
Good to know is how to clean up your images/containers after having played around with them. See here.
#!/bin/bash # Delete all containers docker rm $(docker ps -a -q) # Delete all images docker rmi $(docker images -q)
Options for JDK
Of course there are more options for running JDKs in Docker containers. These are just some of the more commonly used.
Oracle JDK on Oracle Linux
When you’re running in the Oracle Cloud, you have probably noticed the OS running beneath it is often Oracle Linux (and currently also often version 7.x). When for example running Application Container Cloud Service, it uses the Oracle JDK. If you want to run in a similar environment locally, you can use Docker images. Good to know is that the Oracle Server JRE contains more than a regular JRE but less than a complete JDK. Oracle recommends using the Server JRE whenever possible instead of the JDK since the Server JRE has a smaller attack surface. Read more here. For questions about support and roadmap, read the following blog.
store.docker.com
The steps to obtain Docker images for Oracle JDK / Oracle Linux from store.docker.com are as follows:
Create an account on store.docker.com. Go to https://store.docker.com/images/oracle-serverjre-8. Click Get Content. Accept the agreement and you’re ready to login, pull and run.
#use the store.docker.com username and password docker login -u yourusername -p yourpassword docker pull store/oracle/serverjre:8
To start in the foreground:
docker run --name jre8 -it store/oracle/serverjre:8 /bin/bash
container-registry.oracle.com
You can use the image from the container registry. First, same as for just running the OS, enable your OTN account and login.
#use your OTN username and password docker login -u yourusername -p yourpassword container-registry.oracle.com docker pull container-registry.oracle.com/java/serverjre:8 #To start in the foreground: docker run --name jre8 -it container-registry.oracle.com/java/serverjre:8 /bin/bash
OpenJDK on Alpine Linux
When running Docker containers, you want them to as small as possible to allow quick starting, stopping, downloading, scaling, etc. Alpine Linux is a suitable Linux distribution for small containers and is being used quite often. There can be some thread related challenges with Alpine Linux though. See for example here and here.
Running OpenJDK in Alpine Linux in a Docker container is more easy than you might think. You don’t require any specific accounts for this and also no login.
When you pull openjdk:8, you will get a Debian 9 image. In order to run on Alpine Linux, you can do
docker pull openjdk:8-jdk-alpine
Next you can do
docker run --name openjdk8 -it openjdk:8-jdk-alpine /bin/sh
Zulu on Ubuntu Linux
You can also consider OpenJDK based JDK’s like Azul’s Zulu. This works mostly the same only the image name is something like ‘azul/zulu-openjdk:8’. The Zulu images are Ubuntu based.
Do it yourself
Of course you can create your own image with a JDK. See for example here. This requires you download the JDK code and build the image yourself. This is quite easy though.
Spring Boot in a Docker container
Creating a container with a Spring Boot application based on an image which already has a JDK in it, is easy. This is described here. You can create a simple Dockerfile like:
FROM openjdk:8-jdk-alpine VOLUME /tmp ARG JAR_FILE ADD ${JAR_FILE} app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
The FROM image can also be an Oracle JDK or Zulu JDK image as mentioned above.
And add a dependency to com.spotify.dockerfile-maven-plugin and some configuration to your pom.xml file to automate building the Dockerfile once you have the Spring Boot JAR file. See for a complete example pom.xml and Dockerfile also here. The relevant part of the pom.xml file is below.
<build> <finalName>accs-cache-sample</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.3.6</version> <configuration> <repository>${docker.image.prefix}/${project.artifactId}</repository> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build>
To actually build the Docker image, which allows using it locally, you can do:
mvn install dockerfile:build
If you want to distribute it (allow others to easily pull and run it), you can push it with
mvn install dockerfile:push
This will of course only work if you’re logged in as maartensmeets and only for Docker hub (for this example). The below screenshot is after having pushed the image to hub.docker.com. You can find it there since it is public.
You can then do something like
docker run -t maartensmeets/accs-cache-sample:latest