How to add storage using Volume in a Docker container - spring-boot

I have a spring boot application and I want to start it on a docker container. However, I want to persist data, so I do not have to rebuild image to see the changes I made to RestAPI.
My docker file
FROM maven:3.6.1-jdk-8-alpine
RUN mkdir -p /usr/src
WORKDIR /usr/src
COPY . /usr/src/
RUN mvn clean install
WORKDIR /usr/src/target
ENTRYPOINT ["java", "-jar", "SecurityAndDocker-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080:8080
Image build is ok
Running docker run -p 8080:8080 image-name works perfectly fine
How would I attach a volume to this application?
Thank you!

you can mount the volume, while running the container.
docker run -d -p 8080:8080 --name <container-name> --mount source=myvol2,target=/app <image-name>
you can also read the documentation: https://docs.docker.com/storage/volumes/
Feel free to ask in case you found any issue.

If I understand you want the target directory to be extracted out in a volume from your custom image's container.
use VOLUME keyword to specify the directory.
Your dockerfile should go like this.
FROM maven:3.6.1-jdk-8-alpine
RUN mkdir -p /usr/src
WORKDIR /usr/src
COPY . /usr/src/
RUN mvn clean install
VOLUME /usr/src/target
WORKDIR/usr/src/target
ENTRYPOINT ["java", "-jar", "SecurityAndDocker-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080:8080
The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If you want to save the working directory just add VOLUME in your dockerfile.

Related

Create docker image with named/host volume for spring boot application

I have spring boot application which I am trying to dockerize for the first time. I am using docker version 20.10.1 and my host pc is ubuntu 20.04
for this spring boot application, I have a data directory , which has data created when the application is running. I want to access this data from the host operating system. That is why I am using volume.
When I try to mount my container to named volume or to a host volume, but it always create anonymous volume regardless of the command I type.
Here is my docker file.
FROM openjdk:15
COPY target/lib/* /usr/src/app/lib/
COPY target/core-api-7.3.6.jar /usr/src/app/lib/core-api-7.3.6.jar
COPY config/application.properties /usr/src/app/config/application.properties
COPY data/poscms/config/* /usr/src/app/data/poscms/config/
WORKDIR /usr/src/app
ENTRYPOINT ["java", "-jar", "lib/core-api-7.3.6.jar"]
VOLUME /usr/src/app/data
/usr/src/app/data this is the directory where core-app.jar application will create its runtime data, I need to access these data from my host pc
Following is the command for building the image
docker build -t core-app:5.0 .
then I create image using following command
docker run -it -d -p 7071:7071 core-app:5.0 -v /home/bob/data/:/usr/src/app/data
when I check the volumes by running following command
docker volume ls
I can see anonymous volume being created by this container
and my host path which is /home/kapila/data/ is empty and container data is not written to host path.
I experience the same behaviour with named volume as well.
I created a named volume using following command
docker volume create tmp
docker run -it -d -p 7071:7071 core-app:5.0 -v tmp:/usr/src/app/data
and still docker create anonymous volume and data is not written to tmp volume
my host PC is ubuntu pc. Could someone point out what I am doing wrong here
I do something like this:
In your project root , have these files pertaining to docker as required:
1. DockerFile 2.docker-compose.yml 3. docker-env-preview.env
DockerFile content
FROM openjdk:8-jdk-alpine
ARG jarfilepath
RUN mkdir /src
WORKDIR /src
VOLUME /src/tomcat
ADD $jarfilepath yourprojectname.jar
docker-compose.yml content
version: '3'
services:
project-name:
container_name: project-name-service
build:
context: .
args:
jarfilepath: ./target/project-0.0.1.jar
env_file:
- docker-env-preview.env
ports:
- "8831:8831"
- '5005:5005'
networks:
- projectname_subnet
command: java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 projectname.jar --spring.profiles.active=preview
networks:
project-name_subnet:
external: true
docker-env-preview.env
This file will contain your environment variables values. The applicaiton.properties can read this file to fetch the values, like buildserver.ip=${BUILD_SERVER_DOMAIN}. Basically you define what you want need . Like the example below.
GARBABE_SERVER_DOMAIN=h-db-preview
GARBABE_SERVER_PORT=5422
GARBABE_DB=projectdb
GARBABE_USER=user
GARBABE_PASSWORD=pwd
JPA_DDL_AUTO=validate
JPA_DIALECT=org.hibernate.dialect.PostgreSQLDialect
JPA_SHOW_SQL=false
JPA_SE_SQL_COMMENTS=true
JPA_FORMAT_SQL=false
JPA_NON_CONTEXTUAL_CREATION=true
APP_NAME=project-name-service
BUILD_SERVER_METHOD=http
BUILD_SERVER_DOMAIN=7.8.9.4
Commands to execute :
mvn clean package (if you use maven )
docker-compose up -d --build ( execute docker ps -> check the details on the running container),
To view the logs : sudo docker logs <project-name-service> -f
To get into the container console, docker exec -it <project-name-service> bash
I was able to fix the issue, and only change I did, to make it work, is that, to change the base image from
FROM openjdk:15
to
FROM adoptopenjdk/openjdk15:ubi
and now named and host volume mounts are working as expected. I am not sure what is wrong with official openjdk:15 image.

unable to run docker container as getting this error:Unable to access jarfile app.jar

I have created the image using below Docker file.Its working fine in local when I run it in the container using this image[docker run -p 80:8080 username/spring-boot-docker-aws-demo:tag
FROM openjdk:8-jdk-alpine
COPY target/spring-boot-docker-aws-demo.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
I have pushed this image to Docker hub to run it in EC2 instance.when I run it its saying "Error: Unable to access jarfile app.jar"
https://hub.docker.com/layers/chaituu/spring-boot-docker-aws-demo/docker-aws-demo-tag/images/sha256-110363a016eb2250264d96c8890dede518d8e519fdc9a27174334fe1096a540e?context=repo
what could be the issue?
I had a similar issue today (although in my case it wouldn't even run locally). Here's what your Dockerfile would look like with my fix:
FROM openjdk:8-jdk-alpine
COPY target/spring-boot-docker-aws-demo.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["sh"]
CMD ["-c", "java -jar /app/app.jar"]

Using a Bind Mount in Docker to have a folder on Windows Host Machine available to Container

I'm trying to get a setup where I can deploy a Docker Container with a java app installed on it where the app can write to a folder in the container and for those files to appear on the host machine.
I believe that a --mount with type=bind is the correct solution for this. However, I cannot seem to get the mount to show up when I run docker inspect MyContainer.
My full setup is as follows;
Docker File:
FROM openjdk:14.0.2-jdk-nanoserver
WORKDIR /monitor
COPY target/monitor.jar ./
ENTRYPOINT ["java", "-jar", "monitor.jar"] --restart unless-stopped
Build Command:
docker build -t monitor .
and my Run command:
docker run --restart unless-stopped --name MonitorContainer monitor --mount type=bind,source=C:/test,target=/monitor
With the above, I'm attempting to have the folder C:/test available for read and write inside the container at the path /monitor. However, when I run docker inspect StreamMonitorContainer I see that the mount section is empty so it appears the mount is not created.
I receive no errors, so it's all rather confusing.
I would appreciate any help, I'm completely novice at this so please be nice :)
p.s. This question differs from Docker bind mount usage because it's dealing with Volumes, not Bind Mounts (despite the title.)

docker image syntax error

When I run docker command on my image, it errors out. Any ideas on what should I include in my Dockerfile for CMD? Currently, I have java -jar xxxx.jar in it.
here is my Dockerfile:
FROM openjdk:8-jre-alpine
COPY ./target/hola-docker-1.0.0-SNAPSHOT.jar D:/docker-built-test
WORKDIR -p D:/docker-built-test
EXPOSE 8080
CMD ["java", "-jar", "hola-docker-1.0.0-SNAPSHOT.jar"]
My command docker build -t hello-manual-build1 .
click here Created Docker Image
When am trying to create a container using the new image then facing an error don't know how to resolve please help me to move forward
Thanks

Docker containers on travis-ci

I have a Dockerfile that I am attempting to test using RSpec, serverspec and docker-api. Locally (using boot2docker as I am on OS X) this works great and all my test pass, but on travis-ci none of the tests pass. My .travis.yml file is as such:
language: ruby
rvm:
- "2.2.0"
sudo: required
cache: bundler
services:
- docker
before_install:
- docker build -t tomasbasham/nginx .
- docker run -d -p 80:80 -p 443:443 --name nginx -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf tomasbasham/nginx
script: bundle exec rspec
Am I doing something noticeably wrong here? The repository I have created and is run on travis-ci is on GitHub. There may be something else amiss that I am unaware of
tl;dr
A container MUST run its program in the foreground.
Your Dockerfile is the issue. From the github repository you provided, the Dockerfile content is:
# Dockerfile for nginx with configurable persistent volumes
# Select nginx as the base image
FROM nginx
MAINTAINER Tomas Basham <me#tomasbasham.co.uk>
# Install net-tools
RUN apt-get update -q && \
apt-get install -qy net-tools && \
apt-get clean
# Mount configurable persistent volumes
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
# Expose both HTTP and HTTPS ports
EXPOSE 80 443
# ENTRYPOINT
ENTRYPOINT ["service", "nginx", "start"]
Before debugging your RSpec/serverspec tests, you should make sure that docker image is able to run a container.
Type those commands from the directory which has the Dockerfile in:
docker build -t tmp .
docker run --rm -it tmp
If you get your shell prompt back to you, that means your container stopped running. If your container isn't starting, then your test suite will fail.
What's wrong with the dockerfile
The entrypoint you defined ENTRYPOINT ["service", "nginx", "start"] will execute a command that will, in turn, start the nginx program in the background. This means the process that was initially run by docker (/bin/service) will terminate, and docker will detect that and stop your container.
To run nginx in the foreground, one must run nginx -g daemon off; as you can find in the Dockerfile for the official nginx image. But since you put daemon off; in your nginx.conf file, you should be fine with just nginx.
I suggest you remove the entrypoint from your Dockerfile (and also remove the daemon off; from your nginx config) and it should work fine.
serverspec
Once you get a container which runs, you will have to focus on the serverspec part on which I'm not experienced with.

Resources