Execute Spring buildpacks when calling docker-compose build command - spring

I'm using Spring buildpacks introduced by Spring Boot 2.3.0.M1 for creating Docker images of Spring based applications. Everything goes well, I can create docker images for each application by executing ./gradlew bootBuildImage Gradle task, point docker-compose file to created images (e.g. image: spring-test:latest) and at the end successfully run all applications (docker-compose up).
Even though I have a bash script to automate the build process, I'd like to get rid of this additional step and make the Spring buildpacks task executed automatically whenever I run docker-compose up --build command thus the docker image of each application would get built and uploaded to the host's local docker repository from where it would be taken over by docker compose.
My first try was to create a dummy Dockerfile for each application which executes the bootBuildImage task on the host, but that would require an SSH connection from docker to host and not even sure that would work correctly.
Another thought was to use a similar approach, only change is to first mount or copy the app's source code to docker, configure buildpacks to store image into host's local docker image repo (perhaps SSH connection) and finally execute buildpacks on docker.
I'm wondering if there isn't a better, more elegant solution though.

This question really drove me nuts, since I've been playing around with Spring Boot & Paketo Buildpacks for quite a while now - and I really love the simplicity of Docker-Compose. So the questions was already inside the back of my head, but then you asked it :)
I didn't found a 100% perfect solution, but I think a have some ideas. Let's assume a example project of multiple Spring Boot apps, that are composed by a Maven multi-module setup (I know you're using Gradle, but there's a guide on doing multi module setups with Gradle over at the great spring.io guides):
github.com/jonashackt/cxf-spring-cloud-netflix-docker. I created a new branch buildpacks-paketo containing all we need - and removed all Dockerfiles from the respective Spring Boot apps. Since we shouldn't need them anymore using Cloud Native Buildpacks (which is kind of their design goal).
TLDR: My idea is to use the spring-boot-maven-plugin (or it's Gradle equivalent) to issue a fresh Paketo build before every "normal docker-compose up like this:
mvn clean spring-boot:build-image && docker-compose up
The example projects parent pom.xml look like this (shortened):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.jonashackt</groupId>
<artifactId>cxf-spring-cloud-netflix-docker-build-all</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<modules>
<module>eureka-serviceregistry</module>
<module>spring-boot-admin</module>
<module>zuul-edgeservice</module>
<module>weatherbackend</module>
<module>weatherservice</module>
<module>weatherclient</module>
</modules>
</project>
The example projects docker-compose.yml looks straightforward and uses the container images producted by Paketo (which is triggered by the Maven plugin) - those are named like this: eureka-serviceregistry:0.0.1-SNAPSHOT. Here's the full docker-compose.yml for all Spring Boot services:
version: '3.3'
services:
eureka-serviceregistry:
image: eureka-serviceregistry:0.0.1-SNAPSHOT
ports:
- "8761:8761"
tty:
true
restart:
unless-stopped
spring-boot-admin:
image: spring-boot-admin:0.0.1-SNAPSHOT
ports:
- "8092:8092"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
# no portbinding here - the actual services should be accessible through Zuul proxy
weatherbackend:
image: weatherbackend:0.0.1-SNAPSHOT
ports:
- "8090"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
# no portbinding here - the actual services should be accessible through Zuul proxy
weatherservice:
image: weatherservice:0.0.1-SNAPSHOT
ports:
- "8095"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
zuul-edgeservice:
image: zuul-edgeservice:0.0.1-SNAPSHOT
ports:
- "8080:8080"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
=== Possible enhancements =====================
The idea stuck me to also have "on single docker-compose.yml and only use docker-compose up as you asked for - no additional command. Therefore I created another "Docker Compose build service" that should only build the service images like this:
version: '3.3'
services:
paketo-build:
image: maven:3.6-openjdk-15
command: "mvn clean spring-boot:build-image -B -DskipTests --no-transfer-progress" # build all apps
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro" # Mount Docker from host into build container for Paketo to work
- "$HOME/.m2:/root/.m2" # Mount your local Maven repository into build container to prevent repeated downloads
- "$PWD:/workspace" # Mount all Spring Boot apps into the build container
working_dir: "/workspace"
I first integrated this service in the docker-compose.yml I already had. Running a docker-compose up paketo-build did what I was looking for: building all our Spring Boot apps inside the Compose setup:
...
paketo-build_1 | [INFO] --- spring-boot-maven-plugin:2.4.1:build-image (default-cli) # eureka-serviceregistry ---
paketo-build_1 | [INFO] Building image 'docker.io/library/eureka-serviceregistry:0.0.1-SNAPSHOT'
paketo-build_1 | [INFO]
paketo-build_1 | [INFO] > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 100%
paketo-build_1 | [INFO] > Pulled builder image 'paketobuildpacks/builder#sha256:3cff90d13d353ffdb83acb42540dae4ce6c97d55c07fb01c39fe0922177915fa'
paketo-build_1 | [INFO] > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' 100%
paketo-build_1 | [INFO] > Pulled run image 'paketobuildpacks/run#sha256:f393fa2927a2619a10fc09bb109f822d20df909c10fed4ce3c36fad313ea18e3'
paketo-build_1 | [INFO] > Executing lifecycle version v0.10.1
paketo-build_1 | [INFO] > Using build cache volume 'pack-cache-9d8694845b92.build'
paketo-build_1 | [INFO]
paketo-build_1 | [INFO] > Running creator
paketo-build_1 | [INFO] [creator] ===> DETECTING
...
paketo-build_1 | [INFO] [creator]
paketo-build_1 | [INFO] [creator] Paketo Spring Boot Buildpack 3.5.0
paketo-build_1 | [INFO] [creator] https://github.com/paketo-buildpacks/spring-boot
paketo-build_1 | [INFO] [creator] Creating slices from layers index
...
paketo-build_1 | [INFO] [creator] Adding label 'io.buildpacks.project.metadata'
paketo-build_1 | [INFO] [creator] Adding label 'org.opencontainers.image.title'
paketo-build_1 | [INFO] [creator] Adding label 'org.opencontainers.image.version'
paketo-build_1 | [INFO] [creator] Adding label 'org.springframework.boot.spring-configuration-metadata.json'
paketo-build_1 | [INFO] [creator] Adding label 'org.springframework.boot.version'
paketo-build_1 | [INFO] [creator] Setting default process type 'web'
paketo-build_1 | [INFO] [creator] *** Images (7efae8be1167):
paketo-build_1 | [INFO] [creator] docker.io/library/eureka-serviceregistry:0.0.1-SNAPSHOT
paketo-build_1 | [INFO]
paketo-build_1 | [INFO] Successfully built image 'docker.io/library/eureka-serviceregistry:0.0.1-SNAPSHOT'
...
But that didn't feel right because of a bunch of reasons. One is that you need to somehow wait with the startup of all other Compose services until the paketo-build service did it's job and build all the images. BUT as the Docker docs tell us, we will need to work against design decisions made in Compose to make that happen! Also did I find this great answer, where Max explains that it's not a good design to "pollute" the "production" docker-compose.yml with containers that are solely there for the build.
After that I extracted the paketo-build service into it's own Compose file - called build.yml inside the example project. With that we're now able to run the Paketo build without relying on the host to have Maven installed - and solely with Docker-Compose:
docker-compose -f build.yml up && docker-compose up
Remember to not detach from the first container with -d since the full Paketo build has to be finished before we start our docker-compose.yml. With this approach we also need absolutely no Dockerfile. But at the same time the idea came to me to remove the need for a separate build container fully and simply use Maven (or Gradle) before the up concatenated by a && like already described in the TLDR:
mvn clean spring-boot:build-image && docker-compose up
Hope this is of help to you. Would be glad to hear your feedback! Here's also a full GitHub actions build showing all the "magic" on a Cloud CI server.
Right now there's afaik no way to use docker-compose up --build to trigger a fresh image build of all your Spring Boot apps using Paketo Buildpacks.

Related

How to build with maven inside docker container using dependency on a docker image?

I have 2 spring boot projects, one of them is the "core" which is used as a dependency by the second, called here "sascar".
I have a Dockerfile to generate the core image:
FROM maven:3.3-jdk-8
WORKDIR /opt/ivr-engine-core
ADD ./engine-core/. /opt/engine-core
RUN ls -la /opt/engine-core
RUN mvn clean install
Then I run to build the image:
docker build . -t engine-core
Then I start a docker container with the image just created using the main project (engine-sascar inside the app folder) and enter in the bash:
docker run -it --rm -w /app -v "$PWD/engine-sascar:/app" engine-core:latest bash
When inside the container I try to run the maven command to package or install, the point is, this main project canĀ“t reach the core project to use its classes:
mvn clean package
Resulting in:
[INFO] Compiling 35 source files to /app/target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /app/src/main/java/com/app/sascar/StepOne.java:[8,33] package com.engine.core does not exist
How could I make this maven project inside this container "see" those classes inside the image I created before?

Spring Boot Gradle bootBuildImage task with private repo

I'm trying to set up a Spring Boot / Gradle project to use bootBuildImage to build my Docker image, but am hitting a snag. We have limited external network access on our build servers; we use a private nexus repository.
When I try to run the bootBuildImage task, it's attempting to request a file from repo.spring.io:
[creator] unable to invoke layer creator
[creator] unable to contribute spring-cloud-bindings layer
[creator] unable to get dependency spring-cloud-bindings
[creator] unable to download https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar
[creator] unable to request https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar
I have repo.spring.io added as a repository on our nexus server, but I'm unclear on how to get the Spring Boot Gradle plugin to use it. I tried adding it to my repositories block, but it didn't seem to have an effect.
repositories {
// Other repositories...
//
maven {
url "<my nexus server>/repository/spring-io-releases/"
}
What am I missing?
I had a similar problem where I needed to configure the download uri of the bellsoft-liberica JDK used inside the Spring Boot build image goal/task to not use github.com - but my own private server instead. It cannot be done with buildpack environment variable alone, but you can use bindings for that!
Please note that with the Spring Boot Gradle Plugin or Spring Boot Maven Plugin it requires Spring Boot 2.5+ (a bindings option has been added in 2.5). If you're on an older Spring Boot release, you need to either upgrade or switch over to pack CLI.
Bindings can be configured either through volumes or Kubernetes secrets. I created a fully comprehensible guide on how to use bindings in order to change a uri used inside a buildpack - but I will outline the key steps for switching the spring-cloud-bindings-x.y.z.jar uri:
1. Create bindings directory
In order to hand over the binding configuration to pack CLI we need to create a directory first:
mkdir spring-cloud-config && cd spring-cloud-config
2. Create file type, containing the binding key
Now we need to create a file called type inside this directory containing the binding key for the spring-boot buildpack binding type dependency-mapping:
echo "dependency-mapping" >> type
3. Create file named as the sha256, containing the spring-cloud-bindings-x.y.z.jar uri
Now we should create another file named exactly according to the sha256 digest value of the [[metadata.dependencies]] section of the spring-cloud-bindings-1.7.0.jar inside the buildpack.toml:
[[metadata.dependencies]]
id = "spring-cloud-bindings"
name = "Spring Cloud Bindings"
version = "1.7.0"
uri = "https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar"
sha256 = "e3c18bf1a3c2e52743f9ff2fa46af59e5eee0a7f0683ff562eb35aa866e4a9e9"
stacks = [ "io.buildpacks.stacks.bionic", "org.cloudfoundry.stacks.cflinuxfs3" ]
This file must contain the uri of your internal nexus incl. the spring-cloud-bindings.jar:
echo "http://<my nexus server>/repository/spring-io-releases/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar" >> e3c18bf1a3c2e52743f9ff2fa46af59e5eee0a7f0683ff562eb35aa866e4a9e9
4. Execute pack CLI with --volume to use the binding
Finally we can issue our pack CLI command. Ensure that pack CLI is installed on your system:
pack build your-application-name-here \
--path . \
--volume $(pwd)/spring-cloud-config:/platform/bindings/spring-cloud-config \
--builder paketobuildpacks/builder:base
Alternatively, you can use the bindings option with Spring Boot 2.5+ Maven or Gradle plugins, see links above.
Now the spring-boot buildpack will download the spring-cloud-bindings-1.7.0.jar from http://<my nexus server>/repository/spring-io-releases/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar instead of https://repo.spring.io/release.
The bootBuildImage Gradle task uses Paketo Buildpacks to build your OCI container. There are a bunch of buildpacks participating in the creation of the container, one of them is the Spring Boot Buildpack. Among other things, the Spring Boot Buildpack will add Spring Cloud Bindings to the application classpath:
[creator] Spring Cloud Bindings 1.7.0: Contributing to layer
[creator] Downloading from https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar
[creator] Verifying checksum
[creator] Copying to /layers/paketo-buildpacks_spring-boot/spring-cloud-bindings
This all happens inside the build container and the buildpack is not aware of your Gradle repositories. The dependency URL is defined in the buildpack itself:
[[metadata.dependencies]]
id = "spring-cloud-bindings"
name = "Spring Cloud Bindings"
version = "1.7.0"
uri = "https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.0/spring-cloud-bindings-1.7.0.jar"
sha256 = "e3c18bf1a3c2e52743f9ff2fa46af59e5eee0a7f0683ff562eb35aa866e4a9e9"
stacks = [ "io.buildpacks.stacks.bionic", "org.cloudfoundry.stacks.cflinuxfs3" ]
Using the environment variable BPL_SPRING_CLOUD_BINDINGS_ENABLED, you can disable autoconfiguring Spring Boot environment properties from bindings, but the jar file will be pulled anyway.
bootBuildImage {
environment = ["BPL_SPRING_CLOUD_BINDINGS_ENABLED" : "false"]
}
I started getting this error now on spring-cloud-bindings-1.7.1 but in the past it worked:
...
[INFO] [creator] Paketo Spring Boot Buildpack 4.2.0
[INFO] [creator] https://github.com/paketo-buildpacks/spring-boot
[INFO] [creator] Creating slices from layers index
[INFO] [creator] dependencies
[INFO] [creator] spring-boot-loader
[INFO] [creator] snapshot-dependencies
[INFO] [creator] application
[INFO] [creator] Launch Helper: Contributing to layer
[INFO] [creator] Creating /layers/paketo-buildpacks_spring-boot/helper/exec.d/spring-cloud-bindings
[INFO] [creator] Spring Cloud Bindings 1.7.1: Contributing to layer
[INFO] [creator] Downloading from https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.1/spring-cloud-bindings-1.7.1.jar
[INFO] [creator] unable to invoke layer creator
[INFO] [creator] unable to contribute spring-cloud-bindings layer
[INFO] [creator] unable to get dependency spring-cloud-bindings
[INFO] [creator] unable to download https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.1/spring-cloud-bindings-1.7.1.jar
[INFO] [creator] unable to request https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.7.1/spring-cloud-bindings-1.7.1.jar
...
Old log:
...
[INFO] [creator] Paketo Spring Boot Buildpack 4.2.0
[INFO] [creator] https://github.com/paketo-buildpacks/spring-boot
[INFO] [creator] Creating slices from layers index
[INFO] [creator] dependencies
[INFO] [creator] spring-boot-loader
[INFO] [creator] snapshot-dependencies
[INFO] [creator] application
[INFO] [creator] Launch Helper: Reusing cached layer
[INFO] [creator] Spring Cloud Bindings 1.7.1: Reusing cached layer
[INFO] [creator] Web Application Type: Contributing to layer
[INFO] [creator] Servlet web application detected
[INFO] [creator] Writing env.launch/BPL_JVM_THREAD_COUNT.default
[INFO] [creator] 4 application slices
[INFO] [creator] Image labels:
[INFO] [creator] org.opencontainers.image.title
[INFO] [creator] org.opencontainers.image.version
[INFO] [creator] org.springframework.boot.spring-configuration-metadata.json
[INFO] [creator] org.springframework.boot.version
...
[INFO] [creator] *** Images (aafb789b0498):
[INFO] [creator] docker.io/library/cpo-process-registry:1.0.0
[INFO]
[INFO] Successfully built image 'docker.io/library/cpo-process-registry:1.0.0'

How do I use spring boot maven plugin build-image with skaffold and dekorate?

I'm trying to use Skaffold, Dekorate and Spring Boot.
I can't find any examples using the new buildpack feature of Spring Boot 2.3+
apiVersion: skaffold/v2beta9
kind: Config
metadata:
name: tellus-upgrade
build:
artifacts:
- image: tellus-admin
custom:
buildCommand: ./mvnw -pl tellus-admin org.springframework.boot:spring-boot-maven-plugin:2.4.0:build-image -Dspring-boot.build-image.imageName=$IMAGE -Drevision=dev-SNAPSHOT -DskipTests=true
dependencies:
paths:
- tellus-admin/src
- tellus-admin/pom.xml
- image: tellus-config-server
custom:
buildCommand: ./mvnw -pl tellus-config-server org.springframework.boot:spring-boot-maven-plugin:2.4.0:build-image -Dspring-boot.build-image.imageName=$IMAGE -Drevision=dev-SNAPSHOT -DskipTests=true
dependencies:
paths:
- tellus-config-server/src
- tellus-config-server/pom.xml
deploy:
kubectl:
manifests:
- kubernetes/defaults.yml
- kubernetes/db/kubernetes.yml
- kubernetes/dev/dnsutils.yml
- kubernetes/kafka-connect/kubernetes.yml
- tellus-admin/target/classes/META-INF/dekorate/kubernetes.yml
- tellus-config-server/target/classes/META-INF/dekorate/kubernetes.yml
When I run skaffold dev I get the error:
exiting dev mode because first build failed: the custom script didn't produce an image with tag [tellus-config-server:RELEASE_2020_2_0-226-g9be76a373-dirty]
However from the logs it looks like the image was built...
[INFO] Successfully built image 'docker.io/library/tellus-config-server:RELEASE_2020_2_0-226-g9be76a373-dirty'
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.004 s
[INFO] Finished at: 2020-11-15T22:31:59+11:00
[INFO] ------------------------------------------------------------------------
Building [tellus-admin]...
exiting dev mode because first build failed: the custom script didn't produce an image with tag [tellus-config-server:RELEASE_2020_2_0-226-g9be76a373-dirty]
The spring-boot-maven-plugin:build-image loads the image into your local Docker daemon, but does not push the image. I've never tried it, but you might be able to use the com.spotify:dockerfile-maven-plugin:push goal.
Update: here's a Skaffold custom build script that should do the right thing:
#!/bin/sh
set -e
cd "$BUILD_CONTEXT"
mvn -pl "$1" -Drevision=dev-SNAPSHOT -DskipTests=true \
org.springframework.boot:spring-boot-maven-plugin:build-image \
-Dspring-boot.build-image.imageName="$IMAGE"
if [ "$PUSH_IMAGE" = true ]; then
docker push "$IMAGE"
fi
You could save that to a file mvn-build-image.sh and then modify your skaffold.yaml like:
artifacts:
- image: tellus-admin
custom:
buildCommand: ./mvn-build-image.sh tellus-admin
You might want to look at the Skaffold's Jib integration to simplify this process.
If the problem is based on Paketo/spring-boot-maven-plugin only producing a local container image - and not pushing it as Brian de Alwis outlined - then the Image Publishing ability of the spring-boot-maven-plugin should do the trick. Therefore simply append the following to your mvn spring-boot:build-image command:
mvn spring-boot:build-image -Dspring-boot.build-image.publish=true
You can also configure the image name like this explicitely:
mvn spring-boot:build-image -Dspring-boot.build-image.imageName=docker.example.com/library/tellus-config-server:latest -Dspring-boot.build-image.publish=true
As the docs state you can also configure every aspect of image publishing in your pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>docker.example.com/library/${project.artifactId}</name>
<publish>true</publish>
</image>
<docker>
<publishRegistry>
<username>user</username>
<password>secret</password>
<url>https://docker.example.com/v1/</url>
<email>user#example.com</email>
</publishRegistry>
</docker>
</configuration>
</plugin>
With that configuration in place you wouldn't even need to explicitely use the -Dspring-boot.build-image.publish=true parameter, since we configured <image><publish> to be true.
So no need to use Jib or custom build scripts. And there's even Cloud Native Buildpack support currently in beta for Skaffold - so that could be another option to have a look on (because the spring-boot-maven-plugin is also "only" an abstraction for the Cloud Native Buildpack / Paketo.io integration), if you'd like to switch to pack CLI.

Run (Docker) Test Container in gitlab with Maven

I am working in a gitlab ci/cd pipeline. This pipeline executes all of its commands (excluding the deployments) with maven and docker. In this case, I am trying to run integration tests (that are kicked off by maven), which use a test container (for the mysql database). These tests work fine when running locally. However, I am running into issues when I try to run them from gitlab. I am fairly certain my issue is I don't have access to docker (however, in this case, I need my image to have both docker and maven).
Here is the applicable section of gitlab file:
#This phase is only run when merging (to master)
merge_tests:
image: maven:latest
stage: mvn_build_and_test
#TODO can remove services if this does not work without docker image as base image
services:
- docker:stable-dind
#set variables for use later when running maven in script section
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
script:
#ONLY RUN WHEN MERGE REQUEST IS TO MASTER BRANCH
#if ["$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" == "master"]; then
#check docker is installed and running
#- docker --version #this fails if uncommented
- mvn $MAVEN_CLI_OPTS clean install -Pintegration-test-profile
#; fi
#only:
#- merge_requests
Here is the error stack trace on gitlab:
org.testcontainers.containers.ContainerLaunchException: Container startup failed
1958 Caused by: org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageNameFuture=java.util.concurrent.CompletableFuture#21baa903[Completed normally], imagePullPolicy=DefaultPullPolicy(), dockerClient=LazyDockerClient.INSTANCE)
1959 Caused by: java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration
Before anyone suggests it, this testing works locally (and has worked locally for a long time). Here is part of the sample output:
[INFO] --- maven-failsafe-plugin:2.22.1:integration-test (integration-tests) # reading-comprehension-api ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.connor.retrieving.GetByIsbnIT
-----content ommitted for brevity----------------------------
Tests run: 3, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 10.451 s - in com.connor.adding.AddAssessmentIT
--content ommitted, but test containers start
[INFO] --- maven-failsafe-plugin:2.22.1:verify (integration-tests) # reading-comprehension-api ---
[INFO]
[INFO] --- maven-cucumber-reporting:2.8.0:generate (addCucumberReport) # reading-comprehension-api ---
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
[INFO] About to generate Cucumber report.
[INFO]
[INFO] --- maven-cucumber-reporting:2.8.0:generate (getCucumberReport) # reading-comprehension-api ---
[INFO] About to generate Cucumber report.
[INFO]
[INFO] --- maven-cucumber-reporting:2.8.0:generate (updateCucumberReport) # reading-comprehension-api ---
[INFO] About to generate Cucumber report.
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) # reading-comprehension-api ---
[INFO] Installing /home/connor/Desktop/code/reading-comprehension-api/target/reading-comprehension-api-0.0.1-SNAPSHOT.jar to /home/connor/.m2/repository/com/connor/reading-comprehension-api/0.0.1-SNAPSHOT/reading-comprehension-api-0.0.1-SNAPSHOT.jar
[INFO] Installing /home/connor/Desktop/code/reading-comprehension-api/pom.xml to /home/connor/.m2/repository/com/connor/reading-comprehension-api/0.0.1-SNAPSHOT/reading-comprehension-api-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 38.282 s
[INFO] Finished at: 2019-12-04T22:31:23-05:00
How should i fix this? Should i create my own base image which has maven and docker installed? Can I easily modify my container to use apt get in my container? Any suggestions are welcome, but I would like to have both docker and maven, since they are in my technology stack and working--just a gitlab config issue.
Here is the project location on gitlab: https://gitlab.com/connorbutch/reading-comprehension-api
While i certainly welcome comments on other parts of the project, those should be directed to me via email,in order to keep this page clean (don't put them here)
For anyone who's wondering: You can fix this by adding a few variables to your CI/CD configuration.
The ones I added were:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
#these were added to try and get test containers to work -- if it doesnt, can remove below two
DOCKER_HOST: "tcp://docker:2375"
DOCKER_DRIVER: "overlay2"
For anyone who's are running kubernetes runners the runner must be configured privileged to run dind service:
runners:
## Run all containers with the privileged flag enabled
## This will allow the docker:stable-dind image to run if you need to run Docker
## commands. Please read the docs before turning this on:
## ref: https://docs.gitlab.com/runner/executors/kubernetes.html#using-docker-dind
##
privileged: true
https://docs.gitlab.com/runner/install/kubernetes.html#running-privileged-containers-for-the-runners
Example from values.yaml

how to get a jar build in docker maven to my local repository

I use a docker image of maven to build this custom Scribe, the simple OAuth Java lib
Scribe OAuth Java lib
[INFO] Installing /usr/src/app/target/scribe-1.2.3.oauth.jar to /root/.m2/repository/org/scribe/scribe/1.2.3.oauth/scribe-1.2.3.oauth.jar
[INFO] Installing /usr/src/app/pom.xml to /root/.m2/repository/org/scribe/scribe/1.2.3.oauth/scribe-1.2.3.oauth.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.309 s
[INFO] Finished at: 2017-01-26T15:06:12+00:00
[INFO] Final Memory: 16M/41M
[INFO] ------------------------------------------------------------------------
using this
docker build -t my-maven .
The image build creates the scribe-1.2.3.oauth.jar perfectly. But i need this jar file to build the following project
Alfresco Share OAuth SSO Support
How can i get the jar file from the first build and use it in a local repository for my next build where i again want to use a docker maven to build that project
Left the jar build process out of the docker image build.
Why?
Because a better way to do this is making the maven docker image act as a single command:
docker run -it --rm --name my-maven-project -v "$PWD":/usr/src/mymaven -w /usr/src/mymaven maven:3.2-jdk-7 mvn clean install
I've taken the above example from the maven docker image documentation.
The -v flag attach a local directory to docker image which act as a mount point inside the docker image.
The -w flag indicates to maven where outputs the compiled jar project.

Resources