How to dockerize Spring Boot Application? - spring-boot

I want to dockerize my Spring Boot Project.
In eclipse, I have already created a Dockerfile (after creating the application jar file) like this:
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/device-fixer-1.2.1.jar.jar
COPY ${JAR_FILE} device-fixer-1.2.1.jar.jar
ENTRYPOINT ["java","-jar","/device-fixer-1.2.1.jar.jar"]
Now what should I do to be able to dockerize?

Assuming your app listens on port 80
docker build -t <your-app-name> .
docker run -d -p 80:80 <your-app-name>

Create files that are named as Dockerfile and docker-compose.yml under project root directory.
Dockerfile
FROM openjdk:11-slim
COPY /target/app.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
docker-compose.yml
version: '1'
services:
app:
build:
context: "./"
dockerfile: Dockerfile
container_name: 'app-name'
hostname: app-name
ports:
- '8080:8080'
Run docker-compose up -d command under root directory to create an image and run your application on localhost:8080

Related

Mounting Volume in DockerFile on Windows

I am working on a Springboot project with docker. I tried to mount volume so I could have access to generated files from the Springboot application in my local directory. The data is generated in the docker container but I can not find it the local directory.
I have read many topics but none seems to be helpful.
Please, I am still new to docker and would appreciate suggestions to assist.
I have tried to mount the volume directly in the dockerfile as there is a docker compose file to run the service alongside others. Below is what I have in my Dockerfile and docker-compose
Dockerfile
FROM iron/java:1.8
EXPOSE 8080
ENV USER_NAME myprofile
ENV APP_HOME /home/$USER_NAME/app
#Test Script>>>>>>>>>>>>>>>>>>>>>>
#Modifiable
ENV SQL_SCRIPT $APP_HOME/SCRIPTS_TO_RUN
ENV SQL_OUTPUT_FILE $SQL_SCRIPT/data
ENV NO_OF_USERS 3
ENV RANGE_OF_SKILLS "1-4"
ENV HOST_PATH C:"/Users/user1/IdeaProjects/path/logs"
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RUN adduser -S $USER_NAME
RUN mkdir $APP_HOME
RUN mkdir $SQL_SCRIPT
RUN chown $USER_NAME $SQL_SCRIPT
VOLUME $HOST_PATH: $SQL_SCRIPT
ADD myprofile-*.jar $APP_HOME/myprofile.jar
RUN chown $USER_NAME $APP_HOME/myprofile.jar
USER $USER_NAME
WORKDIR $APP_HOME
RUN sh -c 'touch myprofile.jar'
ENTRYPOINT ["sh", "-c","java -Djava.security.egd=file:/dev/./urandom -jar myprofile.jar -o $SQL_OUTPUT_FILE -n $NO_OF_USERS -r $RANGE_OF_SKILLS"]
Docker-compose
myprofile-backend:
extra_hosts:
- remotehost
container_name: samplecontainer-name
image: sampleimagename
links:
- rabbitmq
- db:redis
expose:
- "8080"
ports:
- "8082:8080"
volumes:
- ./logs/:/tmp/logs
- ./logs/:/app
The problem here is that you are mounting the same folder ./logs twice. Docker-compose volume mount syntax is - <your-host-path>:<your-container-path>. Also, its better to use relative paths when you are building the application. So change docker-compose file to (assuming you want to see the files in ./target relative to the Dockerfile:
myprofile-backend:
extra_hosts:
- remotehost
container_name: samplecontainer-name
image: sampleimagename
links:
- rabbitmq
- db:redis
expose:
- "8080"
ports:
- "8082:8080"
volumes:
- ./logs/:/tmp/logs
- ./target/:/app

Docker compose on Windows: no such file or directory

I'm trying to run two services with docker compose: a MySQL server and a SAMP server.
My docker-compose.yml looks like this:
version: '3.9'
services:
mysql:
image: mysql:8.0.28
volumes:
- ./mysql:/var/nw-mysql-data
env_file:
- .env
samp:
build:
context: .
dockerfile: Dockerfile
command: ./samp03svr
ports:
- "7777:7777"
env_file:
- .env
depends_on:
- mysql
And my Dockerfile:
FROM ubuntu:20.04
RUN mkdir /app
COPY . /app/
WORKDIR /app
COPY ./samp03svr /app/
The problem is in the command of the samp service. It throws the following exception when I run docker-compose up:
standard_init_linux.go:228: exec user process caused: no such file or directory
The weird thing, is that if I change the samp's command for an ls like this:
command: ls
I can see the binary file that I'm trying to execute listed, and docker is saying that there's no such file...
Help?
EDIT: Here is a screenshot of the ls command return, ran from the command instruction of the samp service:

docker-compose build context dockerfile envar image

I would like use docker-compose to build/run dockerfiles that have envars in their FROM keyword. The problem that I am getting now is that I seem to be unable to pass envars from my environment through docker-compose into the dockerfile.
docker-compose.yml
version: "3.2"
services:
api:
build: 'api/'
restart: on-failure
depends_on:
- mysql
networks:
- frontend
- backend
volumes:
- ./api/php/:/var/www/html/
Dockerfile in 'api/'
FROM ${DOCKER_IMAGE_API}
RUN apk update
RUN apk upgrade
RUN docker-php-ext-install mysqli
Why?
I want to do this so that I can run docker-compose from a bash script that detects the host architecture and changes the base image of the underlying dockerfiles in the host application.
FROM instructions support variables that are declared by any ARG instructions that occur before the first FROM. So what you can do is this:
ARG IMAGE
FROM $IMAGE
when you run the build command, you then pass the --build-arg as follows:
docker build -t test --build-arg IMAGE=alpine .
you can also choose to have a default value for the IMAGE variable, to be used if the --build-arg flag isn't used.
Alternatively, in case you were to use docker compose build and not docker build (and I think this is your case), you can specify the variable in the docker-compose build --build-arg:
version: "3.9"
services:
api:
build: .
and then
docker compose build --build-arg IMAGE=alpine

Docker Containers for Maven Multi-module Spring Boot project with Angular Frontend module

I have Maven Multi-Modules Project (Angular Frontend Module + SpringBoot Backend Module) residing under same Parent Maven Project. I want to run the application in Docker Multi-containers (docker container for Frontend + docker container for Backend + docker container for database). How can I use Docker Compose to run docker multi-containers?
I created "docker-compose.yml" in the parent project, and in each module I add "Dockerfile".
Here is structure of my project
docker-compose.yml File
version: '3'
services:
docker-container-application-mariadb:
image: mariadb:latest
environment:
- MYSQL_ROOT_PASSWORD=*****
- MYSQL_DATABASE=*******
- MYSQL_USER=*******
- MYSQL_PASSWORD=*******
volumes:
- /data/application-mariadb
docker-container-application-backend:
image: docker-image-application-backend
build:
context: ./application-backend
dockerfile: Dockerfile
depends_on:
- docker-container-application-mariadb
ports:
- 8087:8080
volumes:
- /data/application-backend
Backend Dockerfile:
FROM openjdk:8
EXPOSE 8080
ADD target/application_backend.jar application_backend.jar
# Run the jar file
ENTRYPOINT ["java", "-jar", "application_backend.jar"]
ENTRYPOINT ["java", "-jar", "application_backend.jar"]
When I run:
docker-compose up
here is the error I am getting:
Step 4/6 : ADD $PWD/application-backend/target/application_backend.jar application_backend.jar
ERROR: Service 'docker-container-application-backend' failed to build: ADD failed: stat /var/lib/docker/tmp/docker-builder971325573/esysync-backend/target/application_backend.jar: no such file or directory
Error after code update:
Error after Code update suggested by #Milah:
This should work. I don't have your environment to test so if you get errors let me know and I'll fix them.
Place this Docker file at the root of the project (same level as docker-compose).
Dockerfile:
FROM maven:3.6.0-jdk-8-alpine as build
WORKDIR /app
COPY . .
WORKDIR /app/application-backend
RUN mvn clean package -DskipTests=true
FROM openjdk:8
WORKDIR /app
COPY --from=build /app/application-backend/target/*.jar ./
EXPOSE 8080
# Run the jar file
ENTRYPOINT ["java", "-jar", "/app/application_backend.jar"]
Next to the Dockerfile there should be also an ignore file.
.dockerignore
application-frontend/
You should change the docker-compose file as follows:
...
docker-container-application-backend:
image: docker-image-application-backend
build:
context: ./
dockerfile: Dockerfile
...
The declaration dockerfile: Dockerfile is redundant, can be rmoved.

Pass multiple system parameters thorugh docker-compose-->dockerfile--> springboot application housed in docker container

Below is the content of my docker-compose.yml file:
eureka-server:
image: controlsplm/eureka-server
environment:
HOST_IP: X.X.X.X
ACTIVE_PROFILE=docker-development-cloud
ports:
- "8761:8761"
restart: always
And below is the content of my docker file:
FROM java:8
VOLUME /tmp
ADD eureka-server-0.1.0-SNAPSHOT.jar app.jar
EXPOSE 8761
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Denvironment=$HOST_IP","-Dspring.profiles.active=$ACTIVE_PROFILE","-jar","/app.jar"]
But when i run the docker container using compose, HOST_IP is picked up but not ACTIVE_PROFILE. AM i missing anything here? Kindly help...
Indeed, if you have Spring properties
my.spring.property.one=green
my.spring.property.two=blue
You can include them as follows in the docker-compose.yml:
environment:
- my_spring_property_one=green
- my_spring_property_two=blue
worked for my with
Spring Boot v1.5.10.RELEASE
Spring v4.3.14.RELEASE
docker version '3.6'
I see two problems:
the format of the ACTIVE_PROFILE is wrong, it would be ACTIVE_PROFILE: docker-development-cloud as mentioned by #andreas-jägle in the comments
The entrypoint uses json array notation, which means the command is exec'ed directly without a shell. The shell (usually bash) is what replaced the variables with their values, so you need to run in a shell to use those variables. You can either use the string form of ENTRYPOINT, or use:
ENTRYPOINT ["bash", "-c" ,"java - Dspring.profiles.active=$ACTIVE_PROFILE ..."]
I resolved the issue by adding below lines to my docker-compose.yml file:
eureka-server:
image: controlsplm/eureka-server:latest
environment:
HOST_IP: X.X.X.X
SPRING_PROFILES_ACTIVE: docker-development-cloud
ports:
- "8761:8761"
restart: always
and below lines in dockerfile:
FROM java:8
VOLUME /tmp
ADD eureka-server-0.1.0-SNAPSHOT.jar app.jar
EXPOSE 8761
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Denvironment=$HOST_IP","-jar","/app.jar"]

Resources