diff --git a/deploy_stack.sh b/deploy_stack.sh
index c55fc2714710120af18e1a25c2056208cbb7a99b..a900d6d5c75bcce423e10528767f07bb38e67f18 100755
--- a/deploy_stack.sh
+++ b/deploy_stack.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
 
 echo "Deploying stack"
-docker stack rm func ;  docker stack deploy func --compose-file docker-compose.yml 
+docker stack deploy func --compose-file docker-compose.yml 
diff --git a/docker-compose.yml b/docker-compose.yml
index e613213bde54a1ade3e1653926c2e0b6d9a4d602..cf66e1daf0c45439a02e416a4287254075cd552d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -104,6 +104,15 @@ services:
             no_proxy:   "gateway"
             https_proxy: $https_proxy
 
+    markdown:
+        image: alexellis2/faas-markdownrender:latest
+        depends_on:
+            - gateway
+        networks:
+            - functions
+        environment:
+            no_proxy:   "gateway"
+            https_proxy: $https_proxy
 
     # alexacolorchange:
     #     image: alexellis2/faas-alexachangecolorintent 
diff --git a/gateway/assets/index.html b/gateway/assets/index.html
index 43b0c7ce7faa59fd005269a8719c2dff6727b5b7..6f6f5d13814b6fba7066556c8e6f9e6293032be3 100644
--- a/gateway/assets/index.html
+++ b/gateway/assets/index.html
@@ -50,11 +50,11 @@
       </div>
       <div flex></div>
     </md-content>
+
     <md-content flex layout="column" ng-repeat="function in functions" ng-show="function.name == selectedFunction.name">
 
         <md-card md-theme="default" md-theme-watch>
             <md-card-title>
-
                 <md-card-title-text>
 
                     <span class="md-headline">
@@ -77,12 +77,44 @@
                         <input ng-model="function.image" type="text" readonly="readonly">
                       </md-input-container>
                     </div>
-
                 <md-card-title-text>
-
             </md-card-title>
         </md-card>
-
+        <md-card>
+         <md-card-title>
+            <md-card-title-text>
+
+                <span class="md-headline">
+                  Invoke function
+                </span>
+                <div layout-gt-sm="row">
+                  <md-input-container class="md-block" flex-gt-sm>
+                    <button ng-click="fireRequest()" class="md-raised md-button md-ink-ripple" type="button">
+                      <span class="ng-scope">Invoke</span><div class="md-ripple-container"></div>
+                    </button>
+                  </md-input-container>
+                </div>
+                <div layout-gt-sm="row">
+                  <md-input-container class="md-block" flex-gt-sm>
+                    <label>Request body</label>
+                    <textarea ng-model="invocation.request" cols="80" rows="4"></textarea>
+                  </md-input-container>
+                </div>
+                <div layout-gt-sm="row">
+                  <md-input-container class="md-block" flex-gt-sm>
+                    <label>Response status</label>
+                    <input ng-model="invocationStatus" type="text" readonly="readonly">
+                  </md-input-container>
+                </div>
+                <div layout-gt-sm="row">
+                  <md-input-container class="md-block" flex-gt-sm>
+                    <label>Response body</label>
+                    <textarea ng-model="invocationResponse" cols="80" rows=10></textarea>
+                  </md-input-container>
+                </div>
+            <md-card-title-text>
+        </md-card-title>
+    </md-card>
     </md-content>
   </section>
   </div>
diff --git a/gateway/assets/script/bootstrap.js b/gateway/assets/script/bootstrap.js
index 43ca49e0b74dc73c56abb574ae4da33f49db7c5b..d147be427e1203a974787c7ea3258616f8ab1d21 100644
--- a/gateway/assets/script/bootstrap.js
+++ b/gateway/assets/script/bootstrap.js
@@ -3,11 +3,55 @@ var app = angular.module('faasGateway', ['ngMaterial']);
 
 app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', function($scope, $log, $http, $location, $timeout) {
     $scope.functions = [];
+    $scope.invocationRequest = "";
+    $scope.invocationResponse = "";
+    $scope.invocationStatus = "";
+    $scope.invocation = {
 
+    };
+    $scope.invocation.request = ""
     setInterval(function() {
-        fetch();
+        refreshData();
     }, 1000);
 
+    $scope.fireRequest = function() {
+        $http({url:"/function/"+$scope.selectedFunction.name, data: $scope.invocation.request, method: "POST",  headers: {"Content-Type": "text/plain"}, responseType: "text"}).
+        then(function(response) {
+            $scope.invocationResponse = response.data;
+            $scope.invocationStatus = response.status;
+        }).catch(function(error1) {
+            $scope.invocationResponse = error1;
+            $scope.invocationStatus = null;
+        });
+
+        // console.log("POST /function/"+ $scope.selectedFunction.name);
+        // console.log("Body: " + $scope.invocation.request);
+    };
+
+    var refreshData = function () {
+        var previous = $scope.functions;
+
+        var cl = function(previousItems) {
+            $http.get("/system/functions").then(function(response) {
+                if(response && response.data) {
+                    if(previousItems.length !=response.data.length) {
+                        $scope.functions = response.data;
+                    } else {
+                        for(var i =0;i<$scope.functions.length;i++) {
+                            for(var j =0;j<response.data.length;j++) {
+                                if($scope.functions[i].name == response.data[j].name) {
+                                    $scope.functions[i].replicas=response.data[j].replicas;
+                                    $scope.functions[i].invocationCount=response.data[j].invocationCount;
+                                }
+                            }
+                        }
+                    }
+                }
+            });
+        };
+        cl(previous);
+    }
+
     var fetch = function() {
         $http.get("/system/functions").then(function(response) {
             $scope.functions = response.data;
@@ -15,7 +59,12 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', func
     };
 
     $scope.showFunction = function(fn) {
-        $scope.selectedFunction = fn;
+        if($scope.selectedFunction!=fn) {
+            $scope.selectedFunction = fn;
+            $scope.invocation.request = "";
+            $scope.invocationResponse = "";
+            $scope.invocationStatus = "";
+        }
     };
 
     // TODO: popup + form to create new Docker service.
diff --git a/gateway/build.sh b/gateway/build.sh
index 8e34c77983e60f1eb1e26614bfa55da0df077f25..c000c144704ebe43cd898b0889860d1d52afadb2 100755
--- a/gateway/build.sh
+++ b/gateway/build.sh
@@ -10,4 +10,4 @@ docker rm -f gateway_extract
 
 echo Building alexellis2/faas-gateway:latest
 
-docker build -t alexellis2/faas-gateway:latest-dev4 .
+docker build --no-cache -t alexellis2/faas-gateway:latest-dev4 .
diff --git a/sample-functions/MarkdownRender/Dockerfile b/sample-functions/MarkdownRender/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..1ef8f96015c171738127a59cb7bc44004b479f8f
--- /dev/null
+++ b/sample-functions/MarkdownRender/Dockerfile
@@ -0,0 +1,16 @@
+FROM alpine:latest
+
+WORKDIR /root/
+
+EXPOSE 8080
+ENV http_proxy      ""
+ENV https_proxy     ""
+
+ADD https://github.com/alexellis/faas/releases/download/v0.3-alpha/fwatchdog /usr/bin
+RUN chmod +x /usr/bin/fwatchdog
+# COPY fwatchdog  /usr/bin/
+
+COPY app    .
+
+ENV fprocess="/root/app"
+CMD ["fwatchdog"]
diff --git a/sample-functions/MarkdownRender/Dockerfile.build b/sample-functions/MarkdownRender/Dockerfile.build
new file mode 100644
index 0000000000000000000000000000000000000000..f8697c190f512831fcd25489ce5a7462cce98c9c
--- /dev/null
+++ b/sample-functions/MarkdownRender/Dockerfile.build
@@ -0,0 +1,10 @@
+FROM golang:1.7.3
+RUN mkdir -p /go/src/app
+COPY handler.go /go/src/app
+WORKDIR /go/src/app
+RUN go get github.com/microcosm-cc/bluemonday && \
+    go get github.com/russross/blackfriday
+
+RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
+
+CMD ["echo"]
diff --git a/sample-functions/MarkdownRender/MarkdownRender b/sample-functions/MarkdownRender/MarkdownRender
new file mode 100755
index 0000000000000000000000000000000000000000..7063de3120af1e619e8b760ef0e65cf64667d363
Binary files /dev/null and b/sample-functions/MarkdownRender/MarkdownRender differ
diff --git a/sample-functions/MarkdownRender/app b/sample-functions/MarkdownRender/app
new file mode 100755
index 0000000000000000000000000000000000000000..6dcb3f568012871530382c4914881a22c739918c
Binary files /dev/null and b/sample-functions/MarkdownRender/app differ
diff --git a/sample-functions/MarkdownRender/build.sh b/sample-functions/MarkdownRender/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..12a2f2857161f8cbb054cf91558a63285f33c42f
--- /dev/null
+++ b/sample-functions/MarkdownRender/build.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+echo Building alexellis2/faas-markdownrender:build
+
+docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
+    -t alexellis2/faas-markdownrender . -f Dockerfile.build
+
+docker create --name render_extract alexellis2/faas-markdownrender
+docker cp render_extract:/go/src/app/app ./app
+docker rm -f render_extract
+
+echo Building alexellis2/faas-markdownrender:latest
+docker build --no-cache -t alexellis2/faas-markdownrender:latest .
diff --git a/sample-functions/MarkdownRender/handler.go b/sample-functions/MarkdownRender/handler.go
new file mode 100644
index 0000000000000000000000000000000000000000..748d05601a575fa44174a17e6ff7c6e10401dc2e
--- /dev/null
+++ b/sample-functions/MarkdownRender/handler.go
@@ -0,0 +1,17 @@
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"github.com/microcosm-cc/bluemonday"
+	"github.com/russross/blackfriday"
+)
+
+func main() {
+	input, _ := ioutil.ReadAll(os.Stdin)
+	unsafe := blackfriday.MarkdownCommon([]byte(input))
+	html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
+	fmt.Println(string(html))
+}