Repository: docker-java/docker-java
Pull request #447 (2016-02-02 16:46:36)

Refactoring of DockerClientConfig
This PR addresses issue #331. Additionally it renames all the config options/keys of docker-java to  better match with the docker CLI environment options.


Patch:
diff --git a/README.md b/README.md
index 26ec653a..0b519d0f 100644
--- a/README.md
+++ b/README.md
@@ -85,13 +85,15 @@ For code examples, please look at the [Wiki](https://github.com/docker-java/dock
 
 There are a couple of configuration items, all of which have sensible defaults:
 
-* `url` The Docker URL, e.g. `https://localhost:2376` or `unix:///var/run/docker.sock`
-* `version` The API version, e.g. `1.16`.
-* `username` Your registry username (required to push containers).
-* `password` Your registry password.
-* `email` Your registry email.
-* `serverAddress` Your registry's address.
-* `dockerCertPath` Path to the docker certs.
+* `DOCKER_HOST` The Docker Host URL, e.g. `tcp://localhost:2376` or `unix:///var/run/docker.sock`
+* `DOCKER_TLS_VERIFY` enable/disable TLS verification (switch between `http` and `https` protocol)
+* `DOCKER_CERT_PATH` Path to the certificates needed for TLS verification
+* `DOCKER_CONFIG` Path for additional docker configuration files (like `.dockercfg`)
+* `api.version` The API version, e.g. `1.21`.
+* `registry.url` Your registry's address.
+* `registry.username` Your registry username (required to push containers).
+* `registry.password` Your registry password.
+* `registry.email` Your registry email.
 
 There are three ways to configure, in descending order of precedence:
 
@@ -99,42 +101,46 @@ There are three ways to configure, in descending order of precedence:
 In your application, e.g.
 
     DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder()
-        .withVersion("1.16")
-        .withUri("https://my-docker-host.tld:2376")
-        .withUsername("dockeruser")
-        .withPassword("ilovedocker")
-        .withEmail("dockeruser@github.com")
-        .withServerAddress("https://index.docker.io/v1/")
-        .withDockerCertPath("/home/user/.docker")
+        .withDockerHost("tcp://my-docker-host.tld:2376")
+        .withDockerTlsVerify(true)
+        .withDockerCertPath("/home/user/.docker/certs")
+        .withDockerConfig("/home/user/.docker")
+        .withApiVersion("1.21")
+        .withRegistryUrl("https://index.docker.io/v1/")
+        .withRegistryUsername("dockeruser")
+        .withRegistryPassword("ilovedocker")
+        .withRegistryEmail("dockeruser@github.com")
         .build();
     DockerClient docker = DockerClientBuilder.getInstance(config).build();
 
-#### Properties
-
-    docker.io.url=https://localhost:2376
-    docker.io.version=1.16
-    docker.io.username=dockeruser
-    docker.io.password=ilovedocker
-    docker.io.email=dockeruser@github.com
-    docker.io.serverAddress=https://index.docker.io/v1/
-    docker.io.dockerCertPath=/home/user/.docker
+#### Properties (docker-java.properties)
 
+    DOCKER_HOST=tcp://localhost:2376
+    DOCKER_TLS_VERIFY=1
+    DOCKER_CERT_PATH=/home/user/.docker/certs
+    DOCKER_CONFIG=/home/user/.docker
+    api.version=1.21
+    registry.url=https://index.docker.io/v1/
+    registry.username=dockeruser
+    registry.password=ilovedocker
+    registry.email=dockeruser@github.com
 
 ##### System Properties:
 
-    java -Ddocker.io.username=dockeruser pkg.Main
+    java -Dregistry.username=dockeruser pkg.Main
 
 ##### System Environment
 
-    export DOCKER_URL=http://localhost:2376
-
-Note: we also auto-detect defaults. If you use `DOCKER_HOST` we use that value, and if `DOCKER_CERT_PATH` or `DOCKER_TLS_VERIFY=1` is set, we switch to SSL.
+    export DOCKER_URL=tcp://localhost:2376
+    export DOCKER_TLS_VERIFY=1
+    export DOCKER_CERT_PATH=/home/user/.docker/certs
+    export DOCKER_CONFIG=/home/user/.docker
 
 ##### File System
 
-In `$HOME/.docker.io.properties`
+In `$HOME/.docker-java.properties`
 
 ##### Class Path
 
-In the class path at `/docker.io.properties`
+In the class path at `/docker-java.properties`
     
diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
index fb1715e3..fc793558 100644
--- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
+++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
@@ -3,6 +3,8 @@ package com.github.dockerjava.api.command;
 import java.io.Closeable;
 import java.io.IOException;
 
+import javax.net.ssl.SSLContext;
+
 import com.github.dockerjava.core.DockerClientConfig;
 
 public interface DockerCmdExecFactory extends Closeable {
@@ -105,6 +107,8 @@ public interface DockerCmdExecFactory extends Closeable {
 
     public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec();
 
+    public DockerCmdExecFactory withSSLContext(SSLContext sslContext);
+
     @Override
     public void close() throws IOException;
 
diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java
index fa5c77e6..12d09664 100644
--- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java
+++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java
@@ -8,10 +8,17 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.net.URI;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
 
 import com.github.dockerjava.api.exception.DockerClientException;
 import com.github.dockerjava.api.model.AuthConfig;
@@ -19,74 +26,107 @@ import com.github.dockerjava.api.model.AuthConfigurations;
 import com.github.dockerjava.core.NameParser.HostnameReposName;
 import com.github.dockerjava.core.NameParser.ReposTag;
 
+/**
+ * Respects some of the docker CLI options. See https://docs.docker.com/engine/reference/commandline/cli/#environment-variables
+ */
 public class DockerClientConfig implements Serializable {
 
     private static final long serialVersionUID = -4307357472441531489L;
 
-    private static final String DOCKER_HOST_PROPERTY = "DOCKER_HOST";
+    public static final String DOCKER_HOST = "DOCKER_HOST";
 
-    private static final String DOCKER_CERT_PATH_PROPERTY = "DOCKER_CERT_PATH";
+    public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY";
 
-    private static final String DOCKER_VERIFY_TLS_PROPERTY = "DOCKER_TLS_VERIFY";
+    public static final String DOCKER_CONFIG = "DOCKER_CONFIG";
 
-    private static final String DOCKER_IO_URL_PROPERTY = "docker.io.url";
+    public static final String DOCKER_CERT_PATH = "DOCKER_CERT_PATH";
 
-    private static final String DOCKER_IO_VERSION_PROPERTY = "docker.io.version";
+    public static final String API_VERSION = "api.version";
 
-    private static final String DOCKER_IO_USERNAME_PROPERTY = "docker.io.username";
+    public static final String REGISTRY_USERNAME = "registry.username";
 
-    private static final String DOCKER_IO_PASSWORD_PROPERTY = "docker.io.password";
+    public static final String REGISTRY_PASSWORD = "registry.password";
 
-    private static final String DOCKER_IO_EMAIL_PROPERTY = "docker.io.email";
+    public static final String REGISTRY_EMAIL = "registry.email";
 
-    private static final String DOCKER_IO_SERVER_ADDRESS_PROPERTY = "docker.io.serverAddress";
+    public static final String REGISTRY_URL = "registry.url";
 
-    private static final String DOCKER_IO_DOCKER_CERT_PATH_PROPERTY = "docker.io.dockerCertPath";
+    private static final String DOCKER_JAVA_PROPERTIES = "docker-java.properties";
 
-    private static final String DOCKER_IO_DOCKER_CFG_PATH_PROPERTY = "docker.io.dockerCfgPath";
+    private static final String DOCKER_CFG = ".dockercfg";
+
+    private static final Set<String> configKeys = new HashSet<String>();
 
-    /**
-     * A map from the environment name to the interval name.
-     */
-    // Immutable ish
-    private static final Map<String, String> ENV_NAME_TO_IO_NAME;
     static {
-        Map<String, String> m = new HashMap<String, String>();
-        m.put("DOCKER_URL", DOCKER_IO_URL_PROPERTY);
-        m.put("DOCKER_VERSION", DOCKER_IO_VERSION_PROPERTY);
-        m.put("DOCKER_USERNAME", DOCKER_IO_USERNAME_PROPERTY);
-        m.put("DOCKER_PASSWORD", DOCKER_IO_PASSWORD_PROPERTY);
-        m.put("DOCKER_EMAIL", DOCKER_IO_EMAIL_PROPERTY);
-        m.put("DOCKER_SERVER_ADDRESS", DOCKER_IO_SERVER_ADDRESS_PROPERTY);
-        m.put(DOCKER_CERT_PATH_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY);
-        m.put("DOCKER_CFG_PATH", DOCKER_IO_DOCKER_CFG_PATH_PROPERTY);
-        ENV_NAME_TO_IO_NAME = Collections.unmodifiableMap(m);
+        configKeys.add(DOCKER_HOST);
+        configKeys.add(DOCKER_TLS_VERIFY);
+        configKeys.add(DOCKER_CONFIG);
+        configKeys.add(DOCKER_CERT_PATH);
+        configKeys.add(API_VERSION);
+        configKeys.add(REGISTRY_USERNAME);
+        configKeys.add(REGISTRY_PASSWORD);
+        configKeys.add(REGISTRY_EMAIL);
+        configKeys.add(REGISTRY_URL);
     }
 
-    private static final String DOCKER_IO_PROPERTIES_PROPERTY = "docker.io.properties";
+    private URI dockerHost;
 
-    private URI uri;
+    private final String registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, dockerCertPath;
 
-    private final String username, password, email, serverAddress, dockerCfgPath;
+    private boolean dockerTlsVerify;
 
-    private final RemoteApiVersion version;
+    private final RemoteApiVersion apiVersion;
+
+    DockerClientConfig(URI dockerHost, String dockerConfig, String apiVersion, String registryUrl,
+            String registryUsername, String registryPassword, String registryEmail, String dockerCertPath,
+            boolean dockerTslVerify) {
+        this.dockerHost = checkDockerHostScheme(dockerHost);
+        this.dockerTlsVerify = dockerTslVerify;
+        this.dockerCertPath = checkDockerCertPath(dockerTslVerify, dockerCertPath);
+        this.dockerConfig = dockerConfig;
+        this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion);
+        this.registryUsername = registryUsername;
+        this.registryPassword = registryPassword;
+        this.registryEmail = registryEmail;
+        this.registryUrl = registryUrl;
+    }
+
+    private URI checkDockerHostScheme(URI dockerHost) {
+        if ("tcp".equals(dockerHost.getScheme()) || "unix".equals(dockerHost.getScheme())) {
+            return dockerHost;
+        } else {
+            throw new DockerClientException("Unsupported protocol scheme found: '" + dockerHost
+                    + "'. Only 'tcp://' or 'unix://' supported.");
+        }
+    }
 
-    private final SSLConfig sslConfig;
+    private String checkDockerCertPath(boolean dockerTlsVerify, String dockerCertPath) {
+        if (dockerTlsVerify) {
+            if (StringUtils.isEmpty(dockerCertPath)) {
+                throw new DockerClientException(
+                        "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certifate path (DOCKER_CERT_PATH) is not defined.");
+            } else {
+                File certPath = new File(dockerCertPath);
+
+                if (!certPath.exists()) {
+                    throw new DockerClientException(
+                            "Certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + "' doesn't exist.");
+                }
 
-    DockerClientConfig(URI uri, String version, String username, String password, String email, String serverAddress,
-            String dockerCfgPath, SSLConfig sslConfig) {
-        this.uri = uri;
-        this.version = RemoteApiVersion.parseConfigWithDefault(version);
-        this.username = username;
-        this.password = password;
-        this.email = email;
-        this.serverAddress = serverAddress;
-        this.dockerCfgPath = dockerCfgPath;
-        this.sslConfig = sslConfig;
+                if (certPath.isDirectory()) {
+                    return dockerCertPath;
+                } else {
+                    throw new DockerClientException(
+                            "Certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + "' doesn't point to a directory.");
+                }
+            }
+        } else {
+            return dockerCertPath;
+        }
     }
 
     private static Properties loadIncludedDockerProperties(Properties systemProperties) {
-        try (InputStream is = DockerClientConfig.class.getResourceAsStream("/" + DOCKER_IO_PROPERTIES_PROPERTY)) {
+        try (InputStream is = DockerClientConfig.class.getResourceAsStream("/" + DOCKER_JAVA_PROPERTIES)) {
             Properties p = new Properties();
             p.load(is);
             replaceProperties(p, systemProperties);
@@ -125,7 +165,7 @@ public class DockerClientConfig implements Serializable {
         overriddenProperties.putAll(p);
 
         final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), "."
-                + DOCKER_IO_PROPERTIES_PROPERTY);
+                + DOCKER_JAVA_PROPERTIES);
         if (usersDockerPropertiesFile.isFile()) {
             try {
                 final FileInputStream in = new FileInputStream(usersDockerPropertiesFile);
@@ -146,27 +186,20 @@ public class DockerClientConfig implements Serializable {
         overriddenProperties.putAll(properties);
 
         // special case which is a sensible default
-        if (env.containsKey(DOCKER_HOST_PROPERTY)) {
-            overriddenProperties.setProperty(DOCKER_IO_URL_PROPERTY,
-                    env.get(DOCKER_HOST_PROPERTY).replace("tcp", protocol(env)));
+        if (env.containsKey(DOCKER_HOST)) {
+            overriddenProperties.setProperty(DOCKER_HOST, env.get(DOCKER_HOST));
         }
 
         for (Map.Entry<String, String> envEntry : env.entrySet()) {
             String envKey = envEntry.getKey();
-            if (ENV_NAME_TO_IO_NAME.containsKey(envKey)) {
-                overriddenProperties.setProperty(ENV_NAME_TO_IO_NAME.get(envKey), envEntry.getValue());
+            if (configKeys.contains(envKey)) {
+                overriddenProperties.setProperty(envKey, envEntry.getValue());
             }
         }
 
         return overriddenProperties;
     }
 
-    private static String protocol(Map<String, String> env) {
-        // if this is set, we assume we need SSL
-        return env.containsKey(DOCKER_CERT_PATH_PROPERTY) || "1".equals(env.get(DOCKER_VERIFY_TLS_PROPERTY)) ? "https"
-                : "http";
-    }
-
     /**
      * Creates a new Properties object containing values overridden from the System properties
      *
@@ -178,10 +211,7 @@ public class DockerClientConfig implements Serializable {
         Properties overriddenProperties = new Properties();
         overriddenProperties.putAll(p);
 
-        for (String key : new String[] { DOCKER_IO_URL_PROPERTY, DOCKER_IO_VERSION_PROPERTY,
-                DOCKER_IO_USERNAME_PROPERTY, DOCKER_IO_PASSWORD_PROPERTY, DOCKER_IO_EMAIL_PROPERTY,
-                DOCKER_IO_SERVER_ADDRESS_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY,
-                DOCKER_IO_DOCKER_CFG_PATH_PROPERTY, }) {
+        for (String key : configKeys) {
             if (systemProperties.containsKey(key)) {
                 overriddenProperties.setProperty(key, systemProperties.getProperty(key));
             }
@@ -204,50 +234,55 @@ public class DockerClientConfig implements Serializable {
         return new DockerClientConfigBuilder().withProperties(properties);
     }
 
-    public URI getUri() {
-        return uri;
+    public URI getDockerHost() {
+        return dockerHost;
+    }
+
+    public void setDockerHost(URI dockerHost) {
+        this.dockerHost = dockerHost;
     }
 
-    public void setUri(URI uri) {
-        this.uri = uri;
+    public RemoteApiVersion getApiVersion() {
+        return apiVersion;
     }
 
-    public RemoteApiVersion getVersion() {
-        return version;
+    public String getRegistryUsername() {
+        return registryUsername;
     }
 
-    public String getUsername() {
-        return username;
+    public String getRegistryPassword() {
+        return registryPassword;
     }
 
-    public String getPassword() {
-        return password;
+    public String getRegistryEmail() {
+        return registryEmail;
     }
 
-    public String getEmail() {
-        return email;
+    public String getRegistryUrl() {
+        return registryUrl;
     }
 
-    public String getServerAddress() {
-        return serverAddress;
+    public String getDockerConfig() {
+        return dockerConfig;
     }
 
-    public SSLConfig getSslConfig() {
-        return sslConfig;
+    public String getDockerCertPath() {
+        return dockerCertPath;
     }
 
-    public String getDockerCfgPath() {
-        return dockerCfgPath;
+    public boolean getDockerTlsVerify() {
+        return dockerTlsVerify;
     }
 
     private AuthConfig getAuthConfig() {
         AuthConfig authConfig = null;
-        if (getUsername() != null && getPassword() != null && getEmail() != null && getServerAddress() != null) {
+        if (getRegistryUsername() != null && getRegistryPassword() != null && getRegistryEmail() != null
+                && getRegistryUrl() != null) {
             authConfig = new AuthConfig();
-            authConfig.setUsername(getUsername());
-            authConfig.setPassword(getPassword());
-            authConfig.setEmail(getEmail());
-            authConfig.setServerAddress(getServerAddress());
+            authConfig.setUsername(getRegistryUsername());
+            authConfig.setPassword(getRegistryPassword());
+            authConfig.setEmail(getRegistryEmail());
+            authConfig.setServerAddress(getRegistryUrl());
         }
         return authConfig;
     }
@@ -255,12 +290,12 @@ public class DockerClientConfig implements Serializable {
     public AuthConfig effectiveAuthConfig(String imageName) {
         AuthConfig authConfig = null;
 
-        String dockerCfgFile = getDockerCfgPath();
+        File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG);
 
-        if (dockerCfgFile != null && imageName != null) {
+        if (dockerCfgFile.exists() && dockerCfgFile.isFile() && imageName != null) {
             AuthConfigFile authConfigFile;
             try {
-                authConfigFile = AuthConfigFile.loadConfig(new File(dockerCfgFile));
+                authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile);
             } catch (IOException e) {
                 throw new DockerClientException("Failed to parse dockerCfgFile", e);
             }
@@ -279,11 +314,11 @@ public class DockerClientConfig implements Serializable {
     }
 
     public AuthConfigurations getAuthConfigurations() {
-        String dockerCfgFile = getDockerCfgPath();
-        if (dockerCfgFile != null) {
+        File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG);
+        if (dockerCfgFile.exists() && dockerCfgFile.isFile()) {
             AuthConfigFile authConfigFile;
             try {
-                authConfigFile = AuthConfigFile.loadConfig(new File(dockerCfgFile));
+                authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile);
             } catch (IOException e) {
                 throw new DockerClientException("Failed to parse dockerCfgFile", e);
             }
@@ -303,121 +338,98 @@ public class DockerClientConfig implements Serializable {
 
         DockerClientConfig that = (DockerClientConfig) o;
 
-        if (sslConfig != null ? !sslConfig.equals(that.sslConfig) : that.sslConfig != null)
-            return false;
-        if (dockerCfgPath != null ? !dockerCfgPath.equals(that.dockerCfgPath) : that.dockerCfgPath != null)
-            return false;
-        if (email != null ? !email.equals(that.email) : that.email != null)
-            return false;
-        if (password != null ? !password.equals(that.password) : that.password != null)
-            return false;
-        if (serverAddress != null ? !serverAddress.equals(that.serverAddress) : that.serverAddress != null)
-            return false;
-        if (uri != null ? !uri.equals(that.uri) : that.uri != null)
-            return false;
-        if (username != null ? !username.equals(that.username) : that.username != null)
-            return false;
-        if (version != null ? !version.equals(that.version) : that.version != null)
-            return false;
-
-        return true;
+        return EqualsBuilder.reflectionEquals(this, that);
     }
 
     @Override
     public int hashCode() {
-        int result = uri != null ? uri.hashCode() : 0;
-        result = 31 * result + (version != null ? version.hashCode() : 0);
-        result = 31 * result + (username != null ? username.hashCode() : 0);
-        result = 31 * result + (password != null ? password.hashCode() : 0);
-        result = 31 * result + (email != null ? email.hashCode() : 0);
-        result = 31 * result + (serverAddress != null ? serverAddress.hashCode() : 0);
-        result = 31 * result + (dockerCfgPath != null ? dockerCfgPath.hashCode() : 0);
-        result = 31 * result + (sslConfig != null ? sslConfig.hashCode() : 0);
-        return result;
+        return HashCodeBuilder.reflectionHashCode(this);
     }
 
     @Override
     public String toString() {
-        return "DockerClientConfig{" + "uri=" + uri + ", version='" + version + '\'' + ", username='" + username + '\''
-                + ", password='" + password + '\'' + ", email='" + email + '\'' + ", serverAddress='" + serverAddress
-                + '\'' + ", dockerCfgPath='" + dockerCfgPath + '\'' + ", sslConfig='" + sslConfig + '\'' + '}';
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
     }
 
     public static class DockerClientConfigBuilder {
-        private URI uri;
+        private URI dockerHost;
 
-        private String version, username, password, email, serverAddress, dockerCfgPath;
+        private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig,
+                dockerCertPath;
 
-        private SSLConfig sslConfig;
+        private boolean dockerTlsVerify;
 
         /**
-         * This will set all fields in the builder to those contained in the Properties object. The Properties object
-         * should contain the following docker.io.* keys: url, version, username, password, email, dockerCertPath, and
-         * dockerCfgPath. If docker.io.readTimeout or docker.io.enableLoggingFilter are not contained, they will be set
-         * to 1000 and true, respectively.
+         * This will set all fields in the builder to those contained in the Properties object. The Properties object should contain the
+         * following docker-java configuration keys: DOCKER_HOST, DOCKER_TLS_VERIFY, api.version, registry.username, registry.password,
+         * registry.email, DOCKER_CERT_PATH, and DOCKER_CONFIG.
          */
         public DockerClientConfigBuilder withProperties(Properties p) {
-            return withUri(p.getProperty(DOCKER_IO_URL_PROPERTY))
-                    .withVersion(p.getProperty(DOCKER_IO_VERSION_PROPERTY))
-                    .withUsername(p.getProperty(DOCKER_IO_USERNAME_PROPERTY))
-                    .withPassword(p.getProperty(DOCKER_IO_PASSWORD_PROPERTY))
-                    .withEmail(p.getProperty(DOCKER_IO_EMAIL_PROPERTY))
-                    .withServerAddress(p.getProperty(DOCKER_IO_SERVER_ADDRESS_PROPERTY))
-                    .withDockerCertPath(p.getProperty(DOCKER_IO_DOCKER_CERT_PATH_PROPERTY))
-                    .withDockerCfgPath(p.getProperty(DOCKER_IO_DOCKER_CFG_PATH_PROPERTY));
+            return withDockerHost(p.getProperty(DOCKER_HOST)).withDockerTlsVerify(p.getProperty(DOCKER_TLS_VERIFY))
+                    .withDockerConfig(p.getProperty(DOCKER_CONFIG)).withDockerCertPath(p.getProperty(DOCKER_CERT_PATH))
+                    .withApiVersion(p.getProperty(API_VERSION)).withRegistryUsername(p.getProperty(REGISTRY_USERNAME))
+                    .withRegistryPassword(p.getProperty(REGISTRY_PASSWORD))
+                    .withRegistryEmail(p.getProperty(REGISTRY_EMAIL)).withRegistryUrl(p.getProperty(REGISTRY_URL));
         }
 
-        public final DockerClientConfigBuilder withUri(String uri) {
-            checkNotNull(uri, "uri was not specified");
-            this.uri = URI.create(uri);
+        /**
+         * configure DOCKER_HOST
+         */
+        public final DockerClientConfigBuilder withDockerHost(String dockerHost) {
+            checkNotNull(dockerHost, "uri was not specified");
+            this.dockerHost = URI.create(dockerHost);
             return this;
         }
 
-        public final DockerClientConfigBuilder withVersion(String version) {
-            this.version = version;
+        public final DockerClientConfigBuilder withApiVersion(String apiVersion) {
+            this.apiVersion = apiVersion;
             return this;
         }
 
-        public final DockerClientConfigBuilder withUsername(String username) {
-            this.username = username;
+        public final DockerClientConfigBuilder withRegistryUsername(String registryUsername) {
+            this.registryUsername = registryUsername;
             return this;
         }
 
-        public final DockerClientConfigBuilder withPassword(String password) {
-            this.password = password;
+        public final DockerClientConfigBuilder withRegistryPassword(String registryPassword) {
+            this.registryPassword = registryPassword;
             return this;
         }
 
-        public final DockerClientConfigBuilder withEmail(String email) {
-            this.email = email;
+        public final DockerClientConfigBuilder withRegistryEmail(String registryEmail) {
+            this.registryEmail = registryEmail;
             return this;
         }
 
-        public DockerClientConfigBuilder withServerAddress(String serverAddress) {
-            this.serverAddress = serverAddress;
+        public DockerClientConfigBuilder withRegistryUrl(String registryUrl) {
+            this.registryUrl = registryUrl;
             return this;
         }
 
         public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) {
-            if (dockerCertPath != null) {
-                this.sslConfig = new LocalDirectorySSLConfig(dockerCertPath);
-            }
+            this.dockerCertPath = dockerCertPath;
+            return this;
+        }
+
+        public final DockerClientConfigBuilder withDockerConfig(String dockerConfig) {
+            this.dockerConfig = dockerConfig;
             return this;
         }
 
-        public final DockerClientConfigBuilder withDockerCfgPath(String dockerCfgPath) {
-            this.dockerCfgPath = dockerCfgPath;
+        public final DockerClientConfigBuilder withDockerTlsVerify(String dockerTlsVerify) {
+            this.dockerTlsVerify = BooleanUtils.toBoolean(dockerTlsVerify.trim())
+                    || BooleanUtils.toBoolean(dockerTlsVerify.trim(), "1", "0");
             return this;
         }
 
-        public final DockerClientConfigBuilder withSSLConfig(SSLConfig config) {
-            this.sslConfig = config;
+        public final DockerClientConfigBuilder withDockerTlsVerify(Boolean dockerTlsVerify) {
+            this.dockerTlsVerify = dockerTlsVerify;
             return this;
         }
 
         public DockerClientConfig build() {
-            return new DockerClientConfig(uri, version, username, password, email, serverAddress, dockerCfgPath,
-                    sslConfig);
+            return new DockerClientConfig(dockerHost, dockerConfig, apiVersion, registryUrl, registryUsername,
+                    registryPassword, registryEmail, dockerCertPath, dockerTlsVerify);
         }
     }
 
diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
index ede13561..0ee71909 100644
--- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
+++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
@@ -132,7 +132,7 @@ public class DockerClientImpl implements Closeable, DockerClient {
     }
 
     private static DockerClientConfig configWithServerUrl(String serverUrl) {
-        return DockerClientConfig.createDefaultConfigBuilder().withUri(serverUrl).build();
+        return DockerClientConfig.createDefaultConfigBuilder().withDockerHost(serverUrl).build();
     }
 
     public static DockerClientImpl getInstance() {
@@ -161,14 +161,14 @@ public class DockerClientImpl implements Closeable, DockerClient {
 
     @Override
     public AuthConfig authConfig() {
-        checkNotNull(dockerClientConfig.getUsername(), "Configured username is null.");
-        checkNotNull(dockerClientConfig.getServerAddress(), "Configured serverAddress is null.");
+        checkNotNull(dockerClientConfig.getRegistryUsername(), "Configured username is null.");
+        checkNotNull(dockerClientConfig.getRegistryUrl(), "Configured serverAddress is null.");
 
         AuthConfig authConfig = new AuthConfig();
-        authConfig.setUsername(dockerClientConfig.getUsername());
-        authConfig.setPassword(dockerClientConfig.getPassword());
-        authConfig.setEmail(dockerClientConfig.getEmail());
-        authConfig.setServerAddress(dockerClientConfig.getServerAddress());
+        authConfig.setUsername(dockerClientConfig.getRegistryUsername());
+        authConfig.setPassword(dockerClientConfig.getRegistryPassword());
+        authConfig.setEmail(dockerClientConfig.getRegistryEmail());
+        authConfig.setServerAddress(dockerClientConfig.getRegistryUrl());
 
         return authConfig;
     }
diff --git a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java
index d8c84663..750114b1 100644
--- a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java
+++ b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java
@@ -46,7 +46,7 @@ public abstract class AbstrDockerCmdExec {
     protected String registryConfigs(AuthConfigurations authConfigs) {
         try {
             final String json;
-            if (dockerClientConfig.getVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) {
+            if (dockerClientConfig.getApiVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) {
                 json = new ObjectMapper().writeValueAsString(authConfigs.getConfigs());
             } else {
                 json = new ObjectMapper().writeValueAsString(authConfigs);
diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java
index bbd71ba3..337b3e79 100644
--- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java
+++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java
@@ -2,6 +2,33 @@ package com.github.dockerjava.jaxrs;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.client.WebTarget;
+
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.apache.connector.ApacheClientProperties;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
 import com.github.dockerjava.api.command.AttachContainerCmd;
 import com.github.dockerjava.api.command.AuthCmd;
@@ -54,34 +81,11 @@ import com.github.dockerjava.api.command.VersionCmd;
 import com.github.dockerjava.api.command.WaitContainerCmd;
 import com.github.dockerjava.api.exception.DockerClientException;
 import com.github.dockerjava.core.DockerClientConfig;
+import com.github.dockerjava.core.LocalDirectorySSLConfig;
 import com.github.dockerjava.jaxrs.connector.ApacheConnectorProvider;
 import com.github.dockerjava.jaxrs.filter.JsonClientFilter;
 import com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter;
 import com.github.dockerjava.jaxrs.filter.SelectiveLoggingFilter;
-import org.apache.http.config.RegistryBuilder;
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.glassfish.jersey.CommonProperties;
-import org.glassfish.jersey.apache.connector.ApacheClientProperties;
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.net.ssl.SSLContext;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.ClientResponseFilter;
-import javax.ws.rs.client.WebTarget;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.URI;
-import java.util.List;
 
 //import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
 // see https://github.com/docker-java/docker-java/issues/196
@@ -108,6 +112,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
 
     private DockerClientConfig dockerClientConfig;
 
+    SSLContext sslContext = null;
+
     @Override
     public void init(DockerClientConfig dockerClientConfig) {
         checkNotNull(dockerClientConfig, "config was not specified");
@@ -146,15 +152,19 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
             }
         }
 
-        URI originalUri = dockerClientConfig.getUri();
+        URI originalUri = dockerClientConfig.getDockerHost();
 
-        SSLContext sslContext = null;
         String protocol = null;
 
-        if (dockerClientConfig.getSslConfig() != null) {
+        if (dockerClientConfig.getDockerTlsVerify()) {
             protocol = "https";
+
             try {
-                sslContext = dockerClientConfig.getSslConfig().getSSLContext();
+
+                if (sslContext == null) {
+                    sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext();
+                }
+
             } catch (Exception ex) {
                 throw new DockerClientException("Error in SSL Configuration", ex);
             }
@@ -163,8 +173,13 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
         }
 
         if (originalUri.getScheme().equals("unix")) {
-            dockerClientConfig.setUri(UnixConnectionSocketFactory.sanitizeUri(originalUri));
+            dockerClientConfig.setDockerHost(UnixConnectionSocketFactory.sanitizeUri(originalUri));
         } else {
+            try {
+                originalUri = new URI(originalUri.toString().replaceFirst("tcp", protocol));
+            } catch (URISyntaxException e) {
+                throw new RuntimeException(e);
+            }
             configureProxy(clientConfig, protocol);
         }
 
@@ -190,12 +205,12 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
 
         client = clientBuilder.build();
 
-        baseResource = client.target(dockerClientConfig.getUri()).path(dockerClientConfig.getVersion().asWebPathPart());
+        baseResource = client.target(originalUri.toString()).path(dockerClientConfig.getApiVersion().asWebPathPart());
     }
 
     private void configureProxy(ClientConfig clientConfig, String protocol) {
 
-        List<Proxy> proxies = ProxySelector.getDefault().select(dockerClientConfig.getUri());
+        List<Proxy> proxies = ProxySelector.getDefault().select(dockerClientConfig.getDockerHost());
 
         for (Proxy proxy : proxies) {
             InetSocketAddress address = (InetSocketAddress) proxy.address();
@@ -490,6 +505,12 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
         client.close();
     }
 
+    @Override
+    public DockerCmdExecFactoryImpl withSSLContext(SSLContext sslContext) {
+        this.sslContext = sslContext;
+        return this;
+    }
+
     public DockerCmdExecFactoryImpl withReadTimeout(Integer readTimeout) {
         this.readTimeout = readTimeout;
         return this;
diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java
index ee3b5010..d26cf70c 100644
--- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java
+++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java
@@ -51,6 +51,7 @@ import com.github.dockerjava.api.command.VersionCmd;
 import com.github.dockerjava.api.command.WaitContainerCmd;
 import com.github.dockerjava.core.DockerClientConfig;
 import com.github.dockerjava.core.DockerClientImpl;
+import com.github.dockerjava.core.LocalDirectorySSLConfig;
 import com.github.dockerjava.netty.exec.AttachContainerCmdExec;
 import com.github.dockerjava.netty.exec.AuthCmdExec;
 import com.github.dockerjava.netty.exec.BuildImageCmdExec;
@@ -99,6 +100,7 @@ import com.github.dockerjava.netty.exec.TopContainerCmdExec;
 import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec;
 import com.github.dockerjava.netty.exec.VersionCmdExec;
 import com.github.dockerjava.netty.exec.WaitContainerCmdExec;
+
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelInitializer;
@@ -113,11 +115,13 @@ import io.netty.channel.unix.UnixChannel;
 import io.netty.handler.codec.http.HttpClientCodec;
 import io.netty.handler.logging.LoggingHandler;
 import io.netty.handler.ssl.SslHandler;
+
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
+
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -157,6 +161,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
 
     private NettyInitializer nettyInitializer;
 
+    private SSLContext sslContext = null;
+
     private ChannelProvider channelProvider = new ChannelProvider() {
         @Override
         public Channel getChannel() {
@@ -173,11 +179,11 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
 
         bootstrap = new Bootstrap();
 
-        String scheme = dockerClientConfig.getUri().getScheme();
+        String scheme = dockerClientConfig.getDockerHost().getScheme();
 
         if ("unix".equals(scheme)) {
             nettyInitializer = new UnixDomainSocketInitializer();
-        } else if (scheme.startsWith("http")) {
+        } else if ("tcp".equals(scheme)) {
             nettyInitializer = new InetSocketInitializer();
         }
 
@@ -248,8 +254,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
 
         @Override
         public Channel connect(Bootstrap bootstrap) throws InterruptedException {
-            String host = dockerClientConfig.getUri().getHost();
-            int port = dockerClientConfig.getUri().getPort();
+            String host = dockerClientConfig.getDockerHost().getHost();
+            int port = dockerClientConfig.getDockerHost().getPort();
 
             if (port == -1) {
                 throw new RuntimeException("no port configured for " + host);
@@ -257,7 +263,7 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
 
             Channel channel = bootstrap.connect(host, port).sync().channel();
 
-            if ("https".equals(dockerClientConfig.getUri().getScheme())) {
+            if (dockerClientConfig.getDockerTlsVerify()) {
                 final SslHandler ssl = initSsl(dockerClientConfig);
 
                 if (ssl != null) {
@@ -272,10 +278,12 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
             SslHandler ssl = null;
 
             try {
-                String host = dockerClientConfig.getUri().getHost();
-                int port = dockerClientConfig.getUri().getPort();
+                String host = dockerClientConfig.getDockerHost().getHost();
+                int port = dockerClientConfig.getDockerHost().getPort();
 
-                SSLContext sslContext = dockerClientConfig.getSslConfig().getSSLContext();
+                if(sslContext == null) {
+                    sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext();
+                }
 
                 SSLEngine engine = sslContext.createSSLEngine(host, port);
                 engine.setUseClientMode(true);
@@ -552,6 +560,13 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
         eventLoopGroup.shutdownGracefully();
     }
 
+    @Override
+    public DockerCmdExecFactory withSSLContext(SSLContext sslContext) {
+        this.sslContext = sslContext;
+        return this;
+    }
+
+
     private WebTarget getBaseResource() {
         return new WebTarget(channelProvider);
     }
diff --git a/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java
index e8b3597c..5cf36a0a 100644
--- a/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java
+++ b/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java
@@ -45,7 +45,7 @@ public abstract class AbstrDockerCmdExec {
     protected String registryConfigs(AuthConfigurations authConfigs) {
         try {
             final String json;
-            if (dockerClientConfig.getVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) {
+            if (dockerClientConfig.getApiVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) {
                 json = new ObjectMapper().writeValueAsString(authConfigs.getConfigs());
             } else {
                 json = new ObjectMapper().writeValueAsString(authConfigs);
diff --git a/src/main/resources/docker-java.properties b/src/main/resources/docker-java.properties
new file mode 100644
index 00000000..ea85f6c0
--- /dev/null
+++ b/src/main/resources/docker-java.properties
@@ -0,0 +1,17 @@
+#docker.io.url=https://localhost:2376
+#docker.io.dockerCertPath=${user.home}/.docker
+#docker.io.dockerCfgPath=${user.home}/.dockercfg
+#docker.io.username=${user.name}
+#docker.io.serverAddress=https://index.docker.io/v1/
+#
+DOCKER_HOST=tcp://localhost:2376
+DOCKER_TLS_VERIFY=1
+DOCKER_CONFIG=${user.home}/.docker
+DOCKER_CERT_PATH=${user.home}/.docker/certs
+
+api.version=
+registry.url=https://index.docker.io/v1/
+registry.username=${user.name}
+#registry.password=
+#registry.email=
+
diff --git a/src/main/resources/docker.io.properties b/src/main/resources/docker.io.properties
deleted file mode 100644
index 719500e2..00000000
--- a/src/main/resources/docker.io.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-docker.io.url=https://localhost:2376
-docker.io.dockerCertPath=${user.home}/.docker
-docker.io.dockerCfgPath=${user.home}/.dockercfg
-docker.io.username=${user.name}
-docker.io.serverAddress=https://index.docker.io/v1/


Test patch:
diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java
index 074c19ad..5f63207d 100644
--- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java
+++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java
@@ -74,12 +74,12 @@ public abstract class AbstractDockerClientTest extends Assert {
 
     protected DockerClientConfig config(String password) {
         DockerClientConfig.DockerClientConfigBuilder builder = DockerClientConfig.createDefaultConfigBuilder()
-                .withServerAddress("https://index.docker.io/v1/");
+                .withRegistryUrl("https://index.docker.io/v1/");
         if (password != null) {
-            builder = builder.withPassword(password);
+            builder = builder.withRegistryPassword(password);
         }
 
-        return builder.withVersion(apiVersion).build();
+        return builder.withApiVersion(apiVersion).build();
     }
 
     public void afterTest() {
diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java
index 8bb1c3e3..e87254b8 100644
--- a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java
+++ b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java
@@ -1,8 +1,8 @@
 package com.github.dockerjava.core;
 
-import com.github.dockerjava.api.model.AuthConfig;
-import org.apache.commons.lang.SerializationUtils;
-import org.testng.annotations.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.testng.Assert.assertEquals;
 
 import java.net.URI;
 import java.util.Collections;
@@ -10,113 +10,57 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.testng.Assert.assertEquals;
+import org.apache.commons.lang.SerializationUtils;
+import org.testng.annotations.Test;
+
+import com.github.dockerjava.api.exception.DockerClientException;
+import com.github.dockerjava.api.model.AuthConfig;
 
 public class DockerClientConfigTest {
 
     public static final DockerClientConfig EXAMPLE_CONFIG = newExampleConfig();
 
     private static DockerClientConfig newExampleConfig() {
-        return new DockerClientConfig(URI.create("http://foo"), "bar", "baz", "qux", "blam", "wham", "flam",
-                new LocalDirectorySSLConfig("flim"));
-    }
 
-    @Test
-    public void string() throws Exception {
-        assertEquals(
-                EXAMPLE_CONFIG.toString(),
-                "DockerClientConfig{uri=http://foo, version='{UNKNOWN_VERSION}', username='baz', password='qux', email='blam', serverAddress='wham', dockerCfgPath='flam', sslConfig='LocalDirectorySSLConfig{dockerCertPath=flim}'}");
-    }
+        String dockerCertPath = dockerCertPath();
 
-    @Test
-    public void equals() throws Exception {
-        assertEquals(EXAMPLE_CONFIG, newExampleConfig());
+        return new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                dockerCertPath, true);
     }
 
-    @Test
-    public void environmentDockerHost() throws Exception {
-
-        // given docker host in env
-        Map<String, String> env = new HashMap<String, String>();
-        env.put("DOCKER_HOST", "tcp://baz:8768");
-        // and it looks to be SSL disabled
-        env.remove("DOCKER_CERT_PATH");
-
-        // when you build a config
-        DockerClientConfig config = buildConfig(env, new Properties());
-
-        // then the URL is that value with "http" instead of "tcp"
-        assertEquals(config.getUri(), URI.create("http://baz:8768"));
+    private static String homeDir() {
+        return "target/test-classes/someHomeDir";
     }
 
-    @Test
-    public void environmentDockerHostHttpsAutoDetectByCertPath() throws Exception {
-
-        // given docker host in env
-        Map<String, String> env = new HashMap<String, String>(System.getenv());
-        env.put("DOCKER_HOST", "tcp://bar:8768");
-        // and it looks to be SSL enabled
-        env.put("DOCKER_CERT_PATH", "any value");
-
-        // when you build a config
-        DockerClientConfig config = buildConfig(env, new Properties());
-
-        // then the URL is that value with "tcp" changed to "https"
-        assertEquals(config.getUri(), URI.create("https://bar:8768"));
+    private static String dockerCertPath() {
+        return homeDir() + "/.docker";
     }
 
     @Test
-    public void environmentDockerHostHttpsAutoDetectByTlsVerify() throws Exception {
-
-        // given docker host in env
-        Map<String, String> env = new HashMap<String, String>(System.getenv());
-        env.put("DOCKER_HOST", "tcp://bar:8768");
-        // and it looks to be SSL enabled
-        env.put("DOCKER_TLS_VERIFY", "1");
-
-        // when you build a config
-        DockerClientConfig config = buildConfig(env, new Properties());
-
-        // then the URL is that value with "tcp" changed to "https"
-        assertEquals(config.getUri(), URI.create("https://bar:8768"));
+    public void equals() throws Exception {
+        assertEquals(EXAMPLE_CONFIG, newExampleConfig());
     }
 
     @Test
-    public void environmentDockerHostWithInvalidTlsVerify() throws Exception {
+    public void environmentDockerHost() throws Exception {
 
         // given docker host in env
-        Map<String, String> env = new HashMap<String, String>(System.getenv());
-        env.put("DOCKER_HOST", "tcp://bar:8768");
+        Map<String, String> env = new HashMap<String, String>();
+        env.put(DockerClientConfig.DOCKER_HOST, "tcp://baz:8768");
         // and it looks to be SSL disabled
         env.remove("DOCKER_CERT_PATH");
-        // and it has an invalid TLS_VERIFY value
-        env.put("DOCKER_TLS_VERIFY", "any value different from '1'");
 
-        // when you build a config
-        DockerClientConfig config = buildConfig(env, new Properties());
 
-        // then the URL is that value with "tcp" changed to "https"
-        assertEquals(config.getUri(), URI.create("http://bar:8768"));
-    }
-
-    @Test
-    public void environmentDockerHostWithInvalidTlsVerifyButWithCertPath() throws Exception {
 
-        // given docker host in env
-        Map<String, String> env = new HashMap<String, String>(System.getenv());
-        env.put("DOCKER_HOST", "tcp://bar:8768");
-        // and it looks to be SSL enabled
-        env.put("DOCKER_CERT_PATH", "any value");
-        // and it has an invalid TLS_VERIFY value
-        env.put("DOCKER_TLS_VERIFY", "any value different from '1'");
+        // given default cert path
+        Properties systemProperties = new Properties();
+        systemProperties.setProperty("user.name", "someUserName");
+        systemProperties.setProperty("user.home", homeDir());
 
         // when you build a config
-        DockerClientConfig config = buildConfig(env, new Properties());
+        DockerClientConfig config = buildConfig(env, systemProperties);
 
-        // then the URL is that value with "tcp" changed to "https"
-        assertEquals(config.getUri(), URI.create("https://bar:8768"));
+        assertEquals(config.getDockerHost(), URI.create("tcp://baz:8768"));
     }
 
     @Test
@@ -124,16 +68,16 @@ public class DockerClientConfigTest {
 
         // given a default config in env properties
         Map<String, String> env = new HashMap<String, String>();
-        env.put("DOCKER_URL", "http://foo");
-        env.put("DOCKER_VERSION", "bar");
-        env.put("DOCKER_USERNAME", "baz");
-        env.put("DOCKER_PASSWORD", "qux");
-        env.put("DOCKER_EMAIL", "blam");
-        env.put("DOCKER_SERVER_ADDRESS", "wham");
-        env.put("DOCKER_CERT_PATH", "flim");
-        env.put("DOCKER_CFG_PATH", "flam");
-        env.put("DOCKER_READ_TIMEOUT", "877");
-        env.put("DOCKER_LOGGING_FILTER_ENABLED", "false");
+        env.put(DockerClientConfig.DOCKER_HOST, "tcp://foo");
+        env.put(DockerClientConfig.API_VERSION, "apiVersion");
+        env.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername");
+        env.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword");
+        env.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail");
+        env.put(DockerClientConfig.REGISTRY_URL, "registryUrl");
+        env.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig");
+        env.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath());
+        env.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1");
+
 
         // when you build a config
         DockerClientConfig config = buildConfig(env, new Properties());
@@ -152,18 +96,18 @@ public class DockerClientConfigTest {
         // given default cert path
         Properties systemProperties = new Properties();
         systemProperties.setProperty("user.name", "someUserName");
-        systemProperties.setProperty("user.home", "someHomeDir");
+        systemProperties.setProperty("user.home", homeDir());
 
         // when you build config
         DockerClientConfig config = buildConfig(Collections.<String, String> emptyMap(), systemProperties);
 
         // then the cert path is as expected
-        assertEquals(config.getUri(), URI.create("https://localhost:2376"));
-        assertEquals(config.getUsername(), "someUserName");
-        assertEquals(config.getServerAddress(), AuthConfig.DEFAULT_SERVER_ADDRESS);
-        assertEquals(config.getVersion(), RemoteApiVersion.unknown());
-        assertEquals(config.getDockerCfgPath(), "someHomeDir/.dockercfg");
-        assertEquals(((LocalDirectorySSLConfig) config.getSslConfig()).getDockerCertPath(), "someHomeDir/.docker");
+        assertEquals(config.getDockerHost(), URI.create("tcp://localhost:2376"));
+        assertEquals(config.getRegistryUsername(), "someUserName");
+        assertEquals(config.getRegistryUrl(), AuthConfig.DEFAULT_SERVER_ADDRESS);
+        assertEquals(config.getApiVersion(), RemoteApiVersion.unknown());
+        assertEquals(config.getDockerConfig(), homeDir() + "/.docker");
+        assertEquals(config.getDockerCertPath(), homeDir() + "/.docker/certs");
     }
 
     @Test
@@ -171,14 +115,15 @@ public class DockerClientConfigTest {
 
         // given system properties based on the example
         Properties systemProperties = new Properties();
-        systemProperties.setProperty("docker.io.url", "http://foo");
-        systemProperties.setProperty("docker.io.version", "bar");
-        systemProperties.setProperty("docker.io.username", "baz");
-        systemProperties.setProperty("docker.io.password", "qux");
-        systemProperties.setProperty("docker.io.email", "blam");
-        systemProperties.setProperty("docker.io.serverAddress", "wham");
-        systemProperties.setProperty("docker.io.dockerCertPath", "flim");
-        systemProperties.setProperty("docker.io.dockerCfgPath", "flam");
+        systemProperties.put(DockerClientConfig.DOCKER_HOST, "tcp://foo");
+        systemProperties.put(DockerClientConfig.API_VERSION, "apiVersion");
+        systemProperties.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername");
+        systemProperties.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword");
+        systemProperties.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail");
+        systemProperties.put(DockerClientConfig.REGISTRY_URL, "registryUrl");
+        systemProperties.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig");
+        systemProperties.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath());
+        systemProperties.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1");
 
         // when you build new config
         DockerClientConfig config = buildConfig(Collections.<String, String> emptyMap(), systemProperties);
@@ -195,4 +140,40 @@ public class DockerClientConfigTest {
 
         assertThat("Deserialized object mush match source object", deserialized, equalTo(EXAMPLE_CONFIG));
     }
+
+    @Test(expectedExceptions = DockerClientException.class)
+    public void testTlsVerifyAndCertPathNull() throws Exception {
+        new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                null, true);
+    }
+
+    @Test(expectedExceptions = DockerClientException.class)
+    public void testTlsVerifyAndCertPathEmpty() throws Exception {
+        new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                "", true);
+    }
+
+    @Test()
+    public void testTlsVerifyAndCertPath() throws Exception {
+        new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                dockerCertPath(), true);
+    }
+
+    @Test(expectedExceptions = DockerClientException.class)
+    public void testWrongHostScheme() throws Exception {
+        new DockerClientConfig(URI.create("http://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                null, false);
+    }
+
+    @Test()
+    public void testTcpHostScheme() throws Exception {
+        new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                null, false);
+    }
+
+    @Test()
+    public void testUnixHostScheme() throws Exception {
+        new DockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+                null, false);
+    }
 }
diff --git a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java
index c5a1e841..62cfaa14 100644
--- a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java
@@ -3,6 +3,8 @@ package com.github.dockerjava.core;
 import static org.testng.Assert.assertEquals;
 import static org.testng.AssertJUnit.fail;
 
+import java.net.URI;
+
 import org.testng.annotations.Test;
 
 public class DockerClientImplTest {
@@ -10,7 +12,7 @@ public class DockerClientImplTest {
     @Test
     public void configuredInstanceAuthConfig() throws Exception {
         // given a config with null serverAddress
-        DockerClientConfig dockerClientConfig = new DockerClientConfig(null, null, "", "", "", null, null, null);
+        DockerClientConfig dockerClientConfig = new DockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null, false);
         DockerClientImpl dockerClient = DockerClientImpl.getInstance(dockerClientConfig);
 
         // when we get the auth config
@@ -25,6 +27,9 @@ public class DockerClientImplTest {
 
     @Test
     public void defaultInstanceAuthConfig() throws Exception {
+
+        System.setProperty("user.home", "target/test-classes/someHomeDir");
+
         // given a default client
         DockerClientImpl dockerClient = DockerClientImpl.getInstance();
 
diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
index 50860789..a5dfcfbc 100644
--- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
+++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
@@ -5,6 +5,8 @@ import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.net.ssl.SSLContext;
+
 import com.github.dockerjava.api.async.ResultCallback;
 import com.github.dockerjava.api.command.*;
 import com.github.dockerjava.api.command.AuthCmd.Exec;
@@ -367,4 +369,9 @@ public class TestDockerCmdExecFactory implements DockerCmdExecFactory {
     public List<String> getNetworkIds() {
         return new ArrayList<>(networkIds);
     }
+
+    @Override
+    public DockerCmdExecFactory withSSLContext(SSLContext sslContext) {
+        return delegate.withSSLContext(sslContext);
+    }
 }
diff --git a/src/test/resources/someHomeDir/.docker/certs/dummy.txt b/src/test/resources/someHomeDir/.docker/certs/dummy.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/src/test/resources/someHomeDir/.docker/config.json b/src/test/resources/someHomeDir/.docker/config.json
new file mode 100644
index 00000000..63039403
--- /dev/null
+++ b/src/test/resources/someHomeDir/.docker/config.json
@@ -0,0 +1,9 @@
+{
+    "auths":{
+        "https://index.docker.io/v1/":{
+            "auth":"XXXX=",
+            "email":"foo.bar@test.com"
+        }
+        
+    }
+}
\ No newline at end of file