3

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]
Rod McCutcheon
  • 201
  • 4
  • 21

2 Answers2

2

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.

Brian de Alwis
  • 2,814
  • 2
  • 18
  • 32
  • thanks! I got it working eventually without the need to run the docker push - I think I need to run ```eval $(minikube docker-env)``` – Rod McCutcheon Nov 20 '20 at 00:27
  • Running `eval $(minikube docker-env)` ensures that Skaffold will build using Minikube's packaged docker daemon (not your local docker daemon). Minikube uses images from its own docker daemon when present. You shouldn't have needed to run that eval expression though as Skaffold normally detects that you're using minikube and configures itself with the values from running `minikube docker-env`. If you're interested in diagnosing this further, please open an issue at https://github.com/GoogleContainerTools/skaffold/issues/new and include a log of running `skaffold build -v debug`. – Brian de Alwis Nov 26 '20 at 20:55
0

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.

jonashackt
  • 12,022
  • 5
  • 67
  • 124