Prototype of a simple buildpack (https://buildpacks.io/) client for java.
This project represents a simple implementation of the buildpack platform spec, and can be used to build projects using specified buildpacks.
The client uses the combined creator
lifecycle phase from the buildpack to
drive the entire build. A fluent interface is provided to allow creation & configuration
of the build to be performed.
A very simple build can be performed with as little as.
Buildpack.builder()
.withContent(new File("/home/user/java-project"))
.withFinalImage("test/testimage:latest")
.build();
This will use the default builder image from (https://paketo.io) to handle the build
of the project in the /home/user/java-project
folder. The resulting image will
be stored in the local docker daemon as test/testimage:latest
.
The BuildpackBuilder
offers other configuration methods to customise behavior.
- run/build Image can be specified
- docker socket location can be configured
- cache volume names for build/launch can be specified, and optionally auto deleted after the build
creator
debug level can be set- pull timeout can be configured in seconds
Options exist, but are not (yet) active, for.
- use docker registry instead of daemon (requires additional auth config, not implemented yet)
- passing Env content to the build stage (not implemented yet)
A variety of methods are supported for adding content to be build, content is combined in the order passed, allowing for sparse source directories, or multiple project dirs to be combined.
- File/Directory, with prefix. Eg, take this directory /home/fish/wibble, and make it appear in the application content as /prodcode
- String Content, with path. Eg, take this String content "FISH" and make it appear in the application content as /prodcode/fish.txt
- InputStream Content, with path. Similar to String, except with data pulled from an InputStream.
ContainerEntry
interface, for custom integration.
Build/RunImages will be pulled as required.
The builder will use docker via the DOCKER_HOST
env var, if configured, or via the platform appropriate docker socket if not.
Alternatively, dockerHost can be directly configured on the builder itself. If the docker host starts with unix://
the path to the
docker socket is extracted and used during the build phase. If unset, this defaults to /var/run/docker/sock
Want to try out this project? The packages/api are not fixed in stone yet, so be aware! But here are the basic steps to get you up and running.
- Add this project as a dependency via jitpack.
<dependency>
<groupId>dev.snowdrop</groupId>
<artifactId>buildpack-client</artifactId>
<version>0.0.6</version>
</dependency>
- Instantiate a BuildpackBuilder
BuildpackBuilder bpb = Buildpack.builder();
- Define the content to be built..
bpb = bpb.addNewFileContent(new File("/path/to/the/project/to/build));
- Configure the name/tags for the image to create
bpb = bpb.withFinalImage("myorg/myimage:mytag");
- Invoke the build
bpb.build();
Or combine all the above steps into a single callchain.
Buildpack.builder()
.withFileContent(new File("/path/to/the/project/to/build))
.withFinalImage("myorg/myimage:mytag")
.build();
There are many more ways to customize & configure the BuildpackBuilder, take a look at the interface to see everything thats currently possible.
A demo project has been created to play with the Java BuildpackBuilder
here :-)
Most likely if you are using this to integrate to existing tooling, you will want to supply a custom LogReader to receive the messages output by BuildPacks during the build. You may also want to associate cache names to a project, to enable faster rebuilds for a given project.
Output from the Buildpack execution is available via the dev.snowdrop.buildpack.Logger
interface, which can be optionally be passed using the builder.
At the moment two kinds of logger are supported:
- SystemLogger (default)
- Slf4jLogger
Both can be configured using the builder:
Buildpack.builder()
.withContent(new File("."))
.withFinalImage("test/my-image:latest")
.withLogger(new SystemLogger())
.build();
or
Buildpack.builder()
.withContent(new File("."))
.withFinalImage("test/my-image:latest")
.withLogger(new Slf4jLogger())
.build();
The builder DSL supports inlining Logger
configuration:
Buildpack.builder()
.withContent(new File("."))
.withFinalImage("test/my-image:latest")
.withNewSystemLogger(false) //Explicitly disables ansi colors
.build();
The above statement configures system logger with disabled ansi colors.
Similarly, with Slf4jLogger
one can inline the name of the logger:
Buildpack.builder()
.withContent(new File("."))
.withFinalImage("test/my-image:latest")
.withNewSlf4jLogger(MyApp.class.getCanonicalName()) //Explicitly specify the Logger
.build();
The easiest way to invoke arbitrary java code, without much hassle is by using jbang.
So, you can drop the following file in your project:
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS dev.snowdrop:buildpack-client:0.0.6
import static java.lang.System.*;
import java.io.File;
import dev.snowdrop.buildpack.*;
public class pack {
public static void main(String... args) {
Buildpack.builder()
.withContent(new File("."))
.withFinalImage("test/my-image:latest")
.build();
}
}
... and just run it using:
./pack.java
See how it's used in the included samples.
Will this work with Podman?:
Not yet. Once the regular pack
cli works with Podman, I'll revisit this and ensure it works too.
Does this work on Windows?:
Yes.. it's supposed to! Tested with Win10 + Docker on WSL2
Does this work on Linux?:
Yes.. with Docker (real docker, not podman pretending to be docker). Tested with Ubuntu + Docker