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

Popular posts from this blog

How to deploy a VueJS App using Nginx on Ubuntu

There are thousands of blogs and websites out there explaining how to do a hello world and how to start with VueJS, but in this little post, I’m just going to be explaining how to do deploy a VueJs app after you have run the command through the CLI npm run build . So when you run the command npm run build a dist folder is created and that folder’s got the essential .js files to run our app, when we want to run our app on an Nginx server by default the vue-router is not going to work well so that Nginx does not come ready to work by default with a VueJs app This is basically for a Linux Ubuntu distribution if you’ve got any other Linux distribution just pay attention where is going to be set the www/html folder and the Nginx settings so that this is useful for any Linux distribution  Install and configure nginx sudo apt install nginx Double check to make sure the nginx service is running with command service nginx status, then open your browser and enter url

How to do pagination SpringBoot with Jbctemplate, MySQL

We are going to be working on a topic which is a basic need when doing any app, and it is Pagination. let's get started creating a product table at https://mockaroo.com/ create table products ( id INT, name VARCHAR(50), code VARCHAR(50) ); insert into products (id, name, code) values (1, 'Hettinger-Goyette', '42549-680'); insert into products (id, name, code) values (2, 'Konopelski-Klein', '49527-724'); insert into products (id, name, code) values (3, 'Smitham, Kuhlman and Balistreri', '53238-003'); insert into products (id, name, code) values (4, 'Hettinger, Weissnat and Goodwin', '0143-9916'); insert into products (id, name, code) values (5, 'Rowe Inc', '42291-898'); insert into products (id, name, code) values (6, 'Ernser-Hauck', '10544-617'); insert into products (id, name, code) values (7, 'Maggio and Sons', '68788-9087'); insert into products (id, name,

How to secure SpringBoot with SSL and Tomcat or Undertow

when we are going to take our applications to production mode, we must have an SSL certificate for the FrontEnd and   BackEnd too, in this case, our backend is a  SpringBoot which is using a tomcat embedded server. Terminology TLS vs SSL TLS is the successor to SSL. It is a protocol that ensures privacy between communicating applications. Unless otherwise stated, in this document consider TLS and SSL as interchangable. Certificate (cert) The public half of a public/private key pair with some additional metadata about who issued it etc. It may be freely given to anyone. Private Key A private key can verify that its corresponding certificate/public key was used to encrypt data. It is never given out publicly. Certificate Authority (CA) A company that issues digital certificates. For SSL/TLS certificates, there are a small number of providers (e.g. Symantec/Versign/Thawte, Comodo, GoDaddy, LetsEncrypt) whose certificates are included by most browsers and Operating System