Docker Swarm Sample

Docker swarm sample with NodeJS app on Hyper-V

Prerequisites


  • This sample is using Hyper-V

1. Clone sample repository

git clone https://github.com/wswijaya/docker-swarm-node-app.git

2. Build Docker Image and push to Docker Hub

docker build -t /node-app-sample .
docker push /node-app-sample

3. Create VMs

docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm3
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm2
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm3
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm4

4. Create Docker Swarm and set VM1, VM3, and VM4 as manager

docker-machine ssh myvm1 "docker swarm init"
docker-machine ssh myvm1 "docker swarm join-token manager"
docker-machine ssh myvm3 "docker swarm join --token :"
docker-machine ssh myvm4 "docker swarm join --token :"
docker-machine ssh myvm1 "docker swarm join-token worker"
docker-machine ssh myvm2 "docker swarm join --token :"

5. Deploy Services

docker-machine scp docker-compose-node-app.yml myvm1:~
docker-machine ssh myvm1 "docker stack deploy -c docker-compose-node-app.yml nodeapplab"
docker-machine ssh myvm1 "docker stack ps nodeapplab"

6. Test Site

7. Remove Services

docker-machine ssh myvm1 "docker stack rm nodeapplab"

8. Remove Docker Swarm

docker-machine ssh myvm1 "docker stack rm nodeapplab"
docker-machine ssh myvm2 "docker swarm leave"
docker-machine ssh myvm3 "docker swarm leave --force"
docker-machine ssh myvm4 "docker swarm leave --force"
docker-machine ssh myvm1 "docker swarm leave --force"

Optional: Configure Load Balancer using HAProxy

Installation steps for HAProxy on Ubuntu -> How to use HAProxy

Sample config file /etc/haproxy/haproxy.cfg

global
daemon
maxconn 200

defaults
mode http
timeout connect 5000ms
timeout client 10000ms
timeout server 10000ms

frontend http-in
bind *:9090
default_backend servers

backend servers
server vm1 : maxconn 40
server vm3 : maxconn 40
server vm4 : maxconn 40

HTML5 @Google I/O 2011

Just sharing some of the talk/presentations on HTML5 at Google I/O 2011. HTML5 seems to be moving fast and you will see some of the cool stuff in the “HTML5 versus Android” demo,

  • I/O BootCamp 2011: Getting Started with HTML5

 

  • HTML5 Showcase for Web Developers: The Wow and the How

 

  • HTML5 and What’s Next

 

  • GWT + HTML5: A web developers dream!

 

  • HTML5 vs. Android: Apps or Web Mobile Development?

 

  • HTML5 Today with Google Chrome Frame

 

  • Kick-Ass Game Programming with Google Web Toolkit

 

 

Sencha Touch MVC Application – Part 1

Developing MVC application is nothing new and there are many frameworks to help us implement MVC, e.g. Struts & Spring MVC (JEE), ASP.NET MVC, JavaScriptMVC, etc. If you are a mobile apps developer and using Sencha Touch, you will most likely wonder whether or not you can apply MVC to simplify your apps design and make it more maintainable.

Here I am sharing a useful presentation by Tommy Maintz (@tommymaintz). This presentation will bring you a step further into a better Sencha Touch mobile apps design by structuring your apps and applying MVC pattern.

Countdown to ExtJS 4

On the 16th Feb 2010 Sencha announced the availability of the first Ext JS 4 Developer Preview. Definitely an exciting news for the Ext JS developers, I can see from the comments in Sencha Blog that people cannot wait for the release. This is the biggest overhaul to the framework. For those who worry about migration, the team has taken that into consideration.

Ext JS 4 is completely sandboxed; there is no more native object augmentation or reliance on global variables. This means you can run Ext JS 4 alongside Ext JS 3 on the same page. To demonstrate this we’ve taken the best of both versions and combined them in a single page. We’ve used the Desktop example from Ext JS 3 and loaded Ext JS 4’s brand new charts alongside as if they were part of Desktop itself – check it out for yourself.

The second step is to provide as strong a legacy layer as possible to help you upgrade your Ext JS 3.x applications. We’re starting that today with the release of a detailed overview guide to the differences between the versions, and will update this as we continue our rollout. In addition to the guide we will be providing a legacy file that can be dropped in to an Ext JS 3.x application to help you upgrade your app. We’ll be expanding on both of these in another post very soon. – Sencha Blog

The following articles highlights the key features in Ext JS 4;

Ed Spencer from Sencha presented the introduction to Ext JS 4 and its architecture. You can see the slides below;

Last but not least, the examples and download is available;

Happy hacking!!

Safari5 Unable To Get Geolocation, Why?

With the latest release of Safari, the browser claims to support HTML5. A few days ago, I got a feedback that the NearBy Tweet prototype is not working in Safari5 (desktop). I never test it in Safari before, and turn out it doesn’t work due to no geolocation detected. So I tried map.google.com, it was unable to show my location as well. See screenshot below.


After a bit of digging around, It turns out Safari5 is using CoreLocation (wifi triangulation) to get geolocation data and it is only works when Wifi is ON. If you are using Safari5 on PC just turn on your wireless and if you are using Mac, just turn on Airport. It works!!

Find Destination (Lat,Lng) Given Distance & Bearing

Here, I will be posting a C# implementation to find a destination (latitude, longitude) given distance and bearing. This will be continuation from my previous post. Just add the method to the skeleton class GLatLng.

public GLatLng DestinationPoint(double dist, double brng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    dist = dist / R;
    brng = Math.PI * brng / 180;
    double lat1 = DegreeToRadian(latitude);
    double lon1 = DegreeToRadian(longitude);
<p>    double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(dist) + Math.Cos(lat1) * Math.Sin(dist) * Math.Cos(brng));
    double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(dist) * Math.Cos(lat1), Math.Cos(dist) - Math.Sin(lat1) * Math.Sin(lat2));
<p>    lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
    lat2 = RadianToDegree(lat2);
    lon2 = RadianToDegree(lon2);
<p>    GLatLng newLatLng = new GLatLng(lat2, lon2);
    return newLatLng;
} // end DestinationPoint
public GLatLng RhumbDestinationPoint(double dist, double brng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    double d = dist / R;  
    double lat1 = DegreeToRadian(this.latitude);
    double lon1 = DegreeToRadian(this.longitude);
    brng = DegreeToRadian(brng);
    double lat2 = lat1 + d * Math.Cos(brng);
    double dLat = lat2 - lat1;
    double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
    double q = Math.Cos(lat1);
    if (dPhi != 0) q = dLat / dPhi;  // E-W line gives dPhi=0
    double dLon = d * Math.Sin(brng) / q;
     if (Math.Abs(lat2) &gt; Math.PI / 2) lat2 = (lat2 &gt; 0) ? Math.PI - lat2 : -(Math.PI - lat2);
    double lon2 = (lon1 + dLon + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
   return new GLatLng(RadianToDegree(lat2), RadianToDegree(lon2));
} // end RhumbDestinationPoint

Calculate Distance & Bearing Between Geolocation

Recently, I toyed with “nearby” services based on geolocation. In this post, I will be sharing C# implementation to calculate distance and bearing between geolocation.  

Let’s start with the skeleton class GLatLng below

using System;

namespace GMap
{
    public enum DistanceType : int
    {
        Miles = 0,
        Kilometers = 1
    }
   
    public class GLatLng
    {
        public const double EarthRadiusInMiles = 3956.0;
        public const double EarthRadiusInKilometers = 6367.0;
       
        private double latitude;
        private double longitude;

        public GLatLng(double latitude, double longitude)
        {
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public double DegreeToRadian(double angle) { return Math.PI * angle / 180.0; }

        public double RadianToDegree(double angle) { return 180.0 * angle / Math.PI; }
       
        public double Latitude
        {
            get { return this.latitude; }
            set { this.latitude = value; }
        }
        public double Longitude
        {
            get { return this.longitude; }
            set { this.longitude = value; }
        }
    } // end class GLatLng
}

The following is the method to calculate the distance. You can choose the distance type between miles or kilometers. This uses haversine formula which give great-circle distances between two points on a sphere from their longitudes and latitudes.

public double DistanceTo(double lat, double lng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    double dLat = DegreeToRadian(lat) - DegreeToRadian(this.latitude);
    double dLon = DegreeToRadian(lng) - DegreeToRadian(this.longitude);
    double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(DegreeToRadian(this.latitude)) * Math.Cos(DegreeToRadian(lat)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
    double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
    double distance = c * R;

    return Math.Round(distance, 2);
} // end DistanceTo

The second way to calculate the distance is based on the rhumb line which generally longer than great-circle routes.

public double RhumbDistanceTo(double lat, double lng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    double lat1 = DegreeToRadian(this.latitude);
    double lat2 = DegreeToRadian(lat);
    double dLat = DegreeToRadian(lat - this.latitude);
    double dLon = DegreeToRadian(Math.Abs(lng - this.longitude));

    double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
    double q = Math.Cos(lat1);
    if (dPhi != 0) q = dLat / dPhi;  // E-W line gives dPhi=0
    // if dLon over 180° take shorter rhumb across 180° meridian:
    if (dLon > Math.PI) dLon = 2 * Math.PI - dLon;
    double dist = Math.Sqrt(dLat * dLat + q * q * dLon * dLon) * R;

    return dist;
} // end RhumbDistanceTo

Next methods calculate the bearing between geolocation. Similar to distance there are 2 ways to calculate the bearing.


public double RhumbBearingTo(double lat, double lng)
{
    double lat1 = DegreeToRadian(this.latitude);
    double lat2 = DegreeToRadian(lat);
    double dLon = DegreeToRadian(lng - this.longitude);

    double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
    if (Math.Abs(dLon) > Math.PI) dLon = (dLon > 0) ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
    double brng = Math.Atan2(dLon, dPhi);

    return (RadianToDegree(brng) + 360) % 360;
} // end RhumbBearingTo

public double BearingTo(double lat, double lng)
{
    double lat1 = DegreeToRadian(this.latitude);
    double lat2 = DegreeToRadian(lat);
    double dLon = DegreeToRadian(lng) - DegreeToRadian(this.longitude);

    double y = Math.Sin(dLon) * Math.Cos(lat2);
    double x = Math.Cos(lat1) * Math.Sin(lat2) - Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(dLon);
    double brng = Math.Atan2(y, x);

    return (RadianToDegree(brng) + 360) % 360;
} // end BearingTo

Detects Support for HTML5 and CSS3 (cont’d)

Previously I blog about the same topic “Detects Support for HTML5 and CSS3” but I did not cover much on the CSS3. As a follow up now we look into it. Similar to HTML5, we can use Modernizr to detect CSS3 support. It is like having an if-statement in the css and the syntax is easy to use. There are 2 things you can do with Modernizr in this scenario: 

  1. Automatically load the style supported by the browser. This can be achieve by defining 2 set of classes (see example below); and
  2. Perform additional action when the CSS class is not supported. This can be achive by checking the JavaScript property (see example below).

The snippet below show how to define the CSS classes.

  .borderradius div.somediv {
   /* properties for browsers that
      support border radius */
  }
  .no-borderradius div.somediv {
   /* optional fallback properties
     for browsers that don't */  
  }

Detect CSS3 Classes & JS Property for Border Radius
As you can see the syntax is simple, as add “no” to handle the non-supported style. Find out more about the features that can be detected using Modernizr in the documentation (http://www.modernizr.com/docs/). The figure below shows Modernizr in action and the full example is available below. 

Detects CSS3 - Modernizr in Action
<!DOCTYPE html>
<html>
  <head>
  <title>Detect CSS3</title>

 <style type="text/css">
  body {
      margin: 0;
      font-family: Helvetica;
      background-color: #ddd;
  }
  div.somediv {
   margin: 50px;
  }
  
  .borderradius div.somediv {
     background: #fff;
     border-radius: 30px 30px 0 0;
     -moz-border-radius-topleft: 30px;
     -moz-border-radius-topright: 30px;
     -webkit-border-top-left-radius: 30px;
     -webkit-border-top-right-radius: 30px;
     width: 300px;
     padding: 30px;
  }
  .no-borderradius div.somediv {
     background: #000;
     color: #fff;
     border: 1px solid #fff;
     width: 300px;
     padding: 30px;
  }
 </style>

</head>
<body>

<div id="outer">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vitae consequat tellus. Nulla non velit leo, a pellentesque arcu. Donec aliquet urna in nibh consectetur aliquet non id purus. Curabitur vitae lacus ut nisl elementum sollicitudin. Etiam lorem nunc, iaculis in vehicula vel, convallis in nisi. Quisque diam risus, pharetra sed hendrerit ac, scelerisque non quam. Sed ac ligula nulla, vel lobortis purus. Suspendisse potenti. Integer sit amet diam quam, vitae posuere ligula. Vestibulum lorem nibh, vehicula ac venenatis eu, ornare pharetra tortor. Aliquam sed massa sem, non viverra enim. Integer augue odio, laoreet at posuere sit amet, convallis nec nisl. Donec vel purus arcu, ac venenatis mi.
</div>

</body>
</html>
<script type="text/javascript" src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js%22%3E%3C/script">http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script</a>>
<script language=JavaScript src="js/modernizr-1.5.min.js" type="text/javascript"></script>
<script>
 $(document).ready(function () {
  if (!Modernizr.borderradius)  {
   alert('Border Radius is not supported in this browser.\n Do something about it ');
  }
 });// end document ready

</script>

Enter WhitherApps

 Previously I blog about Sencha and did mentioned about the advantages of building mobile web apps as compared to native client apps. HTML5 has great potential in building mobile we apps and James Pearce is ready to show us that potential. He and “his team” started WhitherApps

WhitherApps is a bandwagon-busting experiment. I believe there are far too many native client apps which could have been far better written as mobile web apps. What we’re going to try and do is take a few examples, apply a little reverse-engineering, and rewrite them, warts and all, with web technologies.

The first project for the team is to rewrite the BBC News iPhone/iPad app into a web app based on HTML5. He has already started 3 blog post on the BBC News apps, Part1, Part2 and Part3. If you see the screenshot below he has gotten pretty far.

BBC News (HTML5)
BBC News (iPad)

If you are into HTML5 and mobile apps developer I recommend you to read his blog and follow his journey to rewrite the BBC News apps. Although native client apps will not wither away, I am sure to see more of such project.

jq Nearby Tweet Plugin

After I did the Nearby Tweet makeover, I kinda ran out of idea. But the past few days, I looked into making it more alive and more dynamic. The result is my very own Nearby Tweet Stream. I am sure if stream is the right word, but it does looks like it. This time my prototype is using jQuery (1.4.2) and created a plugin. Wohoo!!

The idea is kinda simple and first plugin. I used 2 set of timer, (1) to retrieve the nearby tweet and store it into queue and (2) to retrieve from queue and display. Did a sketch below

The plugin is still in its infant state and only accept geolocation as parameter. I thought of registering it into jq plugin repository later, for now testing and more testing. The minified version is available here and you can see it live at jqNearByTweetStream. (For better experience, try it in HTML5-ready browser as it requires geolocation).

Here is an example of how to use the plugin.

 <!DOCTYPE html>
 <html>
 <head>

 <!-- JQuery JS -->
  <script language=JavaScript src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
  <script language=JavaScript src="js/jquery.nearbytweet.stream.0.1-min.js" type="text/javascript"></script>
  <script language=JavaScript src="js/modernizr-1.5.min.js" type="text/javascript"></script>
 <style type="text/css">
 #TwitterStream { height: 400px;  margin: auto; width: 500px }

 </style>

</head>
<body>

<div id="TwitterStream"></div>

</body>
</html>

<script type="text/javascript">

$(document).ready(function(){
  if (Modernizr.geolocation){
   navigator.geolocation.getCurrentPosition(function(position) {
     var options = {
      latitude: position.coords.latitude,
      longtitude: position.coords.longitude
     };
   $('#TwitterStream').jqNearbyTweetStream(options);
   });
 } else {
  window.console && console.log('the browser does not support HTML5');
  $('#TwitterStream').jqNearbyTweetStream();
 }
  
});
// end document ready

</script>

As you can see above, It is very simple to use the plugin. Must find time to update the plugin, wait for new release ho…ho…ho. Do leave comment if you like the plugin 🙂