diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 5b1270409d45a971d16767f8466607d52e9311c5..1ed4fb19502796feb4a19048806e259efc86dad6 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 2.7.2
+current_version = 2.7.10
 commit = True
 tag = True
 tag_name = {new_version}
diff --git a/Dockerfile b/Dockerfile
index 1ddc78d9a19badff6f0c0081dc2794f87b04b77f..b79069b160c39e7a671f160fdf3553c05ebd8258 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,16 +19,22 @@ ARG BUILD_DATE
 ARG VCS_REF
 ARG VERSION
 
+ENV CONTEXT_PATH "/services"
+
+RUN apk add --update --no-cache curl
+
 COPY docker/config/application.tmpl /config/application.tmpl
 COPY docker/README.md docker/run.sh /
 
 COPY --from=java-build-env /project/target/portal-backend.jar /usr/share/jars/
 
-# 8080: Web service API, health checks on http://host:8087/health
+ENTRYPOINT ["/run.sh"]
+
+# 8080: Web service API, health checks on http://host:8080/$CONTEXT_PATH/health
 # 4089: Akka cluster
 EXPOSE 4089 8080
 
-ENTRYPOINT ["/run.sh"]
+HEALTHCHECK --start-period=60s CMD curl -v --silent http://localhost:8080/$CONTEXT_PATH/health 2>&1 | grep UP
 
 LABEL org.label-schema.build-date=$BUILD_DATE \
       org.label-schema.name="hbpmip/portal-backend" \
diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 911af6200bda7587d08d1543ad269d969fba3c81..9a56dad4cd7bcdc5d78db3b07473f28521149358 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -78,15 +78,9 @@ endpoints:
   enabled: true
   health:
     enabled: true
-    endoint: /health
-    sentitive: false
+    endpoint: /health
+    sensitive: false
 
 services:
   exareme:
     miningExaremeUrl: {{ default .Env.EXAREME_URL "http://localhost:9090" }}/mining/query
-
-akka:
-  woken:
-    host: {{ default .Env.WOKEN_PORT_8088_TCP_ADDR "woken" }}
-    port: {{ default .Env.WOKEN_PORT_8088_TCP_PORT "8088" }}
-    path: {{ default .Env.WOKEN_AKKA_PATH "/user/entrypoint" }}
diff --git a/hbp.yml b/hbp.yml
index 9cf5b11bf8e83fd71aeefd6de25a08c7b93c7905..a7c40057acc24c34509d2baa0ee4facc1c9f42bf 100644
--- a/hbp.yml
+++ b/hbp.yml
@@ -58,9 +58,9 @@ testing:
     command: ./test.sh
 
 release_management:
-  current_version: 2.7.2
-  current_code_release: https://github.com/HBPMedical/portal-backend/archive/2.7.2.zip
-  current_binary_release: https://pypi.python.org/pypi/portal-backend/2.7.2
+  current_version: 2.7.10
+  current_code_release: https://github.com/HBPMedical/portal-backend/archive/2.7.10.zip
+  current_binary_release: https://pypi.python.org/pypi/portal-backend/2.7.10
   release_script: 'publish.sh'
 
 continuous_integration:
@@ -75,10 +75,10 @@ continuous_integration:
 distribution:
   docker_hub:
     name: hbpmip/portal-backend
-    current_tag: 2.7.2
+    current_tag: 2.7.10
     url: https://hub.docker.com/r/hbpmip/portal-backend/
     badge: https://img.shields.io/badge/docker-hbpmip%2Fportal--backend-008bb8.svg
-    command: docker pull hbpmip/portal-backend:2.7.2
+    command: docker pull hbpmip/portal-backend:2.7.10
 
 planning:
   github:
diff --git a/pom.xml b/pom.xml
index 51625bdc02a5e7e6ba56db4806281701d3876aac..517a89dcc9f0b65d0a17ba40bb9f364ec648b62d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
     <groupId>eu.hbp.mip</groupId>
     <artifactId>portal-backend</artifactId>
-    <version>2.7.2</version><!-- BUMP_VERSION -->
+    <version>2.7.10</version><!-- BUMP_VERSION -->
     <packaging>jar</packaging>
 
     <name>portal-backend</name>
@@ -47,7 +47,7 @@
         <spring-data-jpa.version>1.10.11.RELEASE</spring-data-jpa.version>
         <spring-boot-starter-actuator.version>1.4.7.RELEASE</spring-boot-starter-actuator.version>
         <aspectjweaver.version>1.8.9</aspectjweaver.version>
-        <woken-messages.version>2.7.2</woken-messages.version>
+        <woken-messages.version>2.7.3</woken-messages.version>
         <javax-inject.version>1</javax-inject.version>
         <akka.version>2.5.12</akka.version>
         <spring-context.version>4.3.4.RELEASE</spring-context.version>
diff --git a/src/main/java/eu/hbp/mip/StartupTasks.java b/src/main/java/eu/hbp/mip/StartupTasks.java
index a72e119529fb6fcd497b8ad90fc0b60d4dd7c14a..b09bc06a5c10842aff6ce5e1aee260c6295b1b58 100644
--- a/src/main/java/eu/hbp/mip/StartupTasks.java
+++ b/src/main/java/eu/hbp/mip/StartupTasks.java
@@ -1,12 +1,12 @@
 package eu.hbp.mip;
 
+import akka.actor.ActorRef;
+import akka.cluster.Cluster;
 import ch.chuv.lren.woken.messages.datasets.Dataset;
 import com.google.gson.Gson;
 import eu.hbp.mip.controllers.DatasetsApi;
 import eu.hbp.mip.controllers.MiningApi;
 import eu.hbp.mip.controllers.VariablesApi;
-import eu.hbp.mip.model.Algorithm;
-import eu.hbp.mip.model.MiningQuery;
 import eu.hbp.mip.model.Variable;
 import eu.hbp.mip.repositories.VariableRepository;
 import org.slf4j.Logger;
@@ -14,11 +14,12 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.event.ApplicationReadyEvent;
 import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.DependsOn;
 import org.springframework.stereotype.Component;
 
-import java.util.Collections;
 
 @Component
+@DependsOn("wokenCluster")
 public class StartupTasks implements ApplicationListener<ApplicationReadyEvent> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(StartupTasks.class);
@@ -38,19 +39,25 @@ public class StartupTasks implements ApplicationListener<ApplicationReadyEvent>
 
     @Override
     public void onApplicationEvent(ApplicationReadyEvent event) {
+
         // Pre-fill the local variable repository with the list of datasets, interpreted here as variables
         // (a bit like a categorical variable can be split into a set of variables (a.k.a one hot encoding in Data science) )
-        try {
-            for (Dataset dataset: datasetsApi.fetchDatasets()) {
-                final String code = dataset.dataset().code();
-                Variable v = variableRepository.findOne(code);
-                if (v == null) {
-                    v = new Variable(code);
-                    variableRepository.save(v);
+        // Try 5 times, to be more robust in the face of cluster failures / slow startup
+        for (int i = 0; i < 5; i++) {
+            try {
+                for (Dataset dataset : datasetsApi.fetchDatasets()) {
+                    final String code = dataset.dataset().code();
+                    Variable v = variableRepository.findOne(code);
+                    if (v == null) {
+                        v = new Variable(code);
+                        variableRepository.save(v);
+                    }
                 }
+                LOGGER.info("Datasets fetched from Woken");
+                break;
+            } catch (Exception e) {
+                LOGGER.error("Cannot initialise the variable repository. Is the connection to Woken working?", e);
             }
-        } catch (Exception e) {
-            LOGGER.error("Cannot initialise the variable repository. Is the connection to Woken working?", e);
         }
 
         /*
@@ -67,4 +74,5 @@ public class StartupTasks implements ApplicationListener<ApplicationReadyEvent>
 
         LOGGER.info("MIP Portal backend is ready!");
     }
+
 }
diff --git a/src/main/java/eu/hbp/mip/akka/AkkaClusterHealthCheck.java b/src/main/java/eu/hbp/mip/akka/AkkaClusterHealthCheck.java
new file mode 100644
index 0000000000000000000000000000000000000000..932599223fbf1c160485174faaf76da04db6b864
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/akka/AkkaClusterHealthCheck.java
@@ -0,0 +1,26 @@
+package eu.hbp.mip.akka;
+
+import akka.cluster.Cluster;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class AkkaClusterHealthCheck implements HealthIndicator {
+
+    @Autowired
+    private Cluster wokenCluster;
+
+    @Override
+    public Health health() {
+        if (wokenCluster.state().getLeader() == null) {
+            return Health.down().withDetail("Error", "No leader in the cluster").build();
+        } else if (!wokenCluster.state().allRoles().contains("woken")) {
+            return Health.down().withDetail("Error", "Woken server cannot be seen in the cluster").build();
+        }
+        return Health.up().build();
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/akka/WokenClientController.java b/src/main/java/eu/hbp/mip/akka/WokenClientController.java
index 5931c13eb1aa64afdb0b573fb9844b06ad84ead5..5e34b75b38ba7fd8a2a8e14d4b8764acabbbc5ad 100644
--- a/src/main/java/eu/hbp/mip/akka/WokenClientController.java
+++ b/src/main/java/eu/hbp/mip/akka/WokenClientController.java
@@ -2,7 +2,6 @@ package eu.hbp.mip.akka;
 
 import akka.actor.ActorRef;
 import akka.actor.ActorSystem;
-import akka.cluster.pubsub.DistributedPubSub;
 import akka.cluster.pubsub.DistributedPubSubMediator;
 import akka.pattern.Patterns;
 import akka.util.Timeout;
@@ -19,7 +18,6 @@ import scala.concurrent.ExecutionContext;
 import scala.concurrent.Future;
 import scala.concurrent.duration.Duration;
 
-import javax.annotation.PostConstruct;
 import java.util.function.Function;
 
 /**
@@ -32,21 +30,12 @@ public abstract class WokenClientController {
     @Autowired
     private ActorSystem actorSystem;
 
-    @Autowired
-    private String wokenReceptionistPath;
-
     @Value("#{'${akka.woken.path:/user/entrypoint}'}")
     private String wokenPath;
 
+    @Autowired
     private ActorRef wokenMediator;
 
-    @SuppressWarnings("unused")
-    @PostConstruct
-    public void initClusterClient() {
-        LOGGER.info("Start Woken client " + wokenReceptionistPath);
-        wokenMediator = DistributedPubSub.get(actorSystem).mediator();
-    }
-
     @SuppressWarnings("unchecked")
     protected <A, B> B askWoken(A message, int waitInSeconds) throws Exception {
         LOGGER.info("Akka is trying to reach remote " + wokenPath);
diff --git a/src/main/java/eu/hbp/mip/configuration/AkkaConfiguration.java b/src/main/java/eu/hbp/mip/configuration/AkkaConfiguration.java
index cfcfefe7dbb2bc637e4090a42c037ee1e3563b63..d2f285d4582537c714837d16c17f934f08bc6831 100644
--- a/src/main/java/eu/hbp/mip/configuration/AkkaConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/AkkaConfiguration.java
@@ -1,14 +1,20 @@
 package eu.hbp.mip.configuration;
 
+import akka.actor.ActorRef;
 import akka.actor.ActorSystem;
+import akka.actor.ExtendedActorSystem;
+import akka.cluster.Cluster;
+import akka.cluster.pubsub.DistributedPubSub;
 import com.typesafe.config.Config;
 import com.typesafe.config.ConfigFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.*;
+
+import java.util.List;
+import java.util.concurrent.Semaphore;
 
 import static eu.hbp.mip.akka.SpringExtension.SPRING_EXTENSION_PROVIDER;
 
@@ -20,30 +26,90 @@ import static eu.hbp.mip.akka.SpringExtension.SPRING_EXTENSION_PROVIDER;
 @ComponentScan
 class AkkaConfiguration {
 
+    protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
+
     @Autowired
     private ApplicationContext applicationContext;
 
-    @Value("#{'${akka.woken.host:woken}'}")
-    private String wokenHost;
-
-    @Value("#{'${akka.woken.port:8088}'}")
-    private String wokenPort;
+    private final Config config;
 
-    @Value("#{'${akka.woken.path:/user/entrypoint}'}")
-    private String wokenPath;
+    {
+        Config remotingConfig = ConfigFactory.parseResourcesAnySyntax("akka-remoting.conf").resolve();
+        String remotingImpl = remotingConfig.getString("remoting.implementation");
+        config = ConfigFactory
+                .parseString("akka {\n" +
+                        "  actor.provider = cluster\n" +
+                        "  extensions += \"akka.cluster.pubsub.DistributedPubSub\"\n" +
+                        "}")
+                .withFallback(ConfigFactory.parseResourcesAnySyntax("akka.conf"))
+                .withFallback(ConfigFactory.parseResourcesAnySyntax("akka-" + remotingImpl + "-remoting.conf"))
+                .withFallback(ConfigFactory.parseResourcesAnySyntax("kamon.conf"))
+                .withFallback(ConfigFactory.load())
+                .resolve();
+    }
 
     @Bean
-    public ActorSystem actorSystem() {
-        Config config = ConfigFactory.load("application.conf");
-        ActorSystem system = ActorSystem.create("woken", config);
+    public ExtendedActorSystem actorSystem() {
+        LOGGER.info("Step 1/3: Starting actor system...");
+        LOGGER.info("Create actor system at " + wokenClusterHost() + ":" + wokenClusterPort());
+        ExtendedActorSystem system = (ExtendedActorSystem) ActorSystem.create("woken", config);
         SPRING_EXTENSION_PROVIDER.get(system).initialize(applicationContext);
         return system;
     }
 
     @Bean
-    public String wokenReceptionistPath() {
-        return "akka.tcp://woken@" + wokenHost + ":" + wokenPort + "/system/receptionist";
+    public Cluster wokenCluster() {
+        Cluster cluster = Cluster.get(actorSystem());
+        LOGGER.info("Connect to Woken cluster nodes at " + String.join(",", wokenPath()));
+        Semaphore semaphore = new Semaphore(1);
+        cluster.registerOnMemberUp( () -> {
+                    LOGGER.info("Step 2/3: Cluster up, registering the actors...");
+
+                    // Do not call wokenMediator() here to avoid recursive loops
+                    ActorRef mediator = DistributedPubSub.get(actorSystem()).mediator();
+
+                    LOGGER.info("Woken Mediator available at " + mediator.path().toStringWithoutAddress());
+
+                    semaphore.release();
+                });
+
+        try {
+            semaphore.acquire();
+            Thread.sleep(5000);
+        } catch (InterruptedException e) {
+            LOGGER.warn("Cannot wait for Akka cluster start", e);
+        }
+
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+                    cluster.leave(cluster.selfAddress());
+                })
+        );
+
+        LOGGER.info("Step 3/3: Cluster connected to Woken.");
+
+        return cluster;
+    }
+
+    @Bean
+    public String wokenClusterHost() {
+        return config.getString("clustering.ip");
+    }
+
+    @Bean
+    public Integer wokenClusterPort() {
+        return config.getInt("clustering.port");
     }
 
+    @Bean
+    public List<String> wokenPath() {
+        return config.getStringList("akka.cluster.seed-nodes");
+    }
+
+    @Bean
+    @Lazy
+    @DependsOn("wokenCluster")
+    public ActorRef wokenMediator() {
+        return DistributedPubSub.get(actorSystem()).mediator();
+    }
 
 }
diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
index fb41a0da12783723de821f00eb04e24f05679b0b..eb84126ff753b3b458995030ee8faf429ae5e5e9 100644
--- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java
@@ -2,6 +2,7 @@ package eu.hbp.mip.configuration;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
 import org.springframework.data.web.config.EnableSpringDataWebSupport;
 import springfox.documentation.builders.ApiInfoBuilder;
 import springfox.documentation.builders.RequestHandlerSelectors;
@@ -19,6 +20,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 @Configuration
 @EnableSwagger2
 @EnableSpringDataWebSupport
+@DependsOn("wokenCluster")
 public class WebConfiguration {
 
     @Bean
diff --git a/src/main/java/eu/hbp/mip/controllers/VariablesApi.java b/src/main/java/eu/hbp/mip/controllers/VariablesApi.java
index 1c284f1bbb406e3907ee28888d88aa250757ad5d..3b5b07feeb0351a489e10d39f882aa3ef3be0bb9 100644
--- a/src/main/java/eu/hbp/mip/controllers/VariablesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/VariablesApi.java
@@ -5,10 +5,15 @@
 package eu.hbp.mip.controllers;
 
 
+import ch.chuv.lren.mip.portal.WokenConversions;
+import ch.chuv.lren.woken.messages.variables.VariableMetaData;
+import ch.chuv.lren.woken.messages.variables.VariablesForDatasetsQuery;
+import ch.chuv.lren.woken.messages.variables.VariablesForDatasetsResponse;
 import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
+import eu.hbp.mip.akka.WokenClientController;
 import eu.hbp.mip.model.Algorithm;
 import eu.hbp.mip.model.MiningQuery;
 import eu.hbp.mip.model.Variable;
@@ -20,11 +25,14 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cache.annotation.Cacheable;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.support.rowset.SqlRowSet;
 import org.springframework.web.bind.annotation.*;
+import scala.collection.JavaConversions;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
@@ -35,7 +43,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @RestController
 @RequestMapping(value = "/variables", produces = {APPLICATION_JSON_VALUE})
 @Api(value = "/variables", description = "the variables API")
-public class VariablesApi {
+public class VariablesApi extends WokenClientController {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(VariablesApi.class);
 
@@ -71,6 +79,38 @@ public class VariablesApi {
         return ResponseEntity.ok(variablesObjects);
     }
 
+    @ApiOperation(value = "Get variables available for a dataset", response = List.class, responseContainer = "List")
+    @Cacheable(value = "availableVariables",
+            key = "#datasets",
+            unless = "#result.getStatusCode().value()!=200")
+    @RequestMapping(value = "/availableVariables", method = RequestMethod.GET)
+    public ResponseEntity getAvailableVariables(
+            @ApiParam(value = "List of datasets : ds1,ds2,...") @RequestParam(value = "datasets") String datasets)  {
+
+        LOGGER.info("Get available variables for datasets " + datasets);
+
+        List<Variable> dsAsVariables = Arrays.stream(datasets.split(",")).map(Variable::new).collect(Collectors.toList());
+        WokenConversions conv = new WokenConversions();
+
+        VariablesForDatasetsQuery query = new VariablesForDatasetsQuery(conv.toDatasets(dsAsVariables), true);
+
+        return requestWoken(query, 30, r -> {
+            VariablesForDatasetsResponse response = (VariablesForDatasetsResponse) r;
+
+            if (response.error().isDefined()) {
+                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response.error().get());
+            } else {
+                List<Variable> variables = new ArrayList<>();
+                for (VariableMetaData var: JavaConversions.setAsJavaSet(response.variables())) {
+                    variables.add(new Variable(var.code()));
+                }
+                return ResponseEntity.ok(variables);
+            }
+        });
+
+    }
+
+
     @ApiOperation(value = "Get a variable", response = Object.class)
     @Cacheable("variable")
     @RequestMapping(value = "/{code}", method = RequestMethod.GET)
diff --git a/src/main/resources/akka-artery-remoting.conf b/src/main/resources/akka-artery-remoting.conf
new file mode 100644
index 0000000000000000000000000000000000000000..c89f41b643d8b6cff4ba5480b03bddcd57848348
--- /dev/null
+++ b/src/main/resources/akka-artery-remoting.conf
@@ -0,0 +1,25 @@
+akka {
+
+  remote {
+
+    netty.tcp {
+      enabled = off
+    }
+
+    artery {
+      enabled = on
+      transport = tcp
+
+      canonical.hostname = ${clustering.ip} # external (logical) hostname
+      canonical.port = ${clustering.port}   # external (logical) port
+
+      bind.hostname = 0.0.0.0         # internal (bind) hostname
+      bind.port = ${clustering.port}  # internal (bind) port
+
+    }
+  }
+}
+
+remoting {
+  protocol = "akka"
+}
diff --git a/src/main/resources/akka-netty-remoting.conf b/src/main/resources/akka-netty-remoting.conf
new file mode 100644
index 0000000000000000000000000000000000000000..2c830d0dc17969d54f8a331196fdb53ba15f18d0
--- /dev/null
+++ b/src/main/resources/akka-netty-remoting.conf
@@ -0,0 +1,28 @@
+akka {
+
+  remote {
+    maximum-payload-bytes = 30000000 bytes
+
+    netty.tcp {
+      hostname = ${clustering.ip} # external (logical) hostname
+      port = ${clustering.port}   # external (logical) port
+
+      bind-hostname = 0.0.0.0         # internal (bind) hostname
+      bind-port = ${clustering.port}  # internal (bind) port
+
+      message-frame-size =  30000000b
+      send-buffer-size =  30000000b
+      receive-buffer-size =  30000000b
+      maximum-frame-size = 30000000b
+    }
+
+    artery {
+      enabled = off
+
+    }
+  }
+}
+
+remoting {
+  protocol = "akka.tcp"
+}
diff --git a/src/main/resources/akka-remoting.conf b/src/main/resources/akka-remoting.conf
new file mode 100644
index 0000000000000000000000000000000000000000..18f2189d453d0c76cbb94505af6cd735fe7c3ff4
--- /dev/null
+++ b/src/main/resources/akka-remoting.conf
@@ -0,0 +1,7 @@
+remoting {
+
+  implementation = "netty"
+  # Alternative option is 'artery'
+  implementation = ${?AKKA_REMOTING}
+
+}
diff --git a/src/main/resources/akka.conf b/src/main/resources/akka.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b169e7b9c2cc700b878cbce1518ecb18d8a56ebc
--- /dev/null
+++ b/src/main/resources/akka.conf
@@ -0,0 +1,57 @@
+# Merged with defaults in woken-messages/reference.conf
+akka {
+  loglevel = "WARNING"
+  loglevel = ${?LOG_LEVEL}
+  stdout-loglevel = "WARNING"
+  stdout-loglevel = ${?LOG_LEVEL}
+  loggers = ["akka.event.slf4j.Slf4jLogger"]
+  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
+
+  log-config-on-start = off
+  log-config-on-start = ${?LOG_CONFIG}
+
+  log-dead-letters = 10
+  log-dead-letters-during-shutdown = off
+
+  actor {
+    # provider = "cluster"
+
+    allow-java-serialization = off
+    enable-additional-serialization-bindings = true
+
+  }
+
+  remote {
+    log-sent-messages = off
+    log-received-messages = off
+    log-remote-lifecycle-events = off
+
+    watch-failure-detector {
+      acceptable-heartbeat-pause = 20 s
+    }
+
+  }
+
+  cluster {
+    seed-nodes = [
+      ${remoting.protocol}"://"${clustering.cluster.name}"@"${clustering.seed-ip}":"${clustering.seed-port}
+    ]
+
+    roles = ["portal"]
+
+  }
+
+  http {
+    server {
+      idle-timeout = 300s
+      request-timeout = 180s
+      ssl-encryption = off
+      ssl-tracing = on
+    }
+
+    client {
+      idle-timeout = 300s
+      request-timeout = 20 s
+    }
+  }
+}
diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf
index 5f553c58dd73df1307ce5d9c6d28c5a48cb05928..333813a1dedc7f79090e077f1d826763ea6521f8 100644
--- a/src/main/resources/application.conf
+++ b/src/main/resources/application.conf
@@ -1,73 +1,3 @@
-akka {
-  loglevel = "WARNING"
-  loglevel = ${?LOG_LEVEL}
-  stdout-loglevel = "WARNING"
-  stdout-loglevel = ${?LOG_LEVEL}
-  loggers = ["akka.event.slf4j.Slf4jLogger"]
-  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
+# No specific configuration for Portal backend
+# All configuration is related to Akka
 
-  log-config-on-start = off
-  log-config-on-start = ${?LOG_CONFIG}
-
-  log-dead-letters = 10
-  log-dead-letters-during-shutdown = off
-
-  actor {
-    provider = "cluster"
-
-    allow-java-serialization = off
-    enable-additional-serialization-bindings = true
-
-  }
-
-  remote {
-    log-sent-messages = on
-    log-received-messages = on
-    log-remote-lifecycle-events = on
-
-    maximum-payload-bytes = 10000000 bytes
-
-    watch-failure-detector {
-      acceptable-heartbeat-pause = 20 s
-    }
-
-    artery {
-      enabled = on
-      transport = tcp
-
-      canonical.hostname = ${clustering.ip} # external (logical) hostname
-      canonical.port = ${clustering.port}   # external (logical) port
-
-      bind.hostname = 0.0.0.0         # internal (bind) hostname
-      bind.port = ${clustering.port}  # internal (bind) port
-
-    }
-
-  }
-
-  cluster {
-    seed-nodes = [
-      "akka://"${clustering.cluster.name}"@"${clustering.seed-ip}":"${clustering.seed-port}
-    ]
-
-    roles = ["portal"]
-
-  }
-
-  extensions += "akka.cluster.pubsub.DistributedPubSub"
-
-}
-
-clustering {
-  ip = "127.0.0.1"
-  ip = ${?CLUSTER_IP}
-  port = 4089
-  port = ${?CLUSTER_PORT}
-  seed-ip = "woken"
-  seed-ip = ${?CLUSTER_IP}
-  seed-ip = ${?WOKEN_PORT_8088_TCP_ADDR}
-  seed-port = 8088
-  seed-port = ${?WOKEN_PORT_8088_TCP_PORT}
-  cluster.name = "woken"
-  cluster.name = ${?CLUSTER_NAME}
-}
diff --git a/src/main/resources/kamon.conf b/src/main/resources/kamon.conf
new file mode 100644
index 0000000000000000000000000000000000000000..00b068b2199b6105255f66e86b23d67ece3e75c8
--- /dev/null
+++ b/src/main/resources/kamon.conf
@@ -0,0 +1,65 @@
+kamon {
+  enabled = no
+  enabled = ${?KAMON_ENABLED}
+
+  environment {
+    service = "woken"
+  }
+
+  zipkin = {
+    enabled = no
+    enabled = ${?ZIPKIN_ENABLED}
+    host = "zipkin"
+    host = ${?ZIPKIN_IP}
+    port = 9411
+    port = ${?ZIPKIN_PORT}
+  }
+
+  prometheus = {
+    enabled = no
+    enabled = ${?PROMETHEUS_ENABLED}
+    host = "prometheus"
+    host = ${?PROMETHEUS_IP}
+    port = 9090
+    port = ${?PROMETHEUS_PORT}
+  }
+
+  util.filters {
+    "akka.tracked-actor" {
+      includes = ["**"]
+    }
+
+    "akka.tracked-dispatcher" {
+      includes = ["**"]
+    }
+
+    "akka.traced-actor" {
+      includes = ["**"]
+    }
+
+  }
+
+  akka-http {
+    add-http-status-code-as-metric-tag = true
+  }
+
+  akka {
+    ask-pattern-timeout-warning = lightweight
+  }
+
+  trace {
+    join-remote-parents-with-same-span-id = yes
+  }
+
+  system-metrics {
+    host {
+      enabled = no
+      enabled = ${?SIGAR_SYSTEM_METRICS}
+    }
+    jvm {
+      enabled = no
+      enabled = ${?JVM_SYSTEM_METRICS}
+    }
+  }
+
+}
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index c1339c7b2b5e52cf61c7bb41bb7b3ba59c451460..659940446830b456353b9f8510ff4f1428fcad39 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -10,25 +10,25 @@
     <Root level="DEBUG">
       <AppenderRef ref="Console"/>
     </Root>
-    <Logger name="akka.actor.LocalActorRefProvider(akka://woken)" level="info">
+    <Logger name="akka.actor.LocalActorRefProvider(akka://woken)" level="INFO">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="akka.cluster" level="info">
+    <Logger name="akka.cluster" level="${sys:AKKA_CLUSTER_LOG_LEVEL:-INFO}">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="akka.io" level="info">
+    <Logger name="akka.io" level="INFO">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="akka.http.impl" level="info">
+    <Logger name="akka.http.impl" level="INFO">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="akka.remote.artery.compress" level="info">
+    <Logger name="akka.remote.artery.compress" level="${sys:AKKA_CLUSTER_LOG_LEVEL:-INFO}">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="akka.remote.artery.tcp" level="info">
+    <Logger name="akka.remote.artery.tcp" level="${sys:AKKA_CLUSTER_LOG_LEVEL:-INFO}">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="akka.stream.impl" level="info">
+    <Logger name="akka.stream.impl" level="INFO">
       <AppenderRef ref="Console"/>
     </Logger>
   </Loggers>
diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf
new file mode 100644
index 0000000000000000000000000000000000000000..c6ce4a9034d3dcca6d4d801997217c78b775684b
--- /dev/null
+++ b/src/main/resources/reference.conf
@@ -0,0 +1,12 @@
+
+app {
+  clusterSystemName = ${clustering.cluster.name}
+}
+
+# Merged with defaults in woken-messages/reference.conf
+clustering {
+  ip = "127.0.0.1"
+  ip = ${?CLUSTER_IP}
+  port = 4489
+  port = ${?CLUSTER_PORT}
+}