mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Support podman for building images
Closes gh-30196
This commit is contained in:
parent
7ad538cd84
commit
de321b00b7
@ -187,7 +187,7 @@ public class DockerApi {
|
||||
listener.onUpdate(event);
|
||||
});
|
||||
}
|
||||
return inspect(reference.withDigest(digestCapture.getCapturedDigest()));
|
||||
return inspect(reference);
|
||||
}
|
||||
finally {
|
||||
listener.onFinish();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -61,6 +61,8 @@ public class ImageArchive implements TarArchive {
|
||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ISO_ZONED_DATE_TIME
|
||||
.withZone(ZoneOffset.UTC);
|
||||
|
||||
private static final String EMPTY_LAYER_NAME_PREFIX = "blank_";
|
||||
|
||||
private static final IOConsumer<Update> NO_UPDATES = (update) -> {
|
||||
};
|
||||
|
||||
@ -125,6 +127,9 @@ public class ImageArchive implements TarArchive {
|
||||
}
|
||||
|
||||
private List<LayerId> writeLayers(Layout writer) throws IOException {
|
||||
for (int i = 0; i < this.existingLayers.size(); i++) {
|
||||
writeEmptyLayer(writer, EMPTY_LAYER_NAME_PREFIX + i);
|
||||
}
|
||||
List<LayerId> writtenLayers = new ArrayList<>();
|
||||
for (Layer layer : this.newLayers) {
|
||||
writtenLayers.add(writeLayer(writer, layer));
|
||||
@ -132,9 +137,13 @@ public class ImageArchive implements TarArchive {
|
||||
return Collections.unmodifiableList(writtenLayers);
|
||||
}
|
||||
|
||||
private void writeEmptyLayer(Layout writer, String name) throws IOException {
|
||||
writer.file(name, Owner.ROOT, Content.of(""));
|
||||
}
|
||||
|
||||
private LayerId writeLayer(Layout writer, Layer layer) throws IOException {
|
||||
LayerId id = layer.getId();
|
||||
writer.file("/" + id.getHash() + ".tar", Owner.ROOT, layer);
|
||||
writer.file(id.getHash() + ".tar", Owner.ROOT, layer);
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -144,7 +153,7 @@ public class ImageArchive implements TarArchive {
|
||||
String json = this.objectMapper.writeValueAsString(config).replace("\r\n", "\n");
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
InspectedContent content = InspectedContent.of(Content.of(json), digest::update);
|
||||
String name = "/" + LayerId.ofSha256Digest(digest.digest()).getHash() + ".json";
|
||||
String name = LayerId.ofSha256Digest(digest.digest()).getHash() + ".json";
|
||||
writer.file(name, Owner.ROOT, content);
|
||||
return name;
|
||||
}
|
||||
@ -187,7 +196,7 @@ public class ImageArchive implements TarArchive {
|
||||
private void writeManifest(Layout writer, String config, List<LayerId> writtenLayers) throws IOException {
|
||||
ArrayNode manifest = createManifest(config, writtenLayers);
|
||||
String manifestJson = this.objectMapper.writeValueAsString(manifest);
|
||||
writer.file("/manifest.json", Owner.ROOT, Content.of(manifestJson));
|
||||
writer.file("manifest.json", Owner.ROOT, Content.of(manifestJson));
|
||||
}
|
||||
|
||||
private ArrayNode createManifest(String config, List<LayerId> writtenLayers) {
|
||||
@ -204,7 +213,7 @@ public class ImageArchive implements TarArchive {
|
||||
private ArrayNode getManifestLayers(List<LayerId> writtenLayers) {
|
||||
ArrayNode layers = this.objectMapper.createArrayNode();
|
||||
for (int i = 0; i < this.existingLayers.size(); i++) {
|
||||
layers.add("");
|
||||
layers.add(EMPTY_LAYER_NAME_PREFIX + i);
|
||||
}
|
||||
writtenLayers.stream().map((id) -> id.getHash() + ".tar").forEach(layers::add);
|
||||
return layers;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -58,6 +58,8 @@ import static org.assertj.core.api.Assertions.entry;
|
||||
*/
|
||||
class EphemeralBuilderTests extends AbstractJsonTests {
|
||||
|
||||
private static final int EXISTING_IMAGE_LAYER_COUNT = 43;
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
@ -131,7 +133,7 @@ class EphemeralBuilderTests extends AbstractJsonTests {
|
||||
void getArchiveContainsEnvLayer() throws Exception {
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
|
||||
this.creator, this.env, this.buildpacks);
|
||||
File directory = unpack(getLayer(builder.getArchive(), 0), "env");
|
||||
File directory = unpack(getLayer(builder.getArchive(), EXISTING_IMAGE_LAYER_COUNT), "env");
|
||||
assertThat(new File(directory, "platform/env/spring")).usingCharset(StandardCharsets.UTF_8).hasContent("boot");
|
||||
assertThat(new File(directory, "platform/env/empty")).usingCharset(StandardCharsets.UTF_8).hasContent("");
|
||||
}
|
||||
@ -154,10 +156,13 @@ class EphemeralBuilderTests extends AbstractJsonTests {
|
||||
this.buildpacks = Buildpacks.of(buildpackList);
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.targetImage, this.metadata,
|
||||
this.creator, null, this.buildpacks);
|
||||
assertBuildpackLayerContent(builder, 0, "/cnb/buildpacks/example_buildpack1/0.0.1/buildpack.toml");
|
||||
assertBuildpackLayerContent(builder, 1, "/cnb/buildpacks/example_buildpack2/0.0.2/buildpack.toml");
|
||||
assertBuildpackLayerContent(builder, 2, "/cnb/buildpacks/example_buildpack3/0.0.3/buildpack.toml");
|
||||
File orderDirectory = unpack(getLayer(builder.getArchive(), 3), "order");
|
||||
assertBuildpackLayerContent(builder, EXISTING_IMAGE_LAYER_COUNT,
|
||||
"/cnb/buildpacks/example_buildpack1/0.0.1/buildpack.toml");
|
||||
assertBuildpackLayerContent(builder, EXISTING_IMAGE_LAYER_COUNT + 1,
|
||||
"/cnb/buildpacks/example_buildpack2/0.0.2/buildpack.toml");
|
||||
assertBuildpackLayerContent(builder, EXISTING_IMAGE_LAYER_COUNT + 2,
|
||||
"/cnb/buildpacks/example_buildpack3/0.0.3/buildpack.toml");
|
||||
File orderDirectory = unpack(getLayer(builder.getArchive(), EXISTING_IMAGE_LAYER_COUNT + 3), "order");
|
||||
assertThat(new File(orderDirectory, "cnb/order.toml")).usingCharset(StandardCharsets.UTF_8)
|
||||
.hasContent(content("order.toml"));
|
||||
}
|
||||
|
@ -164,8 +164,7 @@ class DockerApiTests {
|
||||
void pullPullsImageAndProducesEvents() throws Exception {
|
||||
ImageReference reference = ImageReference.of("gcr.io/paketo-buildpacks/builder:base");
|
||||
URI createUri = new URI(IMAGES_URL + "/create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase");
|
||||
String imageHash = "4acb6bfd6c4f0cabaf7f3690e444afe51f1c7de54d51da7e63fac709c56f1c30";
|
||||
URI imageUri = new URI(IMAGES_URL + "/gcr.io/paketo-buildpacks/builder@sha256:" + imageHash + "/json");
|
||||
URI imageUri = new URI(IMAGES_URL + "/gcr.io/paketo-buildpacks/builder:base/json");
|
||||
given(http().post(eq(createUri), isNull())).willReturn(responseOf("pull-stream.json"));
|
||||
given(http().get(imageUri)).willReturn(responseOf("type/image.json"));
|
||||
Image image = this.api.pull(reference, this.pullListener);
|
||||
@ -180,8 +179,7 @@ class DockerApiTests {
|
||||
void pullWithRegistryAuthPullsImageAndProducesEvents() throws Exception {
|
||||
ImageReference reference = ImageReference.of("gcr.io/paketo-buildpacks/builder:base");
|
||||
URI createUri = new URI(IMAGES_URL + "/create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase");
|
||||
String imageHash = "4acb6bfd6c4f0cabaf7f3690e444afe51f1c7de54d51da7e63fac709c56f1c30";
|
||||
URI imageUri = new URI(IMAGES_URL + "/gcr.io/paketo-buildpacks/builder@sha256:" + imageHash + "/json");
|
||||
URI imageUri = new URI(IMAGES_URL + "/gcr.io/paketo-buildpacks/builder:base/json");
|
||||
given(http().post(eq(createUri), eq("auth token"))).willReturn(responseOf("pull-stream.json"));
|
||||
given(http().get(imageUri)).willReturn(responseOf("type/image.json"));
|
||||
Image image = this.api.pull(reference, this.pullListener, "auth token");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -40,6 +40,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class ImageArchiveTests extends AbstractJsonTests {
|
||||
|
||||
private static final int EXISTING_IMAGE_LAYER_COUNT = 46;
|
||||
|
||||
@Test
|
||||
void fromImageWritesToValidArchiveTar() throws Exception {
|
||||
Image image = Image.of(getContent("image.json"));
|
||||
@ -51,13 +53,16 @@ class ImageArchiveTests extends AbstractJsonTests {
|
||||
archive.writeTo(outputStream);
|
||||
try (TarArchiveInputStream tar = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
for (int i = 0; i < EXISTING_IMAGE_LAYER_COUNT; i++) {
|
||||
TarArchiveEntry blankEntry = tar.getNextTarEntry();
|
||||
assertThat(blankEntry.getName()).isEqualTo("blank_" + i);
|
||||
}
|
||||
TarArchiveEntry layerEntry = tar.getNextTarEntry();
|
||||
byte[] layerContent = read(tar, layerEntry.getSize());
|
||||
TarArchiveEntry configEntry = tar.getNextTarEntry();
|
||||
byte[] configContent = read(tar, configEntry.getSize());
|
||||
TarArchiveEntry manifestEntry = tar.getNextTarEntry();
|
||||
byte[] manifestContent = read(tar, manifestEntry.getSize());
|
||||
assertThat(tar.getNextTarEntry()).isNull();
|
||||
assertExpectedLayer(layerEntry, layerContent);
|
||||
assertExpectedConfig(configEntry, configContent);
|
||||
assertExpectedManifest(manifestEntry, manifestContent);
|
||||
@ -65,7 +70,7 @@ class ImageArchiveTests extends AbstractJsonTests {
|
||||
}
|
||||
|
||||
private void assertExpectedLayer(TarArchiveEntry entry, byte[] content) throws Exception {
|
||||
assertThat(entry.getName()).isEqualTo("/bb09e17fd1bd2ee47155f1349645fcd9fff31e1247c7ed99cad469f1c16a4216.tar");
|
||||
assertThat(entry.getName()).isEqualTo("bb09e17fd1bd2ee47155f1349645fcd9fff31e1247c7ed99cad469f1c16a4216.tar");
|
||||
try (TarArchiveInputStream tar = new TarArchiveInputStream(new ByteArrayInputStream(content))) {
|
||||
TarArchiveEntry contentEntry = tar.getNextTarEntry();
|
||||
assertThat(contentEntry.getName()).isEqualTo("/spring/");
|
||||
@ -73,14 +78,14 @@ class ImageArchiveTests extends AbstractJsonTests {
|
||||
}
|
||||
|
||||
private void assertExpectedConfig(TarArchiveEntry entry, byte[] content) throws Exception {
|
||||
assertThat(entry.getName()).isEqualTo("/682f8d24b9d9c313d1190a0e955dcb5e65ec9beea40420999839c6f0cbb38382.json");
|
||||
assertThat(entry.getName()).isEqualTo("682f8d24b9d9c313d1190a0e955dcb5e65ec9beea40420999839c6f0cbb38382.json");
|
||||
String actualJson = new String(content, StandardCharsets.UTF_8);
|
||||
String expectedJson = StreamUtils.copyToString(getContent("image-archive-config.json"), StandardCharsets.UTF_8);
|
||||
JSONAssert.assertEquals(expectedJson, actualJson, false);
|
||||
}
|
||||
|
||||
private void assertExpectedManifest(TarArchiveEntry entry, byte[] content) throws Exception {
|
||||
assertThat(entry.getName()).isEqualTo("/manifest.json");
|
||||
assertThat(entry.getName()).isEqualTo("manifest.json");
|
||||
String actualJson = new String(content, StandardCharsets.UTF_8);
|
||||
String expectedJson = StreamUtils.copyToString(getContent("image-archive-manifest.json"),
|
||||
StandardCharsets.UTF_8);
|
||||
|
@ -1,53 +1,53 @@
|
||||
[
|
||||
{
|
||||
"Config": "/682f8d24b9d9c313d1190a0e955dcb5e65ec9beea40420999839c6f0cbb38382.json",
|
||||
"Config": "682f8d24b9d9c313d1190a0e955dcb5e65ec9beea40420999839c6f0cbb38382.json",
|
||||
"Layers": [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"blank_0",
|
||||
"blank_1",
|
||||
"blank_2",
|
||||
"blank_3",
|
||||
"blank_4",
|
||||
"blank_5",
|
||||
"blank_6",
|
||||
"blank_7",
|
||||
"blank_8",
|
||||
"blank_9",
|
||||
"blank_10",
|
||||
"blank_11",
|
||||
"blank_12",
|
||||
"blank_13",
|
||||
"blank_14",
|
||||
"blank_15",
|
||||
"blank_16",
|
||||
"blank_17",
|
||||
"blank_18",
|
||||
"blank_19",
|
||||
"blank_20",
|
||||
"blank_21",
|
||||
"blank_22",
|
||||
"blank_23",
|
||||
"blank_24",
|
||||
"blank_25",
|
||||
"blank_26",
|
||||
"blank_27",
|
||||
"blank_28",
|
||||
"blank_29",
|
||||
"blank_30",
|
||||
"blank_31",
|
||||
"blank_32",
|
||||
"blank_33",
|
||||
"blank_34",
|
||||
"blank_35",
|
||||
"blank_36",
|
||||
"blank_37",
|
||||
"blank_38",
|
||||
"blank_39",
|
||||
"blank_40",
|
||||
"blank_41",
|
||||
"blank_42",
|
||||
"blank_43",
|
||||
"blank_44",
|
||||
"blank_45",
|
||||
"bb09e17fd1bd2ee47155f1349645fcd9fff31e1247c7ed99cad469f1c16a4216.tar"
|
||||
],
|
||||
"RepoTags": [
|
||||
|
@ -16,7 +16,7 @@ The `bootBuildImage` task requires access to a Docker daemon.
|
||||
By default, it will communicate with a Docker daemon over a local connection.
|
||||
This works with https://docs.docker.com/install/[Docker Engine] on all supported platforms without configuration.
|
||||
|
||||
Environment variables can be set to configure the `bootBuildImage` task to use the https://minikube.sigs.k8s.io/docs/tasks/docker_daemon/[Docker daemon provided by minikube].
|
||||
Environment variables can be set to configure the `bootBuildImage` task to use an alternative local or remote connection.
|
||||
The following table shows the environment variables and their values:
|
||||
|
||||
|===
|
||||
@ -32,8 +32,6 @@ The following table shows the environment variables and their values:
|
||||
| Path to certificate and key files for HTTPS (required if `DOCKER_TLS_VERIFY=1`, ignored otherwise)
|
||||
|===
|
||||
|
||||
On Linux and macOS, these environment variables can be set using the command `eval $(minikube docker-env)` after minikube has been started.
|
||||
|
||||
Docker daemon connection information can also be provided using `docker` properties in the plugin configuration.
|
||||
The following table summarizes the available properties:
|
||||
|
||||
@ -416,7 +414,14 @@ include::../gradle/packaging/boot-build-image-caches.gradle.kts[tags=caches]
|
||||
[[build-image.examples.docker]]
|
||||
=== Docker Configuration
|
||||
|
||||
If you need the plugin to communicate with the Docker daemon using a remote connection instead of the default local connection, the connection details can be provided using `docker` properties as shown in the following example:
|
||||
[[build-image.examples.docker.minikube]]
|
||||
==== Docker Configuration for minikube
|
||||
|
||||
The plugin can communicate with the https://minikube.sigs.k8s.io/docs/tasks/docker_daemon/[Docker daemon provided by minikube] instead of the default local connection.
|
||||
|
||||
On Linux and macOS, environment variables can be set using the command `eval $(minikube docker-env)` after minikube has been started.
|
||||
|
||||
The plugin can also be configured to use the minikube daemon by providing connection details similar to those shown in the following example:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Groovy
|
||||
@ -430,6 +435,28 @@ include::../gradle/packaging/boot-build-image-docker-host.gradle[tags=docker-hos
|
||||
include::../gradle/packaging/boot-build-image-docker-host.gradle.kts[tags=docker-host]
|
||||
----
|
||||
|
||||
[[build-image.examples.docker.podman]]
|
||||
==== Docker Configuration for podman
|
||||
|
||||
The plugin can communicate with a https://podman.io/[podman container engine].
|
||||
|
||||
The plugin can be configured to use podman local connection by providing connection details similar to those shown in the following example:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Groovy
|
||||
----
|
||||
include::../gradle/packaging/boot-build-image-docker-host-podman.gradle[tags=docker-host]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
include::../gradle/packaging/boot-build-image-docker-host-podman.gradle.kts[tags=docker-host]
|
||||
----
|
||||
|
||||
[[build-image.examples.docker.auth]]
|
||||
==== Docker Configuration for Authentication
|
||||
|
||||
If the builder or run image are stored in a private Docker registry that supports user authentication, authentication details can be provided using `docker.builderRegistry` properties as shown in the following example:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
|
@ -0,0 +1,24 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{gradle-project-version}'
|
||||
}
|
||||
|
||||
tasks.named("bootJar") {
|
||||
mainClass = 'com.example.ExampleApplication'
|
||||
}
|
||||
|
||||
// tag::docker-host[]
|
||||
tasks.named("bootBuildImage") {
|
||||
docker {
|
||||
host = "unix:///run/user/1000/podman/podman.sock"
|
||||
bindHostToBuilder = true
|
||||
}
|
||||
}
|
||||
// end::docker-host[]
|
||||
|
||||
tasks.register("bootBuildImageDocker") {
|
||||
doFirst {
|
||||
println("host=${tasks.bootBuildImage.docker.host}")
|
||||
println("bindHostToBuilder=${tasks.bootBuildImage.docker.bindHostToBuilder}")
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootBuildImage
|
||||
|
||||
plugins {
|
||||
java
|
||||
id("org.springframework.boot") version "{gradle-project-version}"
|
||||
}
|
||||
|
||||
tasks.named<BootJar>("bootJar") {
|
||||
mainClass.set("com.example.ExampleApplication")
|
||||
}
|
||||
|
||||
// tag::docker-host[]
|
||||
tasks.named<BootBuildImage>("bootBuildImage") {
|
||||
docker {
|
||||
host = "unix:///run/user/1000/podman/podman.sock"
|
||||
isBindHostToBuilder = true
|
||||
}
|
||||
}
|
||||
// end::docker-host[]
|
||||
|
||||
tasks.register("bootBuildImageDocker") {
|
||||
doFirst {
|
||||
println("host=${tasks.getByName<BootBuildImage>("bootBuildImage").docker.host}")
|
||||
println("bindHostToBuilder=${tasks.getByName<BootBuildImage>("bootBuildImage").docker.isBindHostToBuilder}")
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ tasks.named("bootBuildImage") {
|
||||
docker {
|
||||
host = "tcp://192.168.99.100:2376"
|
||||
tlsVerify = true
|
||||
certPath = "/home/users/.minikube/certs"
|
||||
certPath = "/home/user/.minikube/certs"
|
||||
}
|
||||
}
|
||||
// end::docker-host[]
|
||||
|
@ -15,7 +15,7 @@ tasks.named<BootBuildImage>("bootBuildImage") {
|
||||
docker {
|
||||
host = "tcp://192.168.99.100:2376"
|
||||
isTlsVerify = true
|
||||
certPath = "/home/users/.minikube/certs"
|
||||
certPath = "/home/user/.minikube/certs"
|
||||
}
|
||||
}
|
||||
// end::docker-host[]
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -279,11 +279,19 @@ class PackagingDocumentationTests {
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void bootBuildImageWithDockerHost() {
|
||||
void bootBuildImageWithDockerHostMinikube() {
|
||||
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-docker-host")
|
||||
.build("bootBuildImageDocker");
|
||||
assertThat(result.getOutput()).contains("host=tcp://192.168.99.100:2376").contains("tlsVerify=true")
|
||||
.contains("certPath=/home/users/.minikube/certs");
|
||||
.contains("certPath=/home/user/.minikube/certs");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void bootBuildImageWithDockerHostPodman() {
|
||||
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-docker-host-podman")
|
||||
.build("bootBuildImageDocker");
|
||||
assertThat(result.getOutput()).contains("host=unix:///run/user/1000/podman/podman.sock")
|
||||
.contains("bindHostToBuilder=true");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
|
@ -25,7 +25,7 @@ The `build-image` goal requires access to a Docker daemon.
|
||||
By default, it will communicate with a Docker daemon over a local connection.
|
||||
This works with https://docs.docker.com/install/[Docker Engine] on all supported platforms without configuration.
|
||||
|
||||
Environment variables can be set to configure the `build-image` goal to use the https://minikube.sigs.k8s.io/docs/tasks/docker_daemon/[Docker daemon provided by minikube].
|
||||
Environment variables can be set to configure the `build-image` goal to use an alternative local or remote connection.
|
||||
The following table shows the environment variables and their values:
|
||||
|
||||
|===
|
||||
@ -41,8 +41,6 @@ The following table shows the environment variables and their values:
|
||||
| Path to certificate and key files for HTTPS (required if `DOCKER_TLS_VERIFY=1`, ignored otherwise)
|
||||
|===
|
||||
|
||||
On Linux and macOS, these environment variables can be set using the command `eval $(minikube docker-env)` after minikube has been started.
|
||||
|
||||
Docker daemon connection information can also be provided using `docker` parameters in the plugin configuration.
|
||||
The following table summarizes the available parameters:
|
||||
|
||||
@ -372,13 +370,35 @@ include::../maven/packaging-oci-image/caches-pom.xml[tags=caches]
|
||||
[[build-image.examples.docker]]
|
||||
=== Docker Configuration
|
||||
|
||||
If you need the plugin to communicate with the Docker daemon using a remote connection instead of the default local connection, the connection details can be provided using `docker` parameters as shown in the following example:
|
||||
[[build-image.examples.docker.minikube]]
|
||||
==== Docker Configuration for minikube
|
||||
|
||||
The plugin can communicate with the https://minikube.sigs.k8s.io/docs/tasks/docker_daemon/[Docker daemon provided by minikube] instead of the default local connection.
|
||||
|
||||
On Linux and macOS, environment variables can be set using the command `eval $(minikube docker-env)` after minikube has been started.
|
||||
|
||||
The plugin can also be configured to use the minikube daemon by providing connection details similar to those shown in the following example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
|
||||
----
|
||||
include::../maven/packaging-oci-image/docker-remote-pom.xml[tags=docker-remote]
|
||||
include::../maven/packaging-oci-image/docker-minikube-pom.xml[tags=docker-minikube]
|
||||
----
|
||||
|
||||
[[build-image.examples.docker.podman]]
|
||||
==== Docker Configuration for podman
|
||||
|
||||
The plugin can communicate with a https://podman.io/[podman container engine].
|
||||
|
||||
The plugin can be configured to use podman local connection by providing connection details similar to those shown in the following example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
|
||||
----
|
||||
include::../maven/packaging-oci-image/docker-podman-pom.xml[tags=docker-podman]
|
||||
----
|
||||
|
||||
[[build-image.examples.docker.auth]]
|
||||
==== Docker Configuration for Authentication
|
||||
|
||||
If the builder or run image are stored in a private Docker registry that supports user authentication, authentication details can be provided using `docker.builderRegistry` parameters as shown in the following example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- tag::docker-remote[] -->
|
||||
<!-- tag::docker-minikube[] -->
|
||||
<project>
|
||||
<build>
|
||||
<plugins>
|
||||
@ -17,5 +17,5 @@
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<!-- end::docker-remote[] -->
|
||||
<!-- end::docker-minikube[] -->
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- tag::docker-podman[] -->
|
||||
<project>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<docker>
|
||||
<host>unix:///run/user/1000/podman/podman.sock</host>
|
||||
<bindHostToBuilder>true</bindHostToBuilder>
|
||||
</docker>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<!-- end::docker-podman[] -->
|
||||
|
Loading…
Reference in New Issue
Block a user