Buildpacks in Lattice

Lattice v0.3.0 just shipped (if you don't know much about Lattice, go to, and for me the big news was the newly added support for Cloud Foundry Buildpacks within a Lattice cluster.

The goal of Lattice is to get a portion of the larger Cloud Foundry platform repackaged into an easily consumable system that makes getting started with the Cloud Foundry technologies straight forward for individuals and small teams. If you want to understand this a little better, watch James Bayer and Colin Humphreys talk about Lattice at the 2015 CF Summit North America.

In previous releases, Lattice was limited to only running completed Docker images within the cluster. Now that we have Buildpack support, Lattice is really able to give you a much better taste of what it means to use Cloud Foundry. Have some code? Just push it to Lattice and let it do the work to build the container for you.

Here's how to use it:


For this walkthrough, I'll be using the Vagrant box version of Lattice (using VirtualBox). These instructions assume v0.3.0 of both Lattice and the ltc command line tool. The same process should work for future versions of Lattice, we well as different deployment options (like one of the Terraform configurations for different IaaS environments).

You can grab the ltc cli tool from the bottom of the release notes.

To get the latest 

>  git clone
> cd lattice
> git checkout v0.3.0
> vagrant up --provider virtualbox

This should result in a running box with the Lattice system initialized. If it worked correctly, you'll see:

==> default: Lattice is now installed and running.
==> default: You may target it using: ltc target

By default, the Lattice box environment will be unauthenticated so it's easy to get ltc to target the cluster:

> ltc target
Blob store is targeted.
Api Location Set

I've run into issues where doesn't resolve via some DNS servers, so if you have that issue consider using another DNS server like Google's address.

At this point, you should have a functional Lattice system and ltc should be able to talk to it. Give it a test by running 'ltc list'.

> ltc list
------------------------------= Apps =-------------------------------
No apps to display.

------------------------------= Tasks =------------------------------
No tasks to display.

Get a Sample App

Now we're ready to find some source code that we want to run within Lattice. Since Lattice is specifically designed to be a BYOS (bring your own services), my example will not require any database or other backend services. It's a simple Python Flask based web app. Obviously it's a trivial Hello World example, but you can easily extrapolate and see how this would be useful for non-trivial systems.

The sample application we'll be using can be found on GitHub at Go ahead and clone the repo now (from a working directory that's not within the lattice project's directory):

> cd ~
> git clone
> cd sample-python

There are only three files in the repo:


  • Procfile - the file that helps Flask startup
  • requirements.txt - the list of modules needed to run the app, in this case it's only Flask
  • - the basic web app that we'll be hosting within Lattice


The contents of are pretty straight forward. The file creates a route for '/' that returns the string "Hello World! Im an instance number X", where X is the Lattice instance number (as retrieved from the app's environment variables).

from flask import Flask
import os

app = Flask(__name__)

cfindex = os.getenv("INSTANCE_INDEX")

def hello_world():
    return 'Hello World! I am instance number ' + str(cfindex)

if __name__ == '__main__':'', port=8080)

My example assumes that 8080 is a reasonable listening port, since that's the default port that Lattice expects from containers. There's lots of flexibility here, but defaults will do for the example.

Build the Droplet

Lattice uses the same terminology as Cloud Foundry for the container images created via buildpacks: Droplets. Droplets are the result of taking code from the user and running it through the staging process.

Step one is to do a build of the droplet:

> ltc build-droplet sample-python

The command tells ltc to build the local directory into a droplet, naming it "sample-python" and using the cloudfoundry/python-buildpack. When you want to do something in other languages, the same process applies. Just be sure to specify an appropriate buildpack.

If everything is working correctly, you'll see Lattice stage the code and build a Droplet image:

Submitted build of sample-python
08/12 14:52:58.93 [BUILD|0] Successfully created container
08/12 14:53:07.60 [BUILD|0] -------> Buildpack version 1.5.0
08/12 14:53:07.67 [BUILD|0] -----> Installing runtime (python-2.7.10)
08/12 14:53:15.09 [BUILD|0] -----> Installing dependencies with pip
08/12 14:53:15.44 [BUILD|0]        Collecting Flask (from -r requirements.txt (line 1))
08/12 14:53:15.60 [BUILD|0]          Downloading Flask-0.10.1.tar.gz (544kB)
08/12 14:53:15.96 [BUILD|0]        Collecting Werkzeug>=0.7 (from Flask->-r requirements.txt (line 1))
08/12 14:53:16.04 [BUILD|0]          Downloading Werkzeug-0.10.4-py2.py3-none-any.whl (293kB)
08/12 14:53:16.11 [BUILD|0]        Collecting Jinja2>=2.4 (from Flask->-r requirements.txt (line 1))
08/12 14:53:16.18 [BUILD|0]          Downloading Jinja2-2.8-py2.py3-none-any.whl (263kB)
08/12 14:53:16.25 [BUILD|0]        Collecting itsdangerous>=0.21 (from Flask->-r requirements.txt (line 1))
08/12 14:53:16.31 [BUILD|0]          Downloading itsdangerous-0.24.tar.gz (46kB)
08/12 14:53:16.46 [BUILD|0]        Collecting MarkupSafe (from Jinja2>=2.4->Flask->-r requirements.txt (line 1))
08/12 14:53:16.53 [BUILD|0]          Downloading MarkupSafe-0.23.tar.gz
08/12 14:53:16.66 [BUILD|0]        Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask
08/12 14:53:16.79 [BUILD|0]          Running install for MarkupSafe
08/12 14:53:17.50 [BUILD|0]          Running install for itsdangerous
08/12 14:53:17.66 [BUILD|0]          Running install for Flask
08/12 14:53:18.00 [BUILD|0]        Successfully installed Flask-0.10.1 Jinja2-2.8 MarkupSafe-0.23 Werkzeug-0.10.4 itsdangerous-0.24
08/12 14:53:37.28 [BUILD|0] Exit status 0
08/12 14:53:37.51 [BUILD|0] Uploaded /tmp/droplet to
08/12 14:53:37.52 [BUILD|0] Exit status 0
08/12 14:53:37.55 [BUILD|0] Uploaded /tmp/result.json to
08/12 14:53:37.56 [BUILD|0] Exit status 0
08/12 14:53:37.60 [BUILD|0] Deleted
08/12 14:53:37.61 [BUILD|0] Exit status 0
Build completed

To confirm that the droplet is registered in the cluster, you can run "ltc list-droplets" (or my favorite shorthand "ltc lsd").

> ltc lsd
Droplet		Created At		Size
sample-python	08/12 18:53:37.00	29.5M

Next, we will launch one instance with the "ltc launch-droplet" comment. You'll need to specify a name for the application (yes, multiple apps can be launched from the same droplet), as well as the name of the droplet to launch from. I used my imagination and named my app "test" in the example below:

> ltc launch-droplet test sample-python
No port specified. Defaulting to 8080.
Creating App: test
.08/12 15:04:55.53 [APP|0] Successfully created container
....08/12 15:05:00.01 [APP|0]  * Running on (Press CTRL+C to quit)
.08/12 15:05:00.39 [HEALTH|0] healthcheck passed
08/12 15:05:00.39 [HEALTH|0] Exit status 0

test is now running.
App is reachable at:

And there we go! You should be able to see the app working by hitting You can also now take advantage of the other features of Lattice, like scaling up / down (ltc scale), automatic health management and log aggregation.

Let's play with Lattice

To see the app list:

> ltc list
------------------------------= Apps =-------------------------------
App Name	Instances	DiskMB		MemoryMB	Route
test		1/1		0		128, => 8080

------------------------------= Tasks =------------------------------
No tasks to display.

To see the details of the "test" app:

> ltc status test
Instances	1/1
Start Timeout	0
DiskMB		0
MemoryMB	128
CPUWeight	100
Ports		8080
Routes => 8080 => 8080
Annotation	{"droplet_source":{"host":"","port":"8444","droplet_name":"sample-python"}}


      Instance 0  [RUNNING]
InstanceGuid	a4aac9d3-fba5-453b-71ba-ec2004a17138
Cell ID		cell-01
Port Mapping	60004:8080
Uptime		3m57s
Crash Count 	0
CPU 		0.12%
Memory 		13.5M

Scaling up or down:

> ltc scale test 5
Scaling test to 5 instances
App Scaled Successfully

Now you should notice when you hit the app's web page that the index will jump around between the 5 instances on each refresh.

Also, the "ltc list" command should now show 5 instances running, and "ltc visualize" should show that there are 5 containers running on your cell (or cells if you deployed a Lattice cluster).

> ltc list
------------------------------= Apps =-------------------------------
App Name	Instances	DiskMB		MemoryMB	Route
test		5/5		0		128, => 8080

------------------------------= Tasks =------------------------------
No tasks to display.

> ltc visualize
cell-01: •••••

And if you want fancy visualizations of your Lattice environment, check out from the kind folks at Pivotal. It will connect to your Lattice environment from your browser, so it even works with your local VirtualBox Lattice instance.

Now let's break something!

Lattice includes both health management (keeping it's promises) as well as great logging visibility into the cluster's operations. To test this out, we can mess with the cluster by killing processes and watch as Lattice heals around our malevolence.

To start, open two terminal windows. In one, we'll use "vagrant ssh" to cause some damage. In the other, we'll watch as Lattice responds.

Get started by running "ltc logs test" in the first terminal to start watching the logs for your test application:

> ltc logs test

08/12 15:24:32.79 [HEALTH|0] healthcheck passed
08/12 15:24:32.79 [HEALTH|0] Exit status 0

Now in the other terminal, use "vagrant ssh" to log into the Vagrant box so we can do some damage:

> vagrant ssh
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.16.0-30-generic x86_64)

 * Documentation:
vagrant@ubuntu-trusty-64:~$ ps -ef | grep iodaemon | grep -v grep | awk '{print $2}'

That's the list of PIDs for the 5 instances of the Lattice app. Go ahead and kill -9 one or more of them!

vagrant@ubuntu-trusty-64:~$ sudo kill -9 13469 14531

If you go over to the terminal window showing logs, you will see that Lattice will notice the issue and quickly restart new app instances within the cluster automatically.

08/12 15:28:33.13 [HEALTH|0] healthcheck passed
08/12 15:28:33.14 [HEALTH|0] Exit status 0
08/12 15:28:38.50 [HEALTH|4] healthcheck passed
08/12 15:28:38.51 [HEALTH|4] Exit status 0
08/12 15:28:40.65 [APP|0] Creating container
08/12 15:28:40.66 [APP|4] Creating container
08/12 15:28:41.68 [APP|0] Successfully created container
08/12 15:28:42.34 [HEALTH|1] healthcheck passed
08/12 15:28:42.34 [HEALTH|1] Exit status 0
08/12 15:28:42.80 [APP|4] Successfully created container
08/12 15:28:45.47 [HEALTH|3] healthcheck passed
08/12 15:28:45.56 [HEALTH|3] Exit status 0
08/12 15:28:45.73 [HEALTH|2] healthcheck passed
08/12 15:28:45.81 [HEALTH|2] Exit status 0
08/12 15:28:48.97 [HEALTH|0] healthcheck failed
08/12 15:28:48.99 [HEALTH|0] Exit status 1
08/12 15:28:49.08 [APP|0]  * Running on (Press CTRL+C to quit)
08/12 15:28:49.55 [HEALTH|0] healthcheck passed
08/12 15:28:49.58 [HEALTH|0] Exit status 0
08/12 15:28:50.87 [APP|4]  * Running on (Press CTRL+C to quit)
08/12 15:28:51.03 [HEALTH|4] healthcheck passed
08/12 15:28:51.04 [HEALTH|4] Exit status 0

So there go... All the fun of Lattice, now with buildpacks!


Room roving robot - phase 1

My second holiday project was a bit more fun than just blinking lights. I decided to tear apart a $10 RC jeep and control it with the Arduino. For this project, I added a motor shield on top of the Arduino that I purchased at the same Radio Shack where I found the RC car (Who would have thought that Radio Shack would get back to the hobby electronics game, after they seemed to be turning into a cell phone store!). The shield is the Seeed Motor Shield V1.0, which sits on top of the Arduino and passes through the Analog input pins as well as Digital pins 1 through 7. The shield is a bit clunky, because it has to sit on top of a shield stack but it served it's purpose.

Starting with the car itself, I stripped it down to just it's bare essentials, including clipping the battery connector wires off of the RC circuit board to remove that board (but reuse the 3x1.5V AA battery casing). The front steering and rear drive motors were connected to the RC board via nice little female connectors that happen to easily accept small gauge pins from the seeed ARDX experimentation kit I started this whole process using. The battery casing took a little finagling to get wire leads connected to the exposed leads, but I just pushed a long section of wire into the coils.

After snipping off a bit of plastic from the frame, I managed to get a pretty flat surface for the Arduino (with motor shield) to sit on top of.  A little electrical tape, and bam...  easy mounting is always the best for quick projects.  I was also able to use the space directly above the rear drive motor to nestle a 9V battery that feeds the Arduino.

Here are some photos of the project:

The first photo shows the whole contraption with everything but the 9V battery attached (the little guy comes to life when that's attached...  I guess I need an on-off switch).

Next is the underside where you can see that I'm reusing the 3 slot battery casing for the motor power source. Also notice that little red dial on the front, which comes in handy. It's a front wheel alignment device, which was needed after all the handling I did of the car to take it apart.

Next is a closer look at the electronic stack from the front of the car. This shows one of the female plugs from the motors, and how nicely the experimentation kit wires fit right into it.

Last is the electronics stack from the rear of the car. The four wires coming out of the green terminals on the motor shield are the wiring for the two motors. The space above the rear drive motor that I use for the 9V battery that powers the Arduino is visible as well. You can also see that, when the 9V isn't on the car, there's easy access to the Arduino's USB port for uploading programs.

The circuits for this project are (again) fairly simple, since the Arduino / Motor shield combination makes it easy to use PWM functionality from the Arduino to control current flowing to the two motors. The only other connections are the two battery power sources. I actually started by feeding power from a 9V into the motor shield, and setting the passthrough jumper on the shield to allow it to send power down to the Arduino. After playing with that a bit, I realized it was better to isolate the power source for the controller from the power for the motors.

For the initial program, I hard coded a path for the car that moves it forward while executing an s-curve, then stops, then reverses a bit, and then starts all over again.

Last, here's a short video of the car in action (and getting a reaction from my dog!).

Next up, I'll be adding an ultrasonic distance sensor to the front grill of the robot (the PING))) sensor) and two infrared reflective sensors to let me do line tracking (here).