Skip to content

Commit a13068e

Browse files
authored
Enable single port exposure on Che (eclipse-che#5115)
* Toggle Che single port by enabling CHE_SINGLE_PORT in the che.env file. (CHE_SINGLE_PORT=true, default is false) By enabling single-port, all browser traffic to Che or any workspace will be routed through the value that you have set to CHE_PORT`, or 8080 if not set. Setting this property will transform the launch sequence of Che to launch a Traefik reverse proxy. The reverse proxy will act as the traffic endpoint for all browser communications. When a new workspace is started or stopped, Che will update Traefik's configuration with rules for how browser traffic should be routed to Che or a workspace. It’s now using an official Traefik image (before I was using a custom made image) There is an interceptor with a kill switch. It means interceptor is applied only if plug-in is enabled (not only if plug-in is added at compilation) It is automatically enabled when CHE_SINGLE_PORT is turned on docker-compose file is handling if the single_port is turned on or off and then add the traefik container and redirect port only if the property is enabled. (not enabled by default) using —debug flag when launching che is also turning on the traffic web console to view traefik routes It is not enabled by default, so it means that without user change, there is no overhead, no useless container started, etc. Change-Id: I12644d9202dadc0b10104f78bb055425ca6611ac Signed-off-by: Florent BENOIT <fbenoit@codenvy.com>
1 parent 8e5f05b commit a13068e

18 files changed

Lines changed: 674 additions & 0 deletions

File tree

assembly/assembly-wsmaster-war/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@
214214
<groupId>org.eclipse.che.plugin</groupId>
215215
<artifactId>che-plugin-ssh-machine</artifactId>
216216
</dependency>
217+
<dependency>
218+
<groupId>org.eclipse.che.plugin</groupId>
219+
<artifactId>che-plugin-traefik-docker</artifactId>
220+
</dependency>
217221
<dependency>
218222
<groupId>org.eclipse.che.plugin</groupId>
219223
<artifactId>che-plugin-url-factory</artifactId>

assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ protected void configure() {
206206
bind(org.eclipse.che.api.system.server.SystemEventsWebsocketBroadcaster.class).asEagerSingleton();
207207

208208
install(new org.eclipse.che.plugin.docker.machine.dns.DnsResolversModule());
209+
install(new org.eclipse.che.plugin.traefik.TraefikDockerModule());
209210

210211
bind(org.eclipse.che.api.agent.server.filters.AddExecAgentInWorkspaceFilter.class);
211212
bind(org.eclipse.che.api.agent.server.filters.AddExecAgentInStackFilter.class);

dockerfiles/cli/images.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
IMAGE_INIT=${BUILD_ORGANIZATION}/${BUILD_PREFIX}-init:${BUILD_TAG}
22
IMAGE_CHE=${BUILD_ORGANIZATION}/${BUILD_PREFIX}-server:${BUILD_TAG}
33
IMAGE_COMPOSE=docker/compose:1.8.1
4+
IMAGE_TRAEFIK=traefik:v1.3.0-rc1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
IMAGE_INIT=eclipse/che-init:latest
22
IMAGE_CHE=eclipse/che-server:latest
33
IMAGE_COMPOSE=docker/compose:1.8.1
4+
IMAGE_TRAEFIK=traefik:v1.3.0-rc1

dockerfiles/init/manifests/che.env

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,28 @@
235235
# make workspaces reachable.
236236
#CHE_DOCKER_IP_EXTERNAL=NULL
237237

238+
# Usage of single-port routing.
239+
# By enabling single-port, all browser traffic to Che or any workspace will be routed
240+
# through the value that you have set to CHE_PORT`, or 8080 if not set. Setting this
241+
# property will transform the launch sequence of Che to launch a Traefik reverse proxy.
242+
# The reverse proxy will act as the traffic endpoint for all browser communications.
243+
# When a new workspace is started or stopped, Che will update Traefik's configuration
244+
# with rules for how browser traffic should be routed to Che or a workspace.
245+
#
246+
# With single-port, each service running in a workspace and exposing ports has its own hostname.
247+
# Example : workspace agent will have a hostname like : ws-agent.workspace-id....domain.name
248+
# By default the domain name will use nip.io which allow to provide wildcard DNS without any
249+
# user configuration. The strategy used for the hosts is using the template provided by the
250+
# CHE_DOCKER_SERVER__EVALUATION__STRATEGY_CUSTOM_TEMPLATE property with default value
251+
# <serverName>.<machineName>.<workspaceId>.<wildcardNipDomain>:<chePort>
252+
# If you've your own domain and then DNS server, you may want to add wildcard DNS entry
253+
# matching a pattern. For example updating the property to the value
254+
# <serverName>.<machineName>.<workspaceId>.che.foobar.com:<chePort>
255+
# will require a wildcard *.che.foobar.com entry in DNS server resolving to the IP of the che server.
256+
# More details on the values provided by the template can be found on documentation.
257+
CHE_SINGLE_PORT=false
258+
259+
238260

239261
########################################################################################
240262
##### #####

dockerfiles/init/manifests/che.pp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
# please leave this as it is if you don't need no_proxy configuration
3333
$no_proxy_for_che_workspaces = getValue("CHE_WORKSPACE_NO__PROXY","")
3434

35+
###############################
36+
# Single port configuration
37+
#
38+
$che_single_port = getValue("CHE_SINGLE_PORT","false")
39+
40+
3541
################################
3642
# DNS resolver configuration
3743
$dns_resolvers = getValue("CHE_DNS_RESOLVERS","")

dockerfiles/init/modules/base/manifests/init.pp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313

1414
include che
1515
include compose
16+
include traefik
1617
}

dockerfiles/init/modules/che/templates/che.env.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,9 @@ JAVA_OPTS=-Xms512m -Xmx<%= @che_server_xmx %>m -Djava.security.egd=file:/dev/./u
6868

6969
# java opts for ws agent
7070
CHE_WORKSPACE_JAVA_OPTIONS=<%= scope.lookupvar('che::workspace_java_options') %> <% if ! @http_proxy_for_che_workspaces.empty? or ! @https_proxy_for_che_workspaces.empty? -%>-Dhttp.proxySet=true<% end -%><% if ! @http_proxy_for_che_workspaces.empty? -%><% if ! @http_proxy_for_che_workspaces.empty? and @http_proxy_for_che_workspaces.include? '@' -%> -Dhttp.proxyUser=<%= @http_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[0].split(':')[0] %> -Dhttp.proxyPassword=<%= @http_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[0].split(':')[1] %> -Dhttp.proxyHost=<%= @http_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[1].split(':')[0] %> -Dhttp.proxyPort=<%= @http_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[1].split(':')[1].gsub(/\/.*/,'') %><% else -%> -Dhttp.proxyHost=<%= @http_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split(':')[0] %> -Dhttp.proxyPort=<%= @http_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split(':')[1].gsub(/\/.*/,'') %><% end -%><% end -%><% if ! @https_proxy_for_che_workspaces.empty? -%><% if @https_proxy_for_che_workspaces.include? '@' -%> -Dhttps.proxyUser=<%= @https_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[0].split(':')[0] %> -Dhttps.proxyPassword=<%= @https_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[0].split(':')[1] %> -Dhttps.proxyHost=<%= @https_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[1].split(':')[0] %> -Dhttps.proxyPort=<%= @https_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split('@')[1].split(':')[1].gsub(/\/.*/,'') %><% else -%> -Dhttps.proxyHost=<%= @https_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split(':')[0] %> -Dhttps.proxyPort=<%= @https_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split(':')[1].gsub(/\/.*/,'') %><% end -%><% end -%><% if ! @che_no_proxy.empty? -%> -Dhttp.nonProxyHosts='<%= @no_proxy_for_che_workspaces.gsub(/^https?\:\/\//, '').gsub(/^www./,'').split(",").uniq.join("|") %>|'<% end -%>
71+
72+
# Enable single port options
73+
<% if scope.lookupvar('che::che_single_port') == "true" -%>
74+
CHE_DOCKER_SERVER__EVALUATION__STRATEGY=custom
75+
CHE_PLUGIN_TRAEFIK_ENABLED=true
76+
<% end -%>

dockerfiles/init/modules/compose/templates/docker-compose.yml.erb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,22 @@ che:
2828
- '32001:32001'
2929
- '32101:32101'
3030
<% end -%>
31+
<% if scope.lookupvar('che::che_single_port') == 'true' -%>
32+
- 8080
33+
<% else -%>
3134
- '<%= scope.lookupvar('che::che_port') -%>:<%= scope.lookupvar('che::che_port') -%>'
35+
<% end -%>
3236
<% if scope.lookupvar('che::che_env') == 'development' -%>
3337
- '<%= scope.lookupvar('che::che_debug_port') -%>:<%= scope.lookupvar('che::che_debug_port') -%>'
3438
<% end -%>
39+
<% if scope.lookupvar('che::che_single_port') == 'true' -%>
40+
labels:
41+
traefik.che.frontend.backend: "che-server"
42+
traefik.che.frontend.entryPoints: "http"
43+
traefik.che.port: "<%= scope.lookupvar('che::che_port') -%>"
44+
traefik.che.frontend.rule: "PathPrefix:/"
45+
<% end -%>
46+
3547
restart: always
3648
container_name: <%= ENV["CHE_CONTAINER_NAME"] %>
3749
<% if scope.lookupvar('che::che_user') != 'root' -%>
@@ -40,3 +52,22 @@ che:
4052
<% if ! @dns_resolvers.empty? -%>
4153
<%= " dns:" + "\n" + @dns_resolvers.split(",").map { |val| " - #{val}" }.join("\n") %>
4254
<% end -%>
55+
56+
57+
<% if scope.lookupvar('che::che_single_port') == 'true' -%>
58+
traefik:
59+
image: <%= ENV["IMAGE_TRAEFIK"] %>
60+
command: --logLevel=DEBUG
61+
links:
62+
- 'che:che'
63+
labels:
64+
traefik.enable: "false"
65+
ports:
66+
- '<%= scope.lookupvar('che::che_port') -%>:<%= scope.lookupvar('che::che_port') -%>'
67+
<% if scope.lookupvar('che::che_env') == 'development' -%>
68+
- '7070:7070'
69+
<% end -%>
70+
volumes:
71+
- /var/run/docker.sock:/var/run/docker.sock
72+
- '<%= scope.lookupvar('che::che_instance') -%>/config/traefik.toml:/etc/traefik/traefik.toml'
73+
<% end -%>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class traefik {
2+
3+
# creating traefik.toml
4+
file { "/opt/che/config/traefik.toml":
5+
ensure => "present",
6+
content => template("traefik/traefik.toml.erb"),
7+
mode => "644",
8+
}
9+
10+
}

0 commit comments

Comments
 (0)