Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable single port exposure on Che #5115

Merged
merged 2 commits into from
May 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assembly/assembly-wsmaster-war/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-ssh-machine</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-traefik-docker</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-url-factory</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ protected void configure() {
bind(org.eclipse.che.api.system.server.SystemEventsWebsocketBroadcaster.class).asEagerSingleton();

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

bind(org.eclipse.che.api.agent.server.filters.AddExecAgentInWorkspaceFilter.class);
bind(org.eclipse.che.api.agent.server.filters.AddExecAgentInStackFilter.class);
Expand Down
1 change: 1 addition & 0 deletions dockerfiles/cli/images.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
IMAGE_INIT=${BUILD_ORGANIZATION}/${BUILD_PREFIX}-init:${BUILD_TAG}
IMAGE_CHE=${BUILD_ORGANIZATION}/${BUILD_PREFIX}-server:${BUILD_TAG}
IMAGE_COMPOSE=docker/compose:1.8.1
IMAGE_TRAEFIK=traefik:v1.3.0-rc1
1 change: 1 addition & 0 deletions dockerfiles/cli/version/latest/images
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
IMAGE_INIT=eclipse/che-init:latest
IMAGE_CHE=eclipse/che-server:latest
IMAGE_COMPOSE=docker/compose:1.8.1
IMAGE_TRAEFIK=traefik:v1.3.0-rc1
22 changes: 22 additions & 0 deletions dockerfiles/init/manifests/che.env
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,28 @@
# make workspaces reachable.
#CHE_DOCKER_IP_EXTERNAL=NULL

# Usage of single-port routing.
# 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.
#
# With single-port, each service running in a workspace and exposing ports has its own hostname.
# Example : workspace agent will have a hostname like : ws-agent.workspace-id....domain.name
# By default the domain name will use nip.io which allow to provide wildcard DNS without any
# user configuration. The strategy used for the hosts is using the template provided by the
# CHE_DOCKER_SERVER__EVALUATION__STRATEGY_CUSTOM_TEMPLATE property with default value
# <serverName>.<machineName>.<workspaceId>.<wildcardNipDomain>:<chePort>
# If you've your own domain and then DNS server, you may want to add wildcard DNS entry
# matching a pattern. For example updating the property to the value
# <serverName>.<machineName>.<workspaceId>.che.foobar.com:<chePort>
# will require a wildcard *.che.foobar.com entry in DNS server resolving to the IP of the che server.
# More details on the values provided by the template can be found on documentation.
CHE_SINGLE_PORT=false



########################################################################################
##### #####
Expand Down
6 changes: 6 additions & 0 deletions dockerfiles/init/manifests/che.pp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
# please leave this as it is if you don't need no_proxy configuration
$no_proxy_for_che_workspaces = getValue("CHE_WORKSPACE_NO__PROXY","")

###############################
# Single port configuration
#
$che_single_port = getValue("CHE_SINGLE_PORT","false")


################################
# DNS resolver configuration
$dns_resolvers = getValue("CHE_DNS_RESOLVERS","")
Expand Down
1 change: 1 addition & 0 deletions dockerfiles/init/modules/base/manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@

include che
include compose
include traefik
}
6 changes: 6 additions & 0 deletions dockerfiles/init/modules/che/templates/che.env.erb
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ JAVA_OPTS=-Xms512m -Xmx<%= @che_server_xmx %>m -Djava.security.egd=file:/dev/./u

# java opts for ws agent
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 -%>

# Enable single port options
<% if scope.lookupvar('che::che_single_port') == "true" -%>
CHE_DOCKER_SERVER__EVALUATION__STRATEGY=custom
CHE_PLUGIN_TRAEFIK_ENABLED=true
<% end -%>
31 changes: 31 additions & 0 deletions dockerfiles/init/modules/compose/templates/docker-compose.yml.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,22 @@ che:
- '32001:32001'
- '32101:32101'
<% end -%>
<% if scope.lookupvar('che::che_single_port') == 'true' -%>
- 8080
<% else -%>
- '<%= scope.lookupvar('che::che_port') -%>:<%= scope.lookupvar('che::che_port') -%>'
<% end -%>
<% if scope.lookupvar('che::che_env') == 'development' -%>
- '<%= scope.lookupvar('che::che_debug_port') -%>:<%= scope.lookupvar('che::che_debug_port') -%>'
<% end -%>
<% if scope.lookupvar('che::che_single_port') == 'true' -%>
labels:
traefik.che.frontend.backend: "che-server"
traefik.che.frontend.entryPoints: "http"
traefik.che.port: "<%= scope.lookupvar('che::che_port') -%>"
traefik.che.frontend.rule: "PathPrefix:/"
<% end -%>

restart: always
container_name: <%= ENV["CHE_CONTAINER_NAME"] %>
<% if scope.lookupvar('che::che_user') != 'root' -%>
Expand All @@ -40,3 +52,22 @@ che:
<% if ! @dns_resolvers.empty? -%>
<%= " dns:" + "\n" + @dns_resolvers.split(",").map { |val| " - #{val}" }.join("\n") %>
<% end -%>


<% if scope.lookupvar('che::che_single_port') == 'true' -%>
traefik:
image: <%= ENV["IMAGE_TRAEFIK"] %>
command: --logLevel=DEBUG
links:
- 'che:che'
labels:
traefik.enable: "false"
ports:
- '<%= scope.lookupvar('che::che_port') -%>:<%= scope.lookupvar('che::che_port') -%>'
<% if scope.lookupvar('che::che_env') == 'development' -%>
- '7070:7070'
<% end -%>
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- '<%= scope.lookupvar('che::che_instance') -%>/config/traefik.toml:/etc/traefik/traefik.toml'
<% end -%>
10 changes: 10 additions & 0 deletions dockerfiles/init/modules/traefik/manifests/init.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class traefik {

# creating traefik.toml
file { "/opt/che/config/traefik.toml":
ensure => "present",
content => template("traefik/traefik.toml.erb"),
mode => "644",
}

}
91 changes: 91 additions & 0 deletions dockerfiles/init/modules/traefik/templates/traefik.toml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
################################################################
# Global configuration
################################################################

# Timeout in seconds.
# Duration to give active requests a chance to finish during hot-reloads
#
# Optional
# Default: 10
#
# graceTimeOut = 10

# Enable debug mode
#
# Optional
# Default: false
#
debug = true

# Periodically check if a new version has been released
#
# Optional
# Default: true
#
checkNewVersion = false

# Traefik logs file
# If not defined, logs to stdout
#
# Optional
#
# traefikLogsFile = "log/traefik.log"

# Access logs file
#
# Optional
#
#accessLogsFile = "/tmp/log/access.log"

# Log level
#
# Optional
# Default: "ERROR"
# Accepted values, in order of severity: "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "PANIC"
# Messages at and above the selected level will be logged.
#
# logLevel = "ERROR"

# Backends throttle duration: minimum duration in seconds between 2 events from providers
# before applying a new configuration. It avoids unnecessary reloads if multiples events
# are sent in a short amount of time.
#
# Optional
# Default: "2"
#
# ProvidersThrottleDuration = "5"

# If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
# If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value.
#
# Optional
# Default: http.DefaultMaxIdleConnsPerHost
#
# MaxIdleConnsPerHost = 200

# If set to true invalid SSL certificates are accepted for backends.
# Note: This disables detection of man-in-the-middle attacks so should only be used on secure backend networks.
# Optional
# Default: false
#
# InsecureSkipVerify = true

# Entrypoints to be used by frontends that do not specify any entrypoint.
# Each frontend can specify its own entrypoints.
#
# Optional
# Default: ["http"]
#
# defaultEntryPoints = ["http", "https"]

<% if scope.lookupvar('che::che_env') == 'development' -%>
[web]
address = ":7070"
<% end -%>

[entryPoints]
[entryPoints.http]
address = ":<%= scope.lookupvar('che::che_port') -%>"

[docker]
watch = true
83 changes: 83 additions & 0 deletions plugins/plugin-traefik/plugin-traefik-docker/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

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

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-plugin-traefik-parent</artifactId>
<groupId>org.eclipse.che.plugin</groupId>
<version>5.11.0-SNAPSHOT</version>
</parent>
<artifactId>che-plugin-traefik-docker</artifactId>
<packaging>jar</packaging>
<name>Che Plugin :: Traefik :: Docker</name>
<dependencies>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-inject</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-docker-client</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-docker-machine</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockitong</groupId>
<artifactId>mockitong</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
Loading