diff --git a/.travis.yml b/.travis.yml
index 64ec3eeb48f0dcd7d1334def2707af37d4fefdbd..daaf24c01d39adb7cb75ee2eb727acfb5c3d2c6d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,13 +5,67 @@ services:
 
 language: cpp
 
+env:
+  matrix:
+    - OPENDHT_TEST_JOB="opendht.classic"
+    - OPENDHT_TEST_JOB="opendht.llvm"
+    - OPENDHT_TEST_JOB="opendht.proxyserver"
+    - OPENDHT_TEST_JOB="opendht.proxyclient"
+    - OPENDHT_TEST_JOB="opendht.proxyserverpush"
+    - OPENDHT_TEST_JOB="opendht.proxyclientpush"
+    - OPENDHT_TEST_JOB="opendht.all"
+
 before_install:
-- docker pull aberaud/opendht-deps
-- docker pull aberaud/opendht-deps-llvm
+  - |
+    # non llvm builds
+    if [[ "$OPENDHT_TEST_JOB" != *"opendht.llvm"* ]]; then
+      docker pull aberaud/opendht-deps;
+      if [[ "$OPENDHT_TEST_JOB" != *"opendht.classic"* ]]; then
+        docker build -t opendht-deps-proxy -f docker/DockerfileDepsProxy .;
+      fi
+    fi
+
+  - |
+    # classic build
+    if [[ "$OPENDHT_TEST_JOB" == *"opendht.llvm"* ]]; then
+      docker pull aberaud/opendht-deps-llvm
+    fi
 
 script:
-- docker build -f docker/DockerfileTravis .
-- docker build -f docker/DockerfileTravisLlvm .
+  - |
+    # classic build
+    if [[ "$OPENDHT_TEST_JOB" == *"opendht.classic"* ]]; then
+      docker build -t opendht -f docker/DockerfileTravis .;
+    fi
+
+  - |
+    # proxy builds
+    if [[ "$OPENDHT_TEST_JOB" != *"opendht.llvm"* ]] && [[ "$OPENDHT_TEST_JOB" != *"opendht.classic"* ]]; then
+      docker build -t opendht-proxy -f docker/DockerfileTravisProxy .;
+      options='';
+      if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyserver"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyserverpush"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.all"* ]]; then
+        options+='-DOPENDHT_PROXY_SERVER=ON ';
+      else
+        options+='-DOPENDHT_PROXY_SERVER=OFF ';
+      fi
+      if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyclient"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyclientpush"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.all"* ]]; then
+        options+='-DOPENDHT_PROXY_CLIENT=ON ';
+      else
+        options+='-DOPENDHT_PROXY_CLIENT=OFF ';
+      fi
+      if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyserverpush"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyclientpush"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.all"* ]]; then
+        options+='-DOPENDHT_PUSH_NOTIFICATIONS=ON ';
+      else
+        options+='-DOPENDHT_PUSH_NOTIFICATIONS=OFF ';
+      fi
+      docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON $options .. && make -j8 && make install";
+    fi
+
+  - |
+    # llvm build
+    if [[ "$OPENDHT_TEST_JOB" == *"opendht.llvm"* ]]; then
+      docker build -f docker/DockerfileTravisLlvm .
+    fi
 
 notifications:
   email:
diff --git a/docker/DockerfileDepsProxy b/docker/DockerfileDepsProxy
new file mode 100644
index 0000000000000000000000000000000000000000..346b7d89885a7ed78e0b160a8348c96c222905e4
--- /dev/null
+++ b/docker/DockerfileDepsProxy
@@ -0,0 +1,16 @@
+FROM aberaud/opendht-deps
+
+# install jsoncpp
+RUN apt-get install libjsoncpp-dev -y
+
+# install restbed dependencies
+RUN sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list # LTS... avoid 404 for libasio-dev
+RUN apt-get update -y
+RUN apt-get install libasio-dev -y
+
+# build restbed from sources
+RUN git clone --recursive https://github.com/corvusoft/restbed.git
+WORKDIR restbed/build
+RUN cmake -DBUILD_TESTS=NO -DBUILD_EXAMPLES=NO -DBUILD_SSL=NO -DBUILD_SHARED=YES -DCMAKE_INSTALL_PREFIX=/usr ..
+RUN make -j 8 install
+RUN mv /usr/library/librestbed* /usr/lib/
diff --git a/docker/DockerfileLlvm b/docker/DockerfileLlvm
deleted file mode 100644
index 9bbe5880112f6388544f16433b0a102efe014616..0000000000000000000000000000000000000000
--- a/docker/DockerfileLlvm
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM aberaud/opendht-deps-llvm
-MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
-RUN git clone https://github.com/savoirfairelinux/opendht.git \
-	&& cd opendht && mkdir build && cd build \
-	&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On && make -j8 && make install \
-	&& cd ../.. && rm -rf opendht
diff --git a/docker/DockerfileTravis b/docker/DockerfileTravis
index dcb8a2670f252c36c24515a507748e4bbb95f834..693827eb0dc0469e9fac2b57b3216de29f59c319 100644
--- a/docker/DockerfileTravis
+++ b/docker/DockerfileTravis
@@ -2,5 +2,4 @@ FROM aberaud/opendht-deps
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
 COPY . /root/opendht
 RUN cd /root/opendht && mkdir build && cd build \
-	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On .. && make -j8 && make install \
-	&& cd ../.. && rm -rf opendht
+	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On .. && make -j8 && make install
diff --git a/docker/DockerfileTravisLlvm b/docker/DockerfileTravisLlvm
index b00d3d91686e4d308f1517fc2d0692629c004e2a..c32a9fd8df95f649ee4463436a20458e6dd9a6bf 100644
--- a/docker/DockerfileTravisLlvm
+++ b/docker/DockerfileTravisLlvm
@@ -2,5 +2,4 @@ FROM aberaud/opendht-deps-llvm
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
 COPY . /root/opendht
 RUN cd /root/opendht && mkdir build && cd build \
-	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On .. && make -j8 && make install \
-	&& cd ../.. && rm -rf opendht
+	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On .. && make -j8 && make install
diff --git a/docker/DockerfileTravisProxy b/docker/DockerfileTravisProxy
new file mode 100644
index 0000000000000000000000000000000000000000..b543e61afba4947878732fd959019f84bbf0bc51
--- /dev/null
+++ b/docker/DockerfileTravisProxy
@@ -0,0 +1,3 @@
+FROM opendht-deps-proxy
+MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+COPY . /root/opendht
diff --git a/include/opendht/dht_proxy_client.h b/include/opendht/dht_proxy_client.h
index 8fd8f5ba369433a63e204b8269803d4872f82c19..b0edcf532d76b982cfc60bbae7e50d369cfdb3fb 100644
--- a/include/opendht/dht_proxy_client.h
+++ b/include/opendht/dht_proxy_client.h
@@ -47,11 +47,11 @@ public:
 
     explicit DhtProxyClient(std::function<void()> loopSignal, const std::string& serverHost, const std::string& pushClientId = "");
 
-#if OPENDHT_PUSH_NOTIFICATIONS
     virtual void setPushNotificationToken(const std::string& token) {
+#if OPENDHT_PUSH_NOTIFICATIONS
         deviceKey_ = token;
-    }
 #endif
+    }
 
     virtual ~DhtProxyClient();
 
@@ -167,7 +167,6 @@ public:
     }
     virtual bool cancelListen(const InfoHash&, size_t token);
 
-#if OPENDHT_PUSH_NOTIFICATIONS
     /**
      * Call linked callback with a push notification
      * @param notification to process
@@ -178,7 +177,6 @@ public:
      * @param token
      */
     void resubscribe(const unsigned token);
-#endif // OPENDHT_PUSH_NOTIFICATIONS
 
     time_point periodic(const uint8_t*, size_t, const SockAddr&);
     time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) {
diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h
index 51dc56aa0db0391a3f9bc360f6bdec04bd117299..eab3490ce28ed28a791e08529c9824a819dc19b4 100644
--- a/include/opendht/dht_proxy_server.h
+++ b/include/opendht/dht_proxy_server.h
@@ -218,8 +218,8 @@ private:
     mutable std::mutex lockPushListeners_;
     mutable std::vector<PushListener> pushListeners_;
     mutable unsigned tokenPushNotif_ {0};
-    const std::string pushServer_;
 #endif //OPENDHT_PUSH_NOTIFICATIONS
+    const std::string pushServer_;
 
     /**
      * Remove finished listeners
diff --git a/include/opendht/securedht.h b/include/opendht/securedht.h
index 7c61c98345ea36f194b69fd2683cb6ad97990313..7d300fba2a0636935b4e7985706110027d58c738 100644
--- a/include/opendht/securedht.h
+++ b/include/opendht/securedht.h
@@ -293,14 +293,14 @@ public:
         dht_->connectivityChanged();
     }
 
-    void setPushNotificationToken(const std::string& token = "") {
-        dht_->setPushNotificationToken(token);
-    }
-
     void forwardAllMessages(bool forward) {
         forward_all_ = forward;
     }
 
+    void setPushNotificationToken(const std::string& token = "") {
+        dht_->setPushNotificationToken(token);
+    }
+
     /**
      * Call linked callback with push_notification
      * @param notification to process
diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp
index 8794c9855e0e0777d34ea3d52e8b372d741d8438..5d76389af29ce97dc911a8ddc4b385cc92db8afd 100644
--- a/src/dht_proxy_client.cpp
+++ b/src/dht_proxy_client.cpp
@@ -659,10 +659,10 @@ DhtProxyClient::restartListeners()
     }
 }
 
-#if OPENDHT_PUSH_NOTIFICATIONS
 void
 DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string>& notification)
 {
+#if OPENDHT_PUSH_NOTIFICATIONS
     try {
         auto token = std::stoul(notification.at("token"));
         for (const auto& listener: listeners_) {
@@ -680,11 +680,13 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
     } catch (...) {
 
     }
+#endif
 }
 
 void
 DhtProxyClient::resubscribe(const unsigned token)
 {
+#if OPENDHT_PUSH_NOTIFICATIONS
     if (deviceKey_.empty()) return;
     for (auto& listener: listeners_) {
         if (*(listener.pushNotifToken) == token) {
@@ -734,8 +736,10 @@ DhtProxyClient::resubscribe(const unsigned token)
             });
         }
     }
+#endif
 }
 
+#if OPENDHT_PUSH_NOTIFICATIONS
 void
 DhtProxyClient::fillBodyToGetToken(std::shared_ptr<restbed::Request> req)
 {
diff --git a/src/dhtrunner.cpp b/src/dhtrunner.cpp
index e511a1c28a93505b6f4690195a324327122bfcd3..5f8ac96fc7a127357bf81206db8e54e7c8ca126f 100644
--- a/src/dhtrunner.cpp
+++ b/src/dhtrunner.cpp
@@ -918,19 +918,6 @@ DhtRunner::enableProxy(bool proxify)
 #endif
 }
 
-
-/**
- * Updates the push notification device token
- */
-void
-DhtRunner::setPushNotificationToken(const std::string& token) {
-#if OPENDHT_PROXY_CLIENT && OPENDHT_PUSH_NOTIFICATIONS
-    pushToken_ = token;
-    if (dht_via_proxy_)
-        dht_via_proxy_->setPushNotificationToken(token);
-#endif
-}
-
 void
 DhtRunner::forwardAllMessages(bool forward)
 {
@@ -944,6 +931,18 @@ DhtRunner::forwardAllMessages(bool forward)
 #endif // OPENDHT_PROXY_SERVER
 }
 
+/**
+ * Updates the push notification device token
+ */
+void
+DhtRunner::setPushNotificationToken(const std::string& token) {
+#if OPENDHT_PROXY_CLIENT && OPENDHT_PUSH_NOTIFICATIONS
+    pushToken_ = token;
+    if (dht_via_proxy_)
+        dht_via_proxy_->setPushNotificationToken(token);
+#endif
+}
+
 void
 DhtRunner::pushNotificationReceived(const std::map<std::string, std::string>& data) const
 {
diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp
index 7a7bbdbbd47b09eda57aacab992b4ac3bcafc3b9..2b5909106ceab9f33541396f640f2682008fc164 100644
--- a/tools/dhtnode.cpp
+++ b/tools/dhtnode.cpp
@@ -219,12 +219,6 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params
 #endif //OPENDHT_PROXY_SERVER
 #if OPENDHT_PROXY_CLIENT
         else if (op == "stt") {
-            /*iss >> idstr >> deviceKey;
-#if OPENDHT_PUSH_NOTIFICATIONS
-            if (not deviceKey.empty())
-                dht->setPushNotificationToken(deviceKey);
-#endif // OPENDHT_PUSH_NOTIFICATIONS
-            dht->setProxyServer(idstr);*/
             dht->enableProxy(true);
             continue;
         } else if (op == "stp") {