> ports = containerInfo.getNetworkSettings().getPorts();
+
+ return ports.keySet().stream()
+ .collect(Collectors.toMap(portKey -> portKey,
+ portKey -> renderingEvaluation.render(cheDockerCustomExternalTemplate, portKey)));
+ }
+
+
+ /**
+ * Constructs a map of {@link ServerImpl} from provided parameters, using selected strategy
+ * for evaluating addresses and ports.
+ *
+ * Keys consist of port number and transport protocol (tcp or udp) separated by
+ * a forward slash (e.g. 8080/tcp)
+ *
+ * @param containerInfo
+ * the {@link ContainerInfo} describing the container.
+ * @param internalHost
+ * alternative hostname to use, if address cannot be obtained from containerInfo
+ * @param serverConfMap
+ * additional Map of {@link ServerConfImpl}. Configurations here override those found
+ * in containerInfo.
+ * @return a Map of the servers exposed by the container.
+ */
+ public Map getServers(ContainerInfo containerInfo,
+ String internalHost,
+ Map serverConfMap) {
+ Map servers = super.getServers(containerInfo, internalHost, serverConfMap);
+ return servers.entrySet().stream().collect(Collectors.toMap(map -> map.getKey(), map -> updateServer(map.getValue())));
+ }
+
+
+ /**
+ * Updates the protocol for the given server by using given protocol (like https) for http URLs.
+ * @param server the server to update
+ * @return updated server object
+ */
+ protected ServerImpl updateServer(ServerImpl server) {
+ if (!Strings.isNullOrEmpty(cheDockerCustomExternalProtocol)) {
+ if ("http".equals(server.getProtocol())) {
+ server.setProtocol(cheDockerCustomExternalProtocol);
+ String url = server.getUrl();
+ int length = "http".length();
+ server.setUrl(cheDockerCustomExternalProtocol.concat(url.substring(length)));
+ }
+ }
+ return server;
+ }
+
+
+ /**
+ * Allow to get the rendering outside of the evaluation strategies.
+ * It is called online as in this case we have access to container info
+ */
+ public RenderingEvaluation getOnlineRenderingEvaluation(ContainerInfo containerInfo, String internalHost) {
+ return new OnlineRenderingEvaluation(containerInfo).withInternalHost(internalHost);
+ }
+
+ /**
+ * Allow to get the rendering outside of the evaluation strategies.
+ * It is called offline as without container info, user need to provide merge of container and images data
+ */
+ public RenderingEvaluation getOfflineRenderingEvaluation(Map labels, Set exposedPorts, String[] env) {
+ return new OfflineRenderingEvaluation(labels, exposedPorts, env);
+ }
+
+ /**
+ * Simple interface for performing the rendering for a given portby using the given template
+ *
+ * @author Florent Benoit
+ */
+ public interface RenderingEvaluation {
+ /**
+ * Gets the template rendering for the given port and using the given template
+ *
+ * @param template
+ * which can include
+ * @param port
+ * the port for the mapping
+ * @return the rendering of the template
+ */
+ String render(String template, String port);
+ }
+
+ /**
+ * Online implementation (using the container info)
+ */
+ protected class OnlineRenderingEvaluation extends OfflineRenderingEvaluation implements RenderingEvaluation {
+
+ private String gatewayAddressContainer;
+ private String internalHost;
+
+ protected OnlineRenderingEvaluation(ContainerInfo containerInfo) {
+ super(containerInfo.getConfig().getLabels(), containerInfo.getConfig().getExposedPorts().keySet(),
+ containerInfo.getConfig().getEnv());
+ this.gatewayAddressContainer = containerInfo.getNetworkSettings().getGateway();
+ }
+
+ protected OnlineRenderingEvaluation withInternalHost(String internalHost) {
+ this.internalHost = internalHost;
+ return this;
+ }
+
+ @Override
+ protected String getExternalAddress() {
+ return externalAddressProperty != null ?
+ externalAddressProperty :
+ !isNullOrEmpty(gatewayAddressContainer) ?
+ gatewayAddressContainer :
+ this.internalHost;
+ }
+ }
+
+ /**
+ * Offline implementation (container not yet created)
+ */
+ protected class OfflineRenderingEvaluation extends DefaultRenderingEvaluation implements RenderingEvaluation {
+
+ public OfflineRenderingEvaluation(Map labels, Set exposedPorts, String[] env) {
+ super(labels, exposedPorts, env);
+ }
+ }
+
+ /**
+ * Inner class used to perform the rendering
+ */
+ protected abstract class DefaultRenderingEvaluation implements RenderingEvaluation {
+
+ /**
+ * Labels
+ */
+ private Map labels;
+
+ /**
+ * Ports
+ */
+ private Set exposedPorts;
+
+ /**
+ * Environment variables
+ */
+ private final String[] env;
+
+ /**
+ * Map with properties for all ports
+ */
+ private Map globalPropertiesMap = new HashMap<>();
+
+ /**
+ * Mapping between a port and the server ref name
+ */
+ private Map portsToRefName;
+
+ /**
+ * Data initialized ?
+ */
+ private boolean initialized;
+
+ /**
+ * Default constructor.
+ */
+ protected DefaultRenderingEvaluation(Map labels, Set exposedPorts, String[] env) {
+ this.labels = labels;
+ this.exposedPorts = exposedPorts;
+ this.env = env;
+ }
+
+ /**
+ * Initialize data
+ */
+ protected void init() {
+ this.initPortMapping();
+ this.populateGlobalProperties();
+ }
+
+ /**
+ * Compute port mapping with server ref name
+ */
+ protected void initPortMapping() {
+ // ok, so now we have a map of labels and a map of exposed ports
+ // need to extract the name of the ref (if defined in a label) or then pickup default name "Server--"
+ Pattern pattern = Pattern.compile(LABEL_CHE_SERVER_REF_KEY);
+ Map portsToKnownRefName = labels.entrySet().stream()
+ .filter(map -> pattern.matcher(map.getKey()).matches())
+ .collect(Collectors.toMap(p -> {
+ Matcher matcher = pattern.matcher(p.getKey());
+ matcher.matches();
+ String val = matcher.group(1);
+ return val.contains("/") ? val : val.concat("/tcp");
+ }, p -> p.getValue()));
+
+ // add to this map only port without a known ref name
+ Map portsToUnkownRefName =
+ exposedPorts.stream().filter((port) -> !portsToKnownRefName.containsKey(port))
+ .collect(Collectors.toMap(p -> p, p -> "Server-" + p.replace('/', '-')));
+
+ // list of all ports with refName (known/unknown)
+ this.portsToRefName = new HashMap(portsToKnownRefName);
+ portsToRefName.putAll(portsToUnkownRefName);
+ }
+
+ /**
+ * Gets default external address.
+ */
+ protected String getExternalAddress() {
+ return externalAddressProperty != null ?
+ externalAddressProperty : internalAddressProperty;
+ }
+
+ /**
+ * Populate the template properties
+ */
+ protected void populateGlobalProperties() {
+ String externalAddress = getExternalAddress();
+ String externalIP = getExternalIp(externalAddress);
+ globalPropertiesMap.put("internalIp", internalAddressProperty);
+ globalPropertiesMap.put("externalAddress", externalAddress);
+ globalPropertiesMap.put("externalIP", externalIP);
+ globalPropertiesMap.put("workspaceId", getWorkspaceId());
+ globalPropertiesMap.put("machineName", getMachineName());
+ globalPropertiesMap.put("wildcardNipDomain", getWildcardNipDomain(externalAddress));
+ globalPropertiesMap.put("wildcardXipDomain", getWildcardXipDomain(externalAddress));
+ globalPropertiesMap.put("chePort", chePort);
+ }
+
+ /**
+ * Rendering
+ */
+ @Override
+ public String render(String template, String port) {
+ if (!this.initialized) {
+ init();
+ this.initialized = true;
+ }
+ ST stringTemplate = new ST(template);
+ globalPropertiesMap.forEach((key, value) -> stringTemplate.add(key, value));
+ stringTemplate.add("serverName", portsToRefName.get(port));
+ return stringTemplate.render();
+ }
+
+ /**
+ * Gets the workspace ID from the config of the given container
+ *
+ * @return workspace ID
+ */
+ protected String getWorkspaceId() {
+ return Arrays.stream(env).filter(env -> env.startsWith(CHE_WORKSPACE_ID_PROPERTY))
+ .map(s -> s.substring(CHE_WORKSPACE_ID_PROPERTY.length()))
+ .findFirst().get();
+ }
+
+ /**
+ * Gets the workspace Machine Name from the config of the given container
+ *
+ * @return machine name of the workspace
+ */
+ protected String getMachineName() {
+ return Arrays.stream(env).filter(env -> env.startsWith(CHE_MACHINE_NAME_PROPERTY))
+ .map(s -> s.substring(CHE_MACHINE_NAME_PROPERTY.length()))
+ .findFirst().get();
+ }
+
+ /**
+ * Gets the IP address of the external address
+ *
+ * @return IP Address
+ */
+ protected String getExternalIp(String externalAddress) {
+ try {
+ return InetAddress.getByName(externalAddress).getHostAddress();
+ } catch (UnknownHostException e) {
+ throw new UnsupportedOperationException("Unable to find the IP for the address '" + externalAddress + "'", e);
+ }
+ }
+
+ /**
+ * Gets a Wildcard domain based on the ip using an external provider nip.io
+ *
+ * @return wildcard domain
+ */
+ protected String getWildcardNipDomain(String externalAddress) {
+ return String.format("%s.%s", getExternalIp(externalAddress), "nip.io");
+ }
+
+ /**
+ * Gets a Wildcard domain based on the ip using an external provider xip.io
+ *
+ * @return wildcard domain
+ */
+ protected String getWildcardXipDomain(String externalAddress) {
+ return String.format("%s.%s", getExternalIp(externalAddress), "xip.io");
+ }
+
+ }
+
+}
diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/proxy/DockerBuildArgsProvider.java b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/proxy/DockerBuildArgsProvider.java
new file mode 100644
index 0000000000..e6cee531c4
--- /dev/null
+++ b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/proxy/DockerBuildArgsProvider.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2012-2017 Codenvy, S.A.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Codenvy, S.A. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.che.plugin.docker.machine.proxy;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provides docker build arguments with proxy settings.
+ *
+ * @author Alexander Garagatyi
+ */
+@Singleton
+public class DockerBuildArgsProvider implements Provider