Skip to main content

Spring Boot native builds when internet downloads are blocked made simple

 No direct access to the internet

If you work at a company that controls their software bill of materials, it's quite common to be blocked from directly downloading from:
  • Maven Central
  • Docker hub
  • GitHub (the public parts)

Getting the bits

Maven

Maven is first, because without it, you won't be able to compile your Spring Boot application, let alone move on to turning it into a native docker image.

I will be showing changes need to work with artifactory, but you should be able to adapt it to other mirror solutions. 

repositories {
  maven {
    name = "central"
    url = "https://artifactory.example.com/central"
    credentials {
      username = "${project.ext.properties.artifactory_username}"
      password = "${project.ext.properties.artifactory_apikey}"
    }
  }
}

With this configuration change, you should be able to download your plugins and dependencies, allowing you to compile and run your application in the JDK.

Docker Hub

Docker hub is next because the Spring Boot target bootBuildImage, requires two docker images:
  1. A builder image - this is the image that will be used to create a native image from your class and jar files.
  2. A runtime image - this is the base image that your resulting executable will be added to.
I'm going to again show my configuration assuming artifactory, but again the concept should work with any other similar mirroring technologies.

bootBuildImage {
  docker {
    builderRegistry {
      url = 'docker-hub.artifactory.example.com'
      username = "${project.ext.properties.artifactory_username}"
      password = "${project.ext.properties.artifactory_apikey}"
    }
  }
  pullPolicy='NEVER'
  builder='docker-hub.artifactory.example.com/paketobuildpacks/builder-jammy-tiny:latest'
  runImage='docker-hub.artifactory.example.com/paketobuildpacks/run-jammy-tiny:latest'
  imageName='my-built-image-name:tagit'
}

A couple of comments are in order here:
  • The pull policy of NEVER allows you to know exactly which images you are using.  Then if your company wants or needs you to use something different, you know what is needed.  For a CI/CD environment you would not want that configuration, but for just getting started it works.
  • You will want to inject the tags, both for the versions you are using to build and run, but also the image you will be publishing.  But this is the simple way to get you started.

GitHub

The default buildpacks to create a native image requires two internet downloads from GitHub.  If your company blocks those downloads, it's a two step process for the simple solution:
  1. Acquire the downloads for the bellsoft liberica and syft tar.gz files in some company approved way and add them to your project (I'm using ./buildpacks) so I ended up with two directory trees.
    1. ./buildpacks/bell-sw/LibericaNIK/releases/download/23.1.3+2-21.0.3+10/bellsoft-liberica-vm-core-openjdk21.0.3+10-23.1.3+2-linux-amd64.tar.gz
    2. ./buildpacks/anchore/syft/releases/download/v0.105.1/syft_0.105.1_linux_amd64.tar.gz
  2. Add the Gradle config to not go to GitHub:
tasks.named("bootBuildImage") {
  environment["BP_DEPENDENCY_MIRROR"]="file:///buildpacks"
  bindings = ["${project.projectDir}/buildpacks:/buildpacks"]
  environment["BP_LOG_LEVEL"]="DEBUG"
}

A few comments here as well:
  • I'm showing a second way of adjusting the bootBuildImage task - you will see both out on the internet and they both can be used.
  • Long term, having a complete JDK in your project adds a lot of overhead and management complexities.  You can also set your mirror to "https://" and a web site; however, then you probably also have to deal with custom certificates and running the buildpacks in a particular order to inject those certificates into the builder image.  Again, this is the simple, not final solution.

Comments

Popular posts from this blog

Kotlin Notebook when you're blocked from Maven Central

 TLDR; If you are blocked getting to maven central when first using Kotlin Notebooks because of company firewalls, you can use a tool like Fiddler Tool to redirect to a different network location. Kotlin Notebooks Kotlin Notebooks are a JDK based environment that brings the Python based Jupyter Notebooks  expressiveness to IntelliJ. From the blog post announcing the plugin, it looks like this: At home, the installation of jar files looked like this: I played around with it at home, but I couldn't use it at work.  Many companies, mine included, do not allow software components to be used when downloaded directly from the internet. In my companies case, we use a product called Artifactory, which allows you to mirror the content from Maven Central while still applying policies like CVE scanning, tracking, etc. The way it should work IntelliJ, as one of the leading IDE's, generally supports this quite well.  In fact, there is a whole setting page dedicated to dealing wi...

Active vs. Passive Log4jShell remediation

 Log4jShell  All computer professionals should be aware of the Log4jShell ( CVE-2021-44228 ) and it follow on defects.  There is no shortage of opinions and lessons to be be learned: The difficulty of performing safe interpretation The problems when assumptions are not clearly documented.  I, for one, was completely shocked to find out that a logging system would actually attempt to do variable substitution in an actual message. The difficulty of finding and resolving issues with such a common library that is not provided by an OS package manager. IT'S A LOG4J CHRISTMAS One of my favorite podcasts, Security Now - episode 850 , discussed an analysis by Google regarding the depth of log4j dependencies.  From the show notes : One contributing reason is because Log4j is, more often than not, an indirect dependency. Java libraries are built by writing some code which uses functions from other Java libraries, which are built by writing some code which uses functions f...