Habitat is an Open Source project that allows you to package your apps in a Platform/Runtime agnostic way.

This blog post discusses the recently added Cloud Foundry exporter that enables running Apps packaged in Habitat to run on Cloud Foundry.

Build the App

We'll be using this demo app as an example.

First lets build the app inside the habitat studio:

$ git clone https://github.com/cloudfoundry-community/expresso.git
$ cd expresso
$ hab studio enter
[1][default:/src:0]# build .
(...)
[2][default:/src:0]# ls results/*.hart
starkandwayne-expresso-0.1.0-20170927132309-x86_64-linux.hart  

Exporting the App

Now that the app has been built, we face the issue of configuring it via the Cloud Foundry injected environment variables.
Habitat doesn't support configuring via arbitrary environment variables. Rather it relies on the hab-CLI being able to talk to an API to push configuration changes.

In a Cloud Foundry setting this won't work because the habitat http-API wont be exposed to the Cloud Foundry user.

Another way of configuring habitat based Apps is via a .toml file that overrides the default application configuration.
The Cloud Foundry exporter makes it possible to provide a mapping file that specifies how the environment variables should be rendered into the configuration .toml file.

[3][default:/src:0]# cat <<EOF >mapping.toml
> [app]
> port = "${PORT}"
> EOF
[4][default:/src:0]# hab pkg export cf starkandwayne/expresso ./mapping.toml
(...)
[4][default:/src:0]# exit

This will export 2 Docker images:

$ docker images
REPOSITORY                                  TAG                         IMAGE ID            CREATED             SIZE  
starkandwayne/expresso                      cf-0.1.0-20170927132309     ed9e423b1ad8        11 seconds ago      170MB  
starkandwayne/expresso                      0.1.0-20170927132309        05a01c4ecf99        22 seconds ago      167MB  
starkandwayne/expresso                      latest                      05a01c4ecf99        22 seconds ago      167MB  

The one with the cf- tag prefix is enabled to run on Cloud Foundry.

Running the App

In order to run the application you must be logged in with the cf-CLI to a Cloud Foundry instance that supports running Docker containers.

First we push the Docker container to dockerhub:

$ docker push starkandwayne/expresso:cf-0.1.0-20170927132309

Then we run it on Cloud Foundry:

$ cf push expresso -o starkandwayne/expresso:cf-0.1.0-20170927141758
(...)
$ cf app expresso
Showing health and status for app expresso in org test / space habitat as admin...

name:              expresso  
requested state:   started  
instances:         1/1  
usage:             256M x 1 instances  
routes:            expresso.local.pcfdev.io  
last uploaded:     Sat 23 Sep 14:47:03 CEST 2017  
stack:             cflinuxfs2  
docker image:      starkandwayne/expresso:cf-0.1.0-20170927141758

     state     since                  cpu    memory          disk           details
#0   running   2017-09-23T12:48:04Z   0.2%   44.7M of 256M   556K of 512M

Once the image has been downloaded and the container started, we should be able access it via our browser or curl:

$ curl expresso.local.pcfdev.io
<!DOCTYPE html><html><head><title>Express</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>Express</h1><p>Welcome to Express</p></body></html>%  

Gotcha

In order for this to work you must make sure that the primary port is exposed and exported in the habitat plan.sh.

pkg_origin=starkandwayne  
pkg_name=expresso  
pkg_version=0.1.0  
pkg_scaffolding=core/scaffolding-node

pkg_exports=(  
  [port]=app.port
)
pkg_exposes=(port)  

Other than adding the pkg_exports and pkg_exposes variables, the app is exactly the result of following the steps in this blog.