GO applications and Cloud Foundry
Cloud Foundry is one of many options to host your applications. It is a PaaS originally developed by VMware, now governed by Cloud Foundry Foundation. Not going much into details about where, how and what as those information is publicly available I’ll focus here on how to host your GO applications on any Cloud Foundry installation including PCF or PWS.
There’s a known and recommended way to push GO applications. It is based on using GO buildpack. Very briefly, the buildpack takes all of your source code and dependencies (managed by godep), builds the binary and creates a droplet that is then distributed to CF nodes. The alternative approach I want to describe here is based on building the binary locally and push the binary instead of the source code. I’ll leave the discussion about the advantages or disadvantages of such approach to a reader as in my opinion it is a matter of preference and specific project requirements.
BuildpacksTo understand what we're going to do, first we need to cover the idea of buildpacks. As per the documentation "buildpacks provide framework and runtime support for your applications. Buildpacks typically examine user-provided artifacts to determine what dependencies to download and how to configure applications to communicate with bound services."
And the description continues: “When you push an application, Cloud Foundry automatically detects which buildpack is required and installs it on the Droplet Execution Agent (DEA) where the application needs to run.".
In our case, we’ll use a special buildpack, called “noop buildpack”. This buildpack (as its name suggests) does nothing. We don’t need any special logic to introspect our application and find out what language it is written in or which runtime it requires, because we know it is going to be a Linux x64 binary.
Application bootstrapNow that we've effectively deactivated standard "boostrap" procedure that is added to an app if using any of the proper buildpacks, we need some other way to start our process. And we can, there's a special directory
".profile.d"that CF recognises and executes all the scripts found there, like
"setenv.sh"described here. And this is exactly what we'll use to bootstrap the app. We'll create a new project with
".profile.d"directory containing a script called
. └── .profile.d └── start.sh
I am sure a careful reader just realised that this is by no means GO specific. Any script can be executed there, for example a script to run a python http server for serving static pages (full example here):
The important part of the script is the
“cd app”. During the staging process, all of your application artifacts that are pushed to Cloud Foundry are placed into the “app” directory as can be seen using
“cf files APP_NAME” command:
% cf files static-files-demo Getting files for app static-files-demo in org ************* / space development as *************@gmail.com... OK .bash_logout 220B .bashrc 3.6K .profile 675B app/ - logs/ - staging_info.yml 168B tmp/ -
GO applicationNow I suppose all should be clear. We'll build local binary of our application. It does not really matter what method you use for managing dependencies, it can be godep, go.pkg or gb. Just make sure to build amd64 linux binary:
$ GOARCH=amd64 GOOS=linux go build APP
Then create a
".profile.d/start.sh” file with a content similar to this:
And push your application to CF using noop-buildpack:
$ cf push APP_NAME -b https://github.com/igm/noop-buildpack