Use Docker CLI context to determine daemon host address for image building
Configuration files managed by the Docker CLI are now used to determine the host address of the Docker daemon used when building images using buildpacks when a host address is not configured with environment variables or build tool plugin configuration. Closes gh-36445
This commit is contained in:
@@ -13,7 +13,8 @@ The task is automatically created when the `java` or `war` plugin is applied and
|
||||
[[build-image.docker-daemon]]
|
||||
== Docker Daemon
|
||||
The `bootBuildImage` task requires access to a Docker daemon.
|
||||
By default, it will communicate with a Docker daemon over a local connection.
|
||||
The task will inspect local Docker CLI https://docs.docker.com/engine/reference/commandline/cli/#configuration-files[configuration files] to determine the current https://docs.docker.com/engine/context/working-with-contexts/[context] and use the context connection information to communicate with a Docker daemon.
|
||||
If the current context can not be determined or the context does not have connection information, then the task will use a default 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 an alternative local or remote connection.
|
||||
@@ -22,6 +23,12 @@ The following table shows the environment variables and their values:
|
||||
|===
|
||||
| Environment variable | Description
|
||||
|
||||
| DOCKER_CONFIG
|
||||
| Location of Docker CLI https://docs.docker.com/engine/reference/commandline/cli/#configuration-files[configuration files] used to determine the current context (defaults to `$HOME/.docker`)
|
||||
|
||||
| DOCKER_CONTEXT
|
||||
| Name of a https://docs.docker.com/engine/context/working-with-contexts/[context] that should be used to retrieve host information from Docker CLI configuration files (overrides `DOCKER_HOST`)
|
||||
|
||||
| DOCKER_HOST
|
||||
| URL containing the host and port for the Docker daemon - for example `tcp://192.168.99.100:2376`
|
||||
|
||||
@@ -38,6 +45,9 @@ The following table summarizes the available properties:
|
||||
|===
|
||||
| Property | Description
|
||||
|
||||
| `context`
|
||||
| Name of a https://docs.docker.com/engine/context/working-with-contexts/[context] that should be used to retrieve host information from Docker CLI https://docs.docker.com/engine/reference/commandline/cli/#configuration-files[configuration files]
|
||||
|
||||
| `host`
|
||||
| URL containing the host and port for the Docker daemon - for example `tcp://192.168.99.100:2376`
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
@@ -54,6 +54,10 @@ public abstract class DockerSpec {
|
||||
this.publishRegistry = publishRegistry;
|
||||
}
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getContext();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getHost();
|
||||
@@ -124,7 +128,15 @@ public abstract class DockerSpec {
|
||||
}
|
||||
|
||||
private DockerConfiguration customizeHost(DockerConfiguration dockerConfiguration) {
|
||||
String context = getContext().getOrNull();
|
||||
String host = getHost().getOrNull();
|
||||
if (context != null && host != null) {
|
||||
throw new GradleException(
|
||||
"Invalid Docker configuration, either context or host can be provided but not both");
|
||||
}
|
||||
if (context != null) {
|
||||
return dockerConfiguration.withContext(context);
|
||||
}
|
||||
if (host != null) {
|
||||
return dockerConfiguration.withHost(host, getTlsVerify().get(), getCertPath().getOrNull());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerHost;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.gradle.junit.GradleProjectBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -68,10 +68,11 @@ class DockerSpecTests {
|
||||
this.dockerSpec.getTlsVerify().set(true);
|
||||
this.dockerSpec.getCertPath().set("/tmp/ca-cert");
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHost host = dockerConfiguration.getHost();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isTrue();
|
||||
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(host.getContext()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
@@ -85,10 +86,29 @@ class DockerSpecTests {
|
||||
void asDockerConfigurationWithHostConfigurationNoTlsVerify() {
|
||||
this.dockerSpec.getHost().set("docker.example.com");
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHost host = dockerConfiguration.getHost();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
assertThat(host.getContext()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
.contains("\"serveraddress\" : \"\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
void asDockerConfigurationWithContextConfiguration() {
|
||||
this.dockerSpec.getContext().set("test-context");
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getContext()).isEqualTo("test-context");
|
||||
assertThat(host.getAddress()).isNull();
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
@@ -98,12 +118,20 @@ class DockerSpecTests {
|
||||
.contains("\"serveraddress\" : \"\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
void asDockerConfigurationWithHostAndContextFails() {
|
||||
this.dockerSpec.getContext().set("test-context");
|
||||
this.dockerSpec.getHost().set("docker.example.com");
|
||||
assertThatExceptionOfType(GradleException.class).isThrownBy(this.dockerSpec::asDockerConfiguration)
|
||||
.withMessageContaining("Invalid Docker configuration");
|
||||
}
|
||||
|
||||
@Test
|
||||
void asDockerConfigurationWithBindHostToBuilder() {
|
||||
this.dockerSpec.getHost().set("docker.example.com");
|
||||
this.dockerSpec.getBindHostToBuilder().set(true);
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHost host = dockerConfiguration.getHost();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
|
||||
Reference in New Issue
Block a user