Spring Boot Bitbucket Pilpline to ECR - java

I try to build a CI/CD Pipeline with Bitbucket-Pipelines.
My dockerized Spring Boot Application should be pushed to my AWS ECR. But when the pipeline executes the docker commands it throws an error:
COPY failed: file not found in build context or excluded by .dockerignore: stat target/app.jar: file does not exist
Does anyone set up a similar pipeline and can help me out?
Here is my dockerfile:
FROM openjdk:11
ARG JAR_FILE
COPY target/app.jar app.jar
EXPOSE 80
ENTRYPOINT ["java", "-jar", "app.jar"]
Here is my pipeline yaml config:
image: maven:3.6.3
pipelines:
default:
- step:
name: Clean install
script:
- cd path.to.file
- mvn clean install -DskipTests
- step:
name: Push to ECR
services:
- docker # Enable Docker for your repository
script:
# build the image
- cd path.to.dockerfile
- docker build -t app-devtest .
# use the pipe to push the image to AWS ECR
- pipe: atlassian/aws-ecr-push-image:1.4.2
variables:
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
IMAGE_NAME: app-devtest
TAGS: 'latest'

The issue is with your dockerfile. This COPY target/app.jar app.jar will work in your local workspace, because you already have the jar locally (it is created when you run your app). In the VM where the pipeline is running, there is no provision to build the jar file over there, so the app.jar is missing.
To fix the issue, first you will need to tell maven to name your jar file using the name you give it; in this case "app". In the pom file of your project, add the following.
<build>
<finalName>app</finalName>
</build>
Then you will need to build the project in the docker build process and then copy your jar file. So the docker file should look something like below.
# first stage: use a maven project to clean package the application
FROM maven:3.8.1-openjdk-11-slim AS MAVEN_BUILD
COPY / /home/myapp/
# Building the jar file using maven
RUN mvn -f /home/app/pom.xml clean package
# second stage: use open jdk 11.0.11 image to build the project docker image
FROM adoptopenjdk/openjdk11:jre-11.0.11_9-alpine
# copy jar needed from the first stage and discard the rest
COPY --from=MAVEN_BUILD /home/myapp/app.jar /usr/local/lib/app.jar
EXPOSE 80
# set the startup command to execute the jar
CMD java -jar /usr/local/lib/app.jar
The above uses a 2 stage docker build process which creates a lightweight docker image.
This should be enough to solve the issue.
COPY failed: file not found in build context or excluded by
.dockerignore: stat target/app.jar: file does not exist

Related

How to build spring boot app in Intellij IDEA in a docker image within the IDE?

I need to replicate the build in our CI/CD tool in the dev workstations of the developers by making Intellij IDEA build within a docker container instead of the current system. Is this doable? I find similar threads with launching the app inside (that i don't need), i need it only as a build environment. I already have the Docker plugin installed but i fail to see how to make it as a build environment.
I have installed the docker plugin, prepared the image. I have docker installed on the workstation.
You are expecting something like this?
FROM eclipse-temurin:17-jdk-alpine as build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:17-jdk-alpine
ARG JAR_FILE=target/*.jar
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build /workspace/app/${JAR_FILE} /app/
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar ${0} ${#}"]
You can use the maven container as a build container to save maven installation time in case it takes.

Dockerfile : /bin/sh: 1: ./mvnw: not found error

I am building a Docker container using the following Dockerfile and actually the app is running on the created container.
FROM eclipse-temurin:17-jdk-jammy as builder
RUN addgroup demogroup; adduser --ingroup demogroup --disabled-password demo
USER demo
WORKDIR /app
# copy pom.xml, mvnw and source code
COPY .mvn/ .mvn
COPY mvnw ./
COPY pom.xml ./
COPY src/ src
#RUN dos2unix ./mvnw
RUN ./mvnw clean install <-- this line gives error
# Second stage: minimal runtime environment
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
# copy jar from the first stage
COPY --from=builder /app/target/*.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
When executing RUN ./mvnw clean install line, I get " /bin/sh: 1: ./mvnw: not found" error. I tried many things, but cannot fix it. Is there any problem in my Dockerfile?
RUN mvn
runs mvn inside the docker image.
The docker image is basically a pared down Linux image. Or a Windows image, or whichever OS was used as the base image.
Presuming your base image is Linux, after docker build completed, at your project folder, you can do
docker run -it
and you will be in your dockerized Linux image, where you can run basic Linux commands (provided your image has those basic commands installed).
You can then navigate and inspect if your docker image.
To solve the problem, include Maven build in your Dockerfile instead of running maven command from project folder via mvnv:
COPY src/main/resources/data/ ./src/data

Building Dockerfile with maven, jdk and jre? [duplicate]

I am building a Docker container using the following Dockerfile and actually the app is running on the created container.
FROM eclipse-temurin:17-jdk-jammy as builder
RUN addgroup demogroup; adduser --ingroup demogroup --disabled-password demo
USER demo
WORKDIR /app
# copy pom.xml, mvnw and source code
COPY .mvn/ .mvn
COPY mvnw ./
COPY pom.xml ./
COPY src/ src
#RUN dos2unix ./mvnw
RUN ./mvnw clean install <-- this line gives error
# Second stage: minimal runtime environment
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
# copy jar from the first stage
COPY --from=builder /app/target/*.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
When executing RUN ./mvnw clean install line, I get " /bin/sh: 1: ./mvnw: not found" error. I tried many things, but cannot fix it. Is there any problem in my Dockerfile?
RUN mvn
runs mvn inside the docker image.
The docker image is basically a pared down Linux image. Or a Windows image, or whichever OS was used as the base image.
Presuming your base image is Linux, after docker build completed, at your project folder, you can do
docker run -it
and you will be in your dockerized Linux image, where you can run basic Linux commands (provided your image has those basic commands installed).
You can then navigate and inspect if your docker image.
To solve the problem, include Maven build in your Dockerfile instead of running maven command from project folder via mvnv:
COPY src/main/resources/data/ ./src/data

COPY or ADD Command in Dockerfile Fails to Find Jar File for Springboot Application

I am getting this error when I am trying to copy the generated jar file from the target folder to /usr/share/ folder in the Docker image. I have scoured Docker forum sites and people are having the exact same issue but there are no clear answer that solves this problem.
Step 9/10 : COPY target/${JAR_FILE} /usr/share/${JAR_FILE}
ERROR: Service 'myservice' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder558103764/target/myservice.jar: no such file or directory
Here's my Dockerfile:
----------------------- begin ---------
FROM adoptopenjdk/openjdk11:alpine
MAINTAINER XXX XXX <ramil.xxxxx#xxxx.ai>
# Add the service itself
ARG JAR_FILE="myservice-1.0.0.jar"
RUN apk add maven
WORKDIR /app
COPY . /app/
RUN mvn -f /app/pom.xml clean install -DskipTests
WORKDIR /app
COPY target/${JAR_FILE} /usr/share/${JAR_FILE}
ENTRYPOINT ["java", "-jar", "/usr/share/myservice-1.0.0.jar"]
------ end snip -------
Here's how I run this from the base folder where I have my Dockerfile on my Mac.
docker build -t service-image .
So I guess you are trying to move your src to image and run a mvn build and copy built file from target to share folder.
If so, every thing seems to be fine except this line
COPY target/${JAR_FILE} /usr/share/${JAR_FILE}
COPY takes in a src and destination. It only lets you copy in a local
file or directory from your host (the machine building the Docker
image) into the Docker image itself
I think your intention is to copy file inside your container's /target to /usr/share folder. try this
RUN cp target/${JAR_FILE} /usr/share/${JAR_FILE}
Regrading error which you see its because with COPY command Docker will try to get the file from docker default path in your HOST
i.e /var/lib/docker/tmp/docker-builder558103764/
where /target folder doesn't exist
I had similar issue because of my .dockerignore had following exclusion:
target
Possible solutions are:
do not ignore target
define ignore exception
!target/*.jar
What has also worked after scouring the Docker forums is using multi-stage build. The multi-stage build not only forces you to use the folders where you specify the WORKDIR in your build stage but also significantly reduces the size of your base images up to 5x-6x less than just using the one stage build like I have shown above. Below is what my solution to finding this jar in the folder I specified as my WORKDIR and use that jar file for my smaller base image. Single-stage build in my initial solution produces 560 MB image. This multi-stage Dockerfile below builds image that is only 108 MB.
FROM adoptopenjdk/openjdk11:alpine as compile
MAINTAINER XXXX <ramil.xxxx#xxxx.ai>
# Build the jar using maven
RUN apk add maven
WORKDIR /app
COPY . /app/
RUN mvn -f pom.xml clean package -DskipTests
FROM adoptopenjdk/openjdk11:alpine-jre
# Copy the packaged jar app file to a smaller JRE base image
COPY --from=compile "/app/target/service-1.0.0.jar" /usr/share/
ENTRYPOINT ["java", "-jar", "/usr/share/service-1.0.0.jar"]
It turns out that the Dockerfile I was using wanted to be executed in a folder different from where the Dockerfile was located.
So given a build_config_folder/Dockerfile...
So instead of
docker build --build-arg SOME_ARG=value build_config_folder
# or
cd build_config_folder
docker build --build-arg SOME_ARG=value .
It needed to be
docker build --build-arg SOME_ARG=value -f build_config_folder/Dockerfile .
This is because the final path positional argument determines where the COPY command will look for files and folders.
Hope that helps someone.

Automated Spring boot Docker Image failed to build on docker hub when connected to github/bitbucket repository

I have a simple Dockerfile in my spring boot as follow. I am able to build the image successfully locally, and can push using my credentials.
But my build keeps failing on every attempt to build automatically.
FROM openjdk:8-jdk-alpine
LABEL maintainer="xxxxx#xxx.com"
VOLUME /tmp
EXPOSE 8080
ARG JAR_FILE=target/jollof.jar
ADD ${JAR_FILE} jollof.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-
jar","/jollof.jar"]
From docker hub, I got this from the log.
Building in Docker Cloud's infrastructure...
Cloning into '.'...
Warning: Permanently added the RSA host key for IP address 'xxx.xx.xxx.xxx' to
the list of known hosts.
....
....
Step 6/7 : ADD ${JAR_FILE} jollof.jar
ADD failed: stat /var/lib/docker/tmp/docker-
builder674045875/target/jollof.jar:
no such file or directory
Unlike your local environment, Docker Hub fetches then builds your project in a fresh environment, so that the file target/jollof.jar that is intended to be copied is not available in the docker context. Hence the error you observe.
So I'd suggest refactoring your Dockerfile so that mvn package or so is done in the Dockerfile itself (which is a best practice to adopt, for the sake of reproducibility). Note that this configuration will be working for Docker Hub's automated builds as well as the builds in your local environment.
For example, below is an example Dockerfile that inspired by the that of this SO answer How to convert a Spring-Boot web service into a Docker image? as well as the Dockerfile of your post:
FROM maven:3.6-jdk-8 as maven
WORKDIR /app
COPY ./pom.xml ./pom.xml
RUN mvn dependency:go-offline -B
COPY ./src ./src
# TODO: jollof-* should be replaced with the proper prefix
RUN mvn package && cp target/jollof-*.jar app.jar
# Rely on Docker's multi-stage build to get a smaller image based on JRE
FROM openjdk:8-jre-alpine
LABEL maintainer="xxxxx#xxx.com"
WORKDIR /app
COPY --from=maven /app/app.jar ./app.jar
# VOLUME /tmp # optional
EXPOSE 8080 # also optional
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/app.jar"]

Categories