diff --git a/msa/integration-tests/README.md b/msa/integration-tests/README.md
new file mode 100644
index 0000000000..5ae6354740
--- /dev/null
+++ b/msa/integration-tests/README.md
@@ -0,0 +1,18 @@
+
+## Integration tests execution
+To run the integration tests with using Docker, the local Docker images of Thingsboard's microservices should be built. 
+- Build the local Docker images in the directory with the Thingsboard's main [pom.xml](./../../pom.xml):
+        
+        mvn clean install -Ddockerfile.skip=false
+- Verify that the new local images were built: 
+
+        docker image ls
+As result, in REPOSITORY column, next images should be present:
+        
+        local-maven-build/tb-node
+        local-maven-build/tb-web-ui
+        local-maven-build/tb-web-ui 
+
+- Run the integration tests in the [msa/integration-tests](../integration-tests) directory:
+
+        mvn clean install -Dintegrationtests.skip=false
\ No newline at end of file
diff --git a/msa/integration-tests/pom.xml b/msa/integration-tests/pom.xml
new file mode 100644
index 0000000000..a1c24f39c6
--- /dev/null
+++ b/msa/integration-tests/pom.xml
@@ -0,0 +1,98 @@
+
+
+    4.0.0
+
+    
+        org.thingsboard
+        2.2.0-SNAPSHOT
+        msa
+    
+    org.thingsboard.msa
+    integration-tests
+
+    ThingsBoard Integration Tests
+    https://thingsboard.io
+    Project for ThingsBoard integration tests with using Docker
+
+    
+        UTF-8
+        ${basedir}/../..
+        true
+        1.9.1
+        1.3.9
+    
+
+    
+        
+            org.testcontainers
+            testcontainers
+            ${testcontainers.version}
+        
+        
+            org.java-websocket
+            Java-WebSocket
+            ${java-websocket.version}
+        
+        
+            io.takari.junit
+            takari-cpsuite
+        
+        
+            ch.qos.logback
+            logback-classic
+        
+        
+            com.google.code.gson
+            gson
+        
+        
+            org.apache.commons
+            commons-lang3
+        
+        
+            com.google.guava
+            guava
+        
+        
+            org.thingsboard
+            netty-mqtt
+        
+        
+            org.thingsboard
+            tools
+        
+    
+
+    
+        
+            
+                org.apache.maven.plugins
+                maven-surefire-plugin
+                
+                    
+                        **/*TestSuite.java
+                    
+                    ${integrationtests.skip}
+                
+            
+        
+    
+
+
diff --git a/msa/integration-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java b/msa/integration-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
new file mode 100644
index 0000000000..ab7f101f98
--- /dev/null
+++ b/msa/integration-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright © 2016-2018 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.msa;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.*;
+import org.thingsboard.client.tools.RestClient;
+import org.thingsboard.server.common.data.Device;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.id.DeviceId;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public abstract class AbstractContainerTest {
+    protected static String httpUrl;
+    protected static String wsUrl;
+    protected static RestClient restClient;
+    protected ObjectMapper mapper = new ObjectMapper();
+
+    @BeforeClass
+    public static void before() {
+        httpUrl = "http://localhost:" + ContainerTestSuite.composeContainer.getServicePort("tb-web-ui1", ContainerTestSuite.EXPOSED_PORT);
+        wsUrl = "ws://localhost:" + ContainerTestSuite.composeContainer.getServicePort("tb-web-ui1", ContainerTestSuite.EXPOSED_PORT);
+        restClient = new RestClient(httpUrl);
+    }
+
+    protected Device createDevice(String name) {
+        return restClient.createDevice(name + RandomStringUtils.randomAlphanumeric(7), "DEFAULT");
+    }
+
+    protected WsClient subscribeToTelemetryWebSocket(DeviceId deviceId) throws URISyntaxException, InterruptedException {
+        WsClient mWs = new WsClient(new URI(wsUrl + "/api/ws/plugins/telemetry?token=" + restClient.getToken()));
+        mWs.connectBlocking(1, TimeUnit.SECONDS);
+
+        JsonObject tsSubCmd = new JsonObject();
+        tsSubCmd.addProperty("entityType", EntityType.DEVICE.name());
+        tsSubCmd.addProperty("entityId", deviceId.toString());
+        tsSubCmd.addProperty("scope", "LATEST_TELEMETRY");
+        tsSubCmd.addProperty("cmdId", new Random().nextInt(100));
+        tsSubCmd.addProperty("unsubscribe", false);
+        JsonArray wsTsSubCmds = new JsonArray();
+        wsTsSubCmds.add(tsSubCmd);
+        JsonObject wsRequest = new JsonObject();
+        wsRequest.add("tsSubCmds", wsTsSubCmds);
+        wsRequest.add("historyCmds", new JsonArray());
+        wsRequest.add("attrSubCmds", new JsonArray());
+        mWs.send(wsRequest.toString());
+        return mWs;
+    }
+
+    protected Map getExpectedLatestValues(long ts) {
+        return ImmutableMap.builder()
+                .put("booleanKey", ts)
+                .put("stringKey", ts)
+                .put("doubleKey", ts)
+                .put("longKey", ts)
+                .build();
+    }
+
+    protected boolean verify(WsTelemetryResponse wsTelemetryResponse, String key, Long expectedTs, String expectedValue) {
+        List