I have a project running Vue & Spring Boot that I need to create a docker-compose.yml file to run mvn clean install to generate the .jar, and then build a "new" image from another Dockerfile with that said .jar inside the docker container.
This is the Dockerfile that needs to be run once the mvn clean install is completed:
FROM java:8
ENV WKHTML_VERSION 0.12.4
# Builds the wkhtmltopdf download URL based on version numbers above
ENV DOWNLOAD_URL "https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/${WKHTML_VERSION}/wkhtmltox-${WKHTML_VERSION}_linux-generic-amd64.tar.xz"
RUN apt-get update && \
apt-get install -y --no-install-recommends wget && \
wget $DOWNLOAD_URL && \
tar vxf wkhtmltox-${WKHTML_VERSION}_linux-generic-amd64.tar.xz && \
cp wkhtmltox/bin/wk* /usr/local/bin/ && \
cp wkhtmltox/lib/* /usr/local/lib/ && \
rm wkhtmltox-${WKHTML_VERSION}_linux-generic-amd64.tar.xz
# #see https://spring.io/guides/gs/spring-boot-docker/
COPY server/target/redo-server-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
So the build steps need to be something like this:
Install node + maven / pull those images
Install postgresql & pull that image
Run mvn clean install & generate .jar
Build new image from abovementioned Dockerfile and run it
I am new to docker-compose so I am having troubles setting this up in the correct execution order.
The reason I need to do this is due to a problem with the production pipeline not having node or npm, which is needed to run the full maven application (Vue.js and Spring Boot app), which is why it needs to be compiled from inside the Docker container
It would be greatly appreciated if anyone could point me in the right direction, let alone – is this possible to do?
Solved by writing a multi-step build as my Dockerfile. I am installing node as a dependency in the client's pom.xml file.
# Install maven and copy project for compilation
FROM maven:latest as builder
COPY pom.xml /usr/local/pom.xml
COPY server /usr/local/server
COPY client /usr/local/client
WORKDIR /usr/local/
RUN mvn clean install
FROM openjdk:8
ENV WKHTML_VERSION 0.12.4
# Builds the wkhtmltopdf download URL based on version numbers above
ENV DOWNLOAD_URL "https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/${WKHTML_VERSION}/wkhtmltox-${WKHTML_VERSION}_linux-generic-amd64.tar.xz"
RUN apt-get update && \
apt-get install -y --no-install-recommends wget && \
wget $DOWNLOAD_URL && \
tar vxf wkhtmltox-${WKHTML_VERSION}_linux-generic-amd64.tar.xz && \
cp wkhtmltox/bin/wk* /usr/local/bin/ && \
cp wkhtmltox/lib/* /usr/local/lib/ && \
rm wkhtmltox-${WKHTML_VERSION}_linux-generic-amd64.tar.xz
COPY --from=builder /usr/local/redo/server/target/server-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
Related
New to the java community, and would appreciate all of the help that I can get with my Dockerfile and Docker Compose setup.
These are the requirements of my project.
Use Maven 3.6.3 and Java 8 SDK,
create a workdir named /app
create a non root user with root permissions (max -777)
install basic linux tools and utilities
change to the root folder as a root user and cd into .m2/settings.xml and edit it with the code below.
Additionally, I need to copy over the pom.xml, the /target, the /src, and settings.xml and the app dir itself as illustrated in my attempt below.
And then run and execute this entire application as a non-root user with root permissions to create, delete, and update files and dirs in the root dir and throughout /app for the build with mvn.
# Custom image from Maven on DockerHub
# Language: dockerfile
FROM maven:3.6.3-amazoncorretto-8
# Set the working dir
WORKDIR /app
# Create a non root user
ARG USERNAME=jefferson
ARG USER_UID=1000
ARG USER_GID=$USER_UID
# Add linux dependenciesq
RUN yum install wget -y
RUN yum install shadow-utils -y
# Create the user
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& yum install sudo -y \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 777 /etc/sudoers.d/$USERNAME \
&& sudo groupadd docker \
&& sudo usermod -aG docker $USERNAME \
&& newgrp docker
# Change to the root folder and edit the settings.xml for Maven
WORKDIR /root/.m2
RUN rm -rf settings.xml
RUN echo '<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" \
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 \
http://maven.apache.org/xsd/settings-1.0.0.xsd"> \
</settings>' >> settings.xml
WORKDIR /app
COPY . ./
USER $USERNAME
# Run the application
CMD ["mvn", "clean", "verify", "-Pcargo.run", "-X"]
version: '1.0'
services:
app:
build: .
command: sh -c "mvn clean verify && mvn -Pcargo.run -X"
ports:
- 3100:3100
working_dir: /app
volumes:
# give absolute path of the workdir app working_dir
- .:/app
# give the absolute bath of src starting at app
- ./src:/app/src
# give the absolute path of target
- ./target:/app/target
# give the absolute path of the maven repo
- ~/.m2:/root/.m2
# give thepom.xml
- ./pom.xml:/app/pom.xml
That being said the docker compose up command should both build and run the container on port 3100. Can somebody give me a push in the right direction?
So I am trying to install OpenJDK in a Dockerfile but I am having issues. It always errors with the following message: Sub-process /usr/bin/dpkg returned an error code (1) and then underneath The command bin/sh returned a non-zero code: 100. This is the command that failed to execute. Currently on Ubuntu 20.04 VM
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY Folder/*.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet build -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/runtime:5.0
# Install OpenJDK-14
RUN apt-get update && \
apt-get install -y default-jdk && \
apt-get install -y ant && \
apt-get clean;
# Fix certificate issues
RUN apt-get update && \
apt-get install ca-certificates-java && \
apt-get clean && \
update-ca-certificates -f;
# Setup JAVA_HOME -- useful for docker commandline
ENV JAVA_HOME /usr/lib/jvm/default/
RUN export JAVA_HOME
RUN apt-get install -y supervisor # Installing supervisord
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
WORKDIR /app
COPY Folder/Lavalink/* ./
COPY --from=build-env /app/out .
#ENTRYPOINT ["dotnet", "Application.dll"]
ENTRYPOINT ["/usr/bin/supervisord"]
Here is the supervisord as well
[supervisord]
nodaemon=true
[program:folder]
command=dotnet /app/Application.dll
[program:lavalink]
command=java -jar /app/Lavalink.jar
This is a Visual Studio project written in 5.0 with a .jar file that needs to be executed.
These didn't seem to help:
apt-get update' returned a non-zero code: 100, Docker File Non-Zero Code 100 Error When Building Basically what I am trying to achieve is to install java within a container. Preferably java 13 but this issue prevents me from doing so. Last, it is important to let you know that the same commands works on another container.
Add this before installing the jdk :
RUN mkdir -p /usr/share/man/man1/
This is a problem in the debian slim images and this image is based on buster-slim. Alternatively you can try to use one of the dotnet/runtime images based on Ubuntu (5.0-focal) or Alpine (5.0-alpine).
I am using this docker-compose.yaml file to run airflow on docker container.
https://airflow.apache.org/docs/apache-airflow/2.0.2/docker-compose.yaml
I need to install JRE in one of the containers. How do I add instruction to add java to the docker-compose.yaml file?
Try the following:
Create the following Dockerfile in the directory where you also have the docker-compose.yml:
FROM apache/airflow:2.0.2
USER root
# Install OpenJDK-11
RUN apt update && \
apt-get install -y openjdk-11-jdk && \
apt-get install -y ant && \
apt-get clean;
# Set JAVA_HOME
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64/
RUN export JAVA_HOME
USER airflow
WORKDIR /app
COPY requirements.txt /app
RUN pip install --trusted-host pypi.python.org -r requirements.txt
In order to install packages via apt, you have to switch to root user. Later, we switch back to user airflow. The specification of the working directory and the installation of python packages through requirements.txt might not apply, depending on your case.
Then, in your docker-compose.yml, add build: . after &airflow-common.
Finally, build your pipeline using docker-compose up -d --build.
For more information, look here: https://airflow.apache.org/docs/docker-stack/build.html#building-the-image
You have to build your own airflow image.
In your Dockerfile you have to apt install the airflow and export JAVA_HOME.
Dockerfile example:
FROM apache/airflow:2.5.1
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
openjdk-11-jre-headless \
&& apt-get autoremove -yqq --purge \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
USER airflow
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
RUN pip install --no-cache-dir apache-airflow-providers-apache-spark==2.1.3
Build command example:
docker build -t airflow-with-java .
After successfully image building edit your docker-compose by replacing airflow image:
x-airflow-common:
&airflow-common
image: ${AIRFLOW_IMAGE_NAME:-airflow-with-java}
More information you can look here: https://airflow.apache.org/docs/docker-stack/build.html
I am new to docker, and I am trying to setup docker for spring boot project.
Here is my Dockerfile
FROM maven:3.6.3-jdk-11-slim AS build
WORKDIR usr/src/springboot
COPY . ./
RUN mvn install
RUN mvn clean package
#
# Package stage
#
FROM openjdk:11-jre-slim
ARG JAR_NAME="springboot-0.0.1-SNAPSHOT"
WORKDIR /usr/src/springboot
EXPOSE 8080
COPY --from=build /usr/src/springboot/target/${JAR_NAME}.jar ./springboot.jar
CMD ["java","-jar", "./springboot.jar"]
Which works completely fine and I can access hello world from localhost:8080
But my confusion is how to make any changes in java file reflect in the docker container? how do I recompile the .jar file.
I tried something like docker exec -it strange_shaw "mvn clean package"
But it throws error exec: "mvn clean package": executable file not found in $PATH: unknown
when you are using double FROM instruction inside your Dockerfile , Docker will keep only the latest FROM and use the previous FROM to build the next one.
So it is simple to find this error because FROM maven:3.6.3-jdk-11-slim AS build only used to build the next step FROM openjdk:11-jre-slim and will be removed from the final image(this strategy used to minimize the docker image size).
I hope that give you a clear idea about Dockerfile with multiple stage.
Build your jar outside after your Dockerfile will be like that:
FROM openjdk:11-jre-slim
ARG JAR_NAME="springboot-0.0.1-SNAPSHOT"
WORKDIR /usr/src/springboot
EXPOSE 8080
COPY /usr/src/springboot/target/${JAR_NAME}.jar ./springboot.jar
CMD ["java","-jar", "./springboot.jar"]
The issue was that maven was not installed within the container. So I changed my Dockerfile to
FROM openjdk:11
ARG JAR_NAME="springboot-0.0.1-SNAPSHOT"
WORKDIR /usr/src/springboot
EXPOSE 8080
#COPY --from=build /usr/src/springboot/target/${JAR_NAME}.jar ./springboot.jar
#CMD ["java","-jar", "./springboot.jar"]
RUN apt-get update; apt-get install curl -y
ARG MAVEN_VERSION=3.6.3
# 2- Define a constant with the working directory
ARG USER_HOME_DIR="/root"
# 4- Define the URL where maven can be downloaded from
ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
# 5- Create the directories, download maven, validate the download, install it, remove downloaded file and set links
RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
&& echo "Downloading maven" \
&& curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
\
&& echo "Unziping maven" \
&& tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
\
&& echo "Cleaning and setting links" \
&& rm -f /tmp/apache-maven.tar.gz \
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
# 6- Define environmental variables required by Maven, like Maven_Home directory and where the maven repo is located
ENV MAVEN_HOME /usr/share/maven
ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"
This will install maven inside the container and set $PATH
docker run -it -v "$(pwd)":/usr/src/springboot -p 8080:8080 spring-boot-app
Run above command to start container and map your project folder to container folder and local port to container port. So both are in sync if you do any changes in project.
docker exec -it <container_name> mvn verify
Above command will create the .jar file. Restart the container.
docker exec -it <container_name> java -jar target/<file_name>.jar
Will execute the jar file in port 8080 and will be accessible in your localhost:8080
I'm trying to Dockerize a Gauge test automation project so I can run specs inside a Docker container. The project is written in Java and Spring Boot.
I saw this tutorial in Gauge documentation.
This is the DockerFile in the tutorial:
FROM ubuntu
# Install Java.
RUN apt-get update && apt-get install -q -y \
openjdk-8-jdk \
apt-transport-https \
gnupg2 \
ca-certificates
# Install gauge
RUN apt-key adv --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys 023EDB0B && \
echo deb https://dl.bintray.com/gauge/gauge-deb stable main | tee -a /etc/apt/sources.list
RUN apt-get update && apt-get install gauge
# Install gauge plugins
RUN gauge install java && \
gauge install screenshot
ENV PATH=$HOME/.gauge:$PATH
As you see, there's no "ADD"/"COPY" there in the DokcerFile.
Is it just suggesting an alternative to install Gauge and the other packages on the host?
Any ideas on how to run the specs inside a Docker container?
Here is what I did to get the test running in the docker container.
I have a specs folder beside src in my project structure meaning the gauge tests will run using the JAR file but they're not part of the JAR file themselves.
--MyProject
----specs
----src
...
I used maven to run the test inside the container. That's why I preferred to build the project inside the container so I get the JAR file ready with the same version of maven I run the test with.
Here is the DockerFile. I developed a bash script to run the test. You may run the script with CMD or ENTRYPOINT:
FROM maven:3.6.1-jdk-8
# add any project resources needed
ADD env /home/e2e/env
ADD specs /home/e2e/specs
ADD src /home/e2e/src
ADD src/main/scripts/entrypoint.sh /home/e2e/
ADD pom.xml /home/e2e/
RUN ["chmod", "+x", "./home/e2e/entrypoint.sh"]
# Install Gauge, web browser and webdriver in your preferred way...
ENV PATH=$HOME/.gauge:$PATH
# I'm keeping the cntainer running. But it's all up to you.
CMD /home/e2e/entrypoint.sh && tail -f /dev/null
And then here is the simple entrypoint.sh script:
#!/bin/bash
cd /home/e2e/
mvn clean package
gauge --version
google-chrome --version
mvn -version
mvn gauge:execute -DspecsDir=specs/myTest.spec
Of course, you could just use a ready JAR instead of building it inside the container. Or you could build the JAR while creating the docker image.