Skip to main content

Deploying a SpringBoot App with an application.properties in Docker using a Dockerfile and limiting its resources

Let's take a quick review about Dockerizing a SpringBoot app,  it is a process quite easy, let's assume you've got Docker installed and MySql server on your host OS server, or even better you've got an RDS!, in my case, my host OS is a Centos 7 with firewall-cmd and MySQL server on it

I have done a mini SpringBoot application with just 3 endpoints,

1: create items,
2: list items,
3: say hello

you can get it from here at https://github.com/juandavidmarin368/SpringBoot-Docker
and there is a .sql to restore for the example, or just run anything else different than the example.

so making this short, I have got a SpringBoot app with its application.properties like this

server.port:7075

spring.datasource.driver = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/docker?serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = n5QHFj3VFFMKVJDV
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

replace those credentials by yours, and the idea is to be able to copy that application.properties as it is  to a Docker image to run it after as a container

after you've got the jar done, let's create a folder mkdir springboot-docker and inside that folder cd springboot-docker do the next steps:


copy the PersisterDataDocker-0.0.1-SNAPSHOT.jar and the application.properties into that folder

let's create a Dockerfile which is the one is going to have the instructions to build the image where we are going to be running our application

vim Dockerfile
# with this, we are pulling a ready image which has got OpenJDK version 8 ready to use
FROM openjdk:8

#with this, we are copying what is inside the folder springboot-docker to the /opt directory on the docker image
COPY PersisterDataDocker-0.0.1-SNAPSHOT.jar /opt
COPY application.properties /opt

# we are setting up the working directory
WORKDIR /opt

#with this, we are opening the port 7075, replace it by yours
expose 7075

#and with this, we are giving the command and the needed parameters to run the jar
CMD ["java", "-jar", "PersisterDataDocker-0.0.1-SNAPSHOT.jar"]

it is as easy as that, inside the folder springboot-docker  there should be the next files


now let's create the image inside that directory with

docker build -t your-image-name .

after I run the command I got something like:


if you run docker image ls 
it will list all the created images



now it is time to run the created image with docker run -p 7075:7075 your-image-name

the left port belongs to the host and the right port belongs to the container, so in that case, we are saying that our host OS is going to have opened the port 7075 redirected to the port 7075 to the docker container tagged by your name

NOTE: until that point, you could run your first SpringBoot docker container, but it runs it as a root user on the container, to enforce the security is a good practice to create a new user, copy the jar file and the application.properties to the new user folder and runs the jar with the new user

inside the same folder:

vim Dockerfile


# with this, we are pulling a ready image which has got OpenJDK version 8 ready to use
FROM openjdk:8

#if you want to install something else before executing your jar, in this case I wanted to add htop, so I must do: #RUN apt-get install -y htop
#we are creating the user and with the flag -m we are creating its own folder under that username
RUN useradd -m springuser

#with this, we are copying what is inside the folder springboot-docker to the /opt directory on the docker image
COPY PersisterDataDocker-0.0.1-SNAPSHOT.jar /home/springuser
COPY application.properties /home/springuser

#we are changing the permissions to the .jar file and the application.properties to the new user
RUN chown -R springuser:springuser /home/springuser

#now we are switching to the new user
USER springuser

# we are setting up the working directory
WORKDIR /home/springuser

#with this, we are opening the port 7075, replace it by yours
expose 7075
CMD "echo $(ls -l)"
#and with this, we are giving the command and the needed parameters to run the jar
CMD ["java", "-jar", "PersisterDataDocker-0.0.1-SNAPSHOT.jar"]


after that let's build the image

docker build -t your-image-name . 
and now let's run the image

docker run -p --name spring-persister 7075:7075 your-image-name

now if you want to run your container in the background the run it in a detached mode

I gave it the name as spring-persister-one


docker run --name containerspring -d -p 7075:7075 spring-persister-one

now if you run docker container ls




Get a Shell to the Container

The docker exec command allows you to run commands inside a running container.

To see how the exec command works and how it can be used to enter the container shell

docker exec -it --user springuser containerspring bash




as you could see it logged in with the user springuser on the container containerspring , and there are only those 2 files in there, if you run the top command you can see just  3 processes which are running on the container.

Support with SSL

Now if you've got a .p12 for giving SSL to your SpringBoot app, you can copy that file with in the same directory where is the .jar and the application.properties



server.port:7075

server.ssl.enabled=true
security.require-ssl=true
server.ssl.key-store=yourkey.p12
server.ssl.key-store-password=your_password
server.ssl.key-alias=your_domain.com
server.ssl.key-password=your_password

if you want to know how to secure an SpringBoot application running with SSL click on https://springboot-vuejs-reactjs.blogspot.com/2019/07/how-to-secure-springboot-with-ssl-and.html

These are some useful commands in docker:

docker image ls

docker container ls

FORCE REMOVE IMAGES

docker rmi $(docker images -aq) -f

LIMITING THE CONTAINER RESOURCES

We are going to limit the container by CPU and by ram memory too, so that sometimes there are some processes which starts taking the whole ram memory and processors and we would not like our host OS gets stuck because of this

docker run --cpuset-cpus=0 --name spring-container -p 7075:7075 --memory="400m" spring-persister-one

we are giving to the container the name as spring-container and it is using the image spring-persister-one
we are giving it --cpuset-cpus=0 it means it is taking one CPU and using  300MB, now that the container is running let's open 2 more terminals, in one terminal let's run htop and in the another terminal let's go to the shell container with docker exec -it --user root spring-container bash and once it is open let's run
stress --cpu 8 --io 2 --vm 1 --vm-bytes 300mb and let's get back to the terminal where it is the htop
we can see now how just one processor is being used how the ram memory is being used too according to its limits







Comments