I was testing Skaffod and It is a great tool for microservices development.
But I do not find any tutorial on how to use it with Java. Is there any support to Maven builds?
There is a discussion going on about adding support for Java apps here, you can very much use Docker multistage build with Skaffold. A probably working example is available here
Your build portion of Skaffold file will look something like:
apiVersion: skaffold/v1alpha2
kind: Config
build:
tagPolicy:
dateTime:
format: 2006-01-02_15-04-05.999_MST
timezone: Local
artifacts:
- imageName: <repo>/<image>
workspace: ./appdir
In the appdir - you can use a multistage Dockerfile and integrate with rest of the workflow. Multistage Dockefile will build artefact in one stage and create a container using the artefact of the first stage.
Skaffold now supports JIB out of the box which will be more efficient than multistage Dockerfile building! Check out the JIB Maven example in Skaffold.
I haven't tried it yet, but alternatively now it allows you to specify a custom build script: Custom Build Script
I'm assuming you could try as below, or source a build.sh as their documentation exemplifies.
build:
artifacts:
- image: my-image
custom:
buildCommand: mvn package && docker build .
Related
I have a Spring Boot project that builds using a bootJar task in gradle. It produces a runnable ____-1.0-SNAPSHOT.jar file. Now, I want to leverage GitLab CI to build the JAR and make releases.
There didn't seem to be an obvious way to do the builds. I started looking at the researchgate gradle plugin. It seems promising but has a lot of assumptions.
What is the best way to get the release JARs out of GitLab CI?
There is couple of ways of getting released artifacts from gitlab ci pipeline.
Publish it to maven repository (private repository if it is propitiatory)
use gitlab job artifact functionality within pipeline so you can download it via gitlab web interface
build docker image from your pipeline and upload it to docker registry from pipeline
Here is the sample .gitlab-ci.yml which uses gitlab job artifacts functionality (assume gradle wrapper is used)
image: java:8-jdk
cache:
paths:
- .gradle/wrapper
- .gradle/caches
build:
stage: build
script:
- ./gradlew assemble
# define path to collect artifacts
artifacts:
paths:
- build/libs/*.jar
expire_in: 1 week
only:
- master
Ruwanka provided a great answer, however I believe it is now a bit outdated. GitLab.com (and self-hosted) now supports hosted maven repositories as a native feature of their Premium tiers.
More information regarding how to deploy a java application (JAR, etc.) for private or public consumption can be found here:
https://docs.gitlab.com/ee/user/project/packages/maven_repository.html#gitlab-maven-repository-premium
I want to setup a CI pipeline in GitLab for my Java project managed with Maven.
This is my gitlab-ci.yml
image: maven:3-jdk-9
variables:
MAVEN_CLI_OPTS: "--batch-mode"
stages:
- build
compile:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
I always get the following exception:
I tried many things like changing versions of the plugins, various docker images, including a settings.xml and local repository in the project itself, but nothing works.
Thanks in advance for any help!
UPDATE:
Using the latest docker image everything works.
It seems like the CI server has no connection to the internet. Check this using the curl command in your .gitlab-ci.ymlfile.
But I'm pretty sure you guys at daimler have a local mirror, something like Artifactory.
In that case you have to use a settings.xml file.
Here is the official tutorial of Gitlab
I am dockerizing my Java applications by maven docker plugin.
I found a simple docker-maven-plugin that creates a simple docker file..
I want to know how to convert docker file command such as ADD,COPY,VOLUME etc. in to maven xml entries ?
I mean I need to be able to customize my dockerfile through maven pom.xml
I could not find any documentations or tutorial for this ...
Thanks for your input.
I have several java components (WARs), all of them expose webservices, and they happen to use the samemessaging objects (DTOs).
This components all share a common maven dependency for the DTOs, let's call it "messaging-dtos.jar". This common dependency has a version number, for example messaging-dtos-1.2.3.jar, where 1.2.3 is the maven version for that artifact, which is published in a nexus repository and the like.
In the maven world, docker aside, it can get tedious to work with closed version dependencies. The solution for that is maven SNAPSHOTS. When you use for example Eclipse IDE, and you set a dependency to a SNAPSHOT version, this will cause the IDE to take the version from your current workspace instead of nexus, saving time by not having to close a version each time you make a small change.
Now, I don't know how to make this development cycle to work with docker and docker-compose. I have "Component A" which lives in its own git repo, and messaging-dtos.jar, which lives in another git repo, and it's published in nexus.
My Dockerfile simpy does a RUN mvn clean install at some point, bringing the closed version for this dependency (we are using Dockerfiles for the actual deployments, but for local environments we use docker-compose). This works for closed versions, but not for SNAPSHOTS (at least not for local SNAPSHOTs, I could publish the SNAPSHOT in nexus, but that creates another set of problems, with different content overwriting the same SNAPSHOT and such, been there and I would like to not come back).
I've been thinking about using docker-compose volumes at some point, maybe to mount whatever is in my local .m2 so ComponentA can find the snapshot dependency when it builds, but this doesn't feel "clean" enough, the build would depend partially on whatever is specified in the Dockerfile and partially on things build locally. I'm not sure that'd be the correct way.
Any ideas? Thanks!
I propose maintain two approaches: one for your local development environment (i.e. your machine) and another for building in your current CI tool.
For your local dev environment:
A Dockerfile that provides the system needs for your War application (i.e. Tomcat)
docker-compose to mount a volume with the built war app, from Eclipse or whatever IDE.
For CI (not your dev environment):
A very similar Dockerfile but one that can build your application (with maven installed)
A practical example
I use the docker feature: multi stage build.
A single Dockerfile for both Dev and CI envs that might be splited but I prefer to maintain only one:
FROM maven as build
ARG LOCAL_ENV=false
COPY ./src /app/
RUN mkdir /app/target/
RUN touch /app/target/app.war
WORKDIR /app
# Run the following only if we are not in Dev Environment:
RUN test $LOCAL_ENV = "false" && mvn clean install
FROM tomcat
COPY --from=build /app/target/app.war /usr/local/tomcat/webapps
The multi-stage build saves a lot of disk space discarding everything from the build, except what is being COPY --from='ed.
Then, docker-compose.yml used in Dev env:
version: "3"
services:
app:
build:
context: .
args:
LOCAL_ENV: true
volumes:
- ./target/app.war:/usr/local/tomcat/webapps/app.war
Build in CI (not your local machine):
# Will run `mvn clean install`, fetching whatever it needs from Nexus and so on.
docker build .
Run in local env (your local machine):
# Will inject the war that should be available after a build from your IDE
docker-compose up
I would like to build a test environment with Docker, where I can remotely send JUnit test classes (including the code that is tested), execute the tests and retrieve the results.
I found some articles which explained how to use docker for testing databaseconntection/writing inside a redis, but not how i can simple let my tests perform on docker and retrieve the results.
Do you have any recommendations how You would actually achieve this?
I don't know much about Jenkins, but would this might solve my problem?
Is there any good framework outside for this?
In a dockerfile, checkout your code and do a "maven test" command, redirect the result in a file that is on a mounted directory.
Each time you build the dockerfile, you do a unit test on your project.
With docker you also have a "docker test" command. I dont know if there is a plugin to use it on jenkins.
One way I found that works (using Gradle) is as follows. I know you are specifically referencing JUnit as your testing framework, but I actually think something similar to this could work.
Dockerfile (I called mine Dockerfile.UnitTests):
FROM gradle:jdk8 AS test-stage
WORKDIR /app
COPY . ./
RUN gradle clean
RUN gradle test
FROM scratch AS export-stage
COPY --from=test-stage /app/build/reports/tests/test/* /
I then run this with (in Gitbash on Windows 10):
> DOCKER_BUILDKIT=1 docker build -f Dockerfile.UnitTests --output type=tar,dest=UnitTests.tar .
This results in a tar file containing the test results displayed in an html file.
I executed the above in a Gitlab CI/CD pipeline and then sent the results to a web API for analysis.
A couple of assumptions:
My project is set up for Gradle builds so I have the structure from the root of my project src/test/java/groupname/projectname/testfile.java
I am working in Windows 10 targeting Linux containers and using Gitbash.