{"id":7022,"date":"2014-12-12T20:18:58","date_gmt":"2014-12-12T17:18:58","guid":{"rendered":"http:\/\/blog.altoros.com\/?p=7022"},"modified":"2021-03-12T04:42:15","modified_gmt":"2021-03-12T01:42:15","slug":"creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/","title":{"rendered":"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#Pre-history\" >Pre-history<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#DEA_in_a_nutshell\" >DEA in a nutshell<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#Detect_compile_and_release_scripts\" >Detect, compile, and release scripts<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#Debugging\" >Debugging<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#Tips_for_developers\" >Tips for developers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#Related_reading\" >Related reading<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Pre-history\"><\/span>Pre-history<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p dir=\"ltr\"><strong><\/strong>Buildpack is a core link in the chain of the Cloud Foundry deployment process. It automates detection of an application framework, application compilation and running. Being a happy user of Cloud Foundry for a long time, I haven&#8217;t had any troubles while using the official buildpacks for Ruby, Java, and Python projects.<\/p>\n<p dir=\"ltr\">Customization of the staging process was also easy by forking the existing buildpacks and extending them. A common development practice for custom buildpacks is forking existing buildpacks and synchronizing subsequent patches from upstream. You can even use a branch of your fork or private github repos with the <em>\u2018cf push\u2019<\/em> command.  So, there were no actual limitations for these cases.<\/p>\n<p dir=\"ltr\">I guess, you all know Jenkins CI, a popular Continuous Integration service. A lot of developers use it in their daily work. So, Jenkins community recently delivered a <a href=\"https:\/\/www.activestate.com\/blog\/cloud-foundry-jenkins-plugin\/\" target=\"_blank\" rel=\"noopener noreferrer\">plugin<\/a> that provides Cloud Foundry support.<\/p>\n<p dir=\"ltr\">Still, when I tried to deploy Jenkins as a Cloud Foundry application, I faced issues that couldn\u2019t be resolved in a regular manner. The standard Java buildpack supports a lot of frameworks\u2014thus, it is too complicated to work with. Jenkins features runtime dependencies that make it even harder to run it using the Java buildpack. That\u2019s where I\u2019ve come up with an idea to write a brand new buildpack from scratch. As a result, I delivered a working <a href=\"https:\/\/github.com\/Altoros\/jenkins-buildpack\" target=\"_blank\" rel=\"noopener noreferrer\">buildpack<\/a> and got the hang of how it should be done.<\/p>\n<p>Gladly, the official Cloud Foundry documentation was of a great assistance to me:<\/p>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><a href=\"https:\/\/docs.cloudfoundry.org\/buildpacks\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/docs.cloudfoundry.org\/buildpacks<\/a><\/p>\n<\/li>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><a href=\"https:\/\/docs.cloudfoundry.org\/buildpacks\/custom.html\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/docs.cloudfoundry.org\/buildpacks\/custom.html<\/a><\/p>\n<\/li>\n<\/ul>\n<p>Now, let\u2019s move on to the main components essential for creating a buildpack.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"DEA_in_a_nutshell\"><\/span>DEA in a nutshell<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>DEA (Droplet Execution Agent) is a Web service that allows for uploading and running applications in the Cloud Foundry PaaS. DEA is written in Ruby, which makes it possible to run it on different systems. Moreover, DEA is enhanced with the <a href=\"https:\/\/rubygems.org\/gems\/eventmachine\" target=\"_blank\" rel=\"noopener noreferrer\">Event Machine<\/a> gem to process requests asynchronously. The Cloud Controller uses the DEA API to manage application containers.<\/p>\n<p><center><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-DEA-Virtual-Machine.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-DEA-Virtual-Machine.gif\" alt=\"Custom-Cloud-Foundry-Buildpack-DEA-Virtual-Machine\" width=\"495\" height=\"492\" class=\"aligncenter size-full wp-image-26987\" \/><\/a><\/center><\/p>\n<p>DEA runs over <a href=\"https:\/\/github.com\/cloudfoundry-attic\/warden\" target=\"_blank\" rel=\"noopener noreferrer\">Warden<\/a>, which is a Web server that uses <a href=\"https:\/\/en.wikipedia.org\/wiki\/Protocol_Buffers\" target=\"_blank\" rel=\"noopener noreferrer\">protobuf<\/a> to define its protocol. Then, Warden translates requests into the language of an operating system. For instance, in Linux-based systems it executes Bash scripts.<\/p>\n<p>It is made to hide differences and complexities of containerization on different platforms. For example, it is possible to use almost the same code of the DEA server in <a href=\"https:\/\/www.ironfoundry.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Iron Foundry<\/a> to add Windows Stack to Cloud Foundry. At the same time, Iron Foundry uses another <a href=\"https:\/\/github.com\/cloudfoundry-attic\/if_warden\" target=\"_blank\" rel=\"noopener noreferrer\">implementation of Warden<\/a> that handles process isolation on the Windows platform.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Detect_compile_and_release_scripts\"><\/span>Detect, compile, and release scripts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The functional part of a buildpack consists of three scripts: detect, compile, and release ones. They are executables that can be implemented in any way you are comfortable with. As a rule, buildpacks use the Ruby language for these scripts (Java and Ruby buildpacks). Still, if the functionality is simple, e.g. there is no need to support multiple frameworks, you can use Bash (as it is done in the Node.js buildpack).<\/p>\n<p>When DEA gets a request from the Cloud Controller to stage an app, it places the code to a container and starts to look for a suitable buildpack. It calls the <em>\u2018detect\u2019<\/em> script in every buildpack and chooses the first to return 0. Thus, the order of a buildpack is important. Usually, a buildpack checks the presence of specific files at this stage. Therefore, several technology stacks within one project can result in errors.<\/p>\n<p><center><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-Application-Compilation.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-Application-Compilation.png\" alt=\"Custom-Cloud-Foundry-Buildpack-Application-Compilation\" width=\"640\" class=\"aligncenter size-full wp-image-26988\" \/><\/a><\/center><\/p>\n<p>After that, the <em>\u2018compile\u2019<\/em> script of the detected buildpack is called. This script gets two parameters: cache folders and paths to build. A build folder is a folder that contains all the necessary assets to get an application running. After the compile process is finished, this folder is archived to the so-called droplet tarball, which travels to a blobstore. A cache folder is used to store all the intermediate data that is necessary to compile an app, such as a source code or object files. Keep in mind that you need to store all the additional libraries and binaries in a build folder to have access to them, when you run an application.<\/p>\n<p><center><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-Staging-Complete.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-Staging-Complete.png\" alt=\"Custom-Cloud-Foundry-Buildpack-Staging-Complete\" width=\"640\" class=\"aligncenter size-full wp-image-26989\" \/><\/a><\/center><\/p>\n<p dir=\"ltr\">After a droplet is uploaded to a blobstore, DEA asks Warden to run new containers for each application instance. In Linux-based systems, Warden uses rootfs (specified in config) to have the initial file structure for these containers. Each container gets an application droplet from the blobstore and unpacks into the \u201capp\u201d folder within a home directory of a vcap user.<\/p>\n<p dir=\"ltr\">Then, the <em>\u2018release\u2019<\/em> script is executed. DEA expects it to print to a standard output with YAML parameters to run the application. You can store the YAML file in the build directory and then print it as in the <a href=\"https:\/\/github.com\/cloudfoundry\/ruby-buildpack\/blob\/master\/bin\/release\" target=\"_blank\" rel=\"noopener noreferrer\">Ruby buildpack<\/a>, or use the Bash script, as it is done in the <a href=\"https:\/\/github.com\/cloudfoundry\/nodejs-buildpack\/blob\/master\/bin\/release\" target=\"_blank\" rel=\"noopener noreferrer\">Node.js buildpack<\/a>.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-Running-an-application.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Custom-Cloud-Foundry-Buildpack-Running-an-application.png\" alt=\"Custom-Cloud-Foundry-Buildpack-Running-an application\" width=\"640\" class=\"aligncenter size-full wp-image-26990\" \/><\/a><\/p>\n<p dir=\"ltr\">To check if an application works, either make sure an application port is open or check it via <em>\u201cstate file.\u201d<\/em> In case your application runs as a background job, you can specify the <em>\u201c&#8211;no-route\u201d<\/em> option to prevent Cloud Foundry from executing the<em> \u2018cf push\u2019<\/em> command.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Debugging\"><\/span>Debugging<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If an application crashes during staging or a start, all application containers are removed. It is done in several places: immediately after an app crash and within a reaper process that removes everything that does not correspond to the running containers from a depot folder to save disk space on the DEA machine.<\/p>\n<p>You can prove that scripts from your buildpack run properly by running them on your local machine [<a href=\"https:\/\/github.com\/cloudfoundry\/java-buildpack\/blob\/main\/docs\/debugging-the-buildpack.md#running-the-buildpack-locally\" target=\"_blank\" rel=\"noopener noreferrer\">link<\/a>]. Still, when something goes wrong, I settle the issue by getting an access to the crashed container. There is no explicit parameter that prevents DEA from killing application containers, but there is a parameter that defines time before DEA deletes containers [<a href=\"https:\/\/groups.google.com\/a\/cloudfoundry.org\/forum\/#!searchin\/vcap-dev\/crashed$20app\/vcap-dev\/szqqlUbsxX4\/v_cKxFm4LogJ\" target=\"_blank\" rel=\"noopener noreferrer\">link to vcap-group<\/a>]. Thus, you need to get the ssh access to a DEA instance and to add the <em>container_grace_time<\/em> parameter with some large number to a server hash in the Warden configuration file\u2014stored in <em>\/var\/vcap\/jobs\/dea_next\/config\/warden.yml<\/em> (find this option in a Warden repo [<a href=\"https:\/\/github.com\/cloudfoundry-attic\/warden\/blob\/master\/warden\/config\/linux.yml#L16\" target=\"_blank\" rel=\"noopener noreferrer\">link to config<\/a>]). After that, you need to restart the Warden process with Monit using the following command: <em>\/var\/vcap\/bosh\/bin\/monit<\/em> <em>-I restart warden<\/em>. Be careful, it will remove all working containers that you currently have in DEA. That done, you will be able to access your crashed container by going to a container folder in a depot directory\u2014usually, it is <em>\/var\/vcap\/data\/warden\/depot\/&lt;container-handle&gt;<\/em>\u2014and running <em>sudo .\/bin\/wsh<\/em>. That\u2019s it, you are in! Remember, all the apps run under the <em>\u2018vcap\u2019<\/em> user.<\/p>\n<p>Sometimes, DEA removes those applications that can not run without the Warden grace time option. In this case, you can even patch DEA or Warden to leave your containers for good. To patch Warden, you need to comment the content of the <em>\u2018do_destroy\u2019<\/em> method in the <em>\u2018linux.rb<\/em>\u2019 file in the following directory: <em>\/var\/vcap\/jobs\/dea_next\/packages\/warden\/warden\/lib\/warden\/container\/<\/em>. If you decide on patching DEA, you can use this <a href=\"https:\/\/gist.github.com\/allomov\/d0033ef822133e9afad7\" target=\"_blank\" rel=\"noopener noreferrer\">gist<\/a> for cf-release v192. As long as the operation is quite risky, never try to run such stuff on production machines.<\/p>\n<p>I would also recommend you to read about application <a href=\"https:\/\/docs.cloudfoundry.org\/devguide\/deploy-apps\/troubleshoot-app-health.html\" target=\"_blank\" rel=\"noopener noreferrer\">troubleshooting<\/a> in the Cloud Foundry documentation.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tips_for_developers\"><\/span>Tips for developers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>There are some other things that can be helpful for developers. Check out the GitHub <a href=\"https:\/\/github.com\/cf-buildpacks\" target=\"_blank\" rel=\"noopener noreferrer\">cf-builpacks<\/a> organization for this kind of products.<\/p>\n<p dir=\"ltr\"> There you can find some useful helpers to deal with routine tasks in your buildpack. It\u2019s a common thing to use Git submodules for adding repositories with helpers. Take a look at the following repos:<\/p>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><a href=\"https:\/\/github.com\/cloudfoundry\/compile-extensions\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/cloudfoundry\/compile-extensions<\/a><\/p>\n<\/li>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><a href=\"https:\/\/github.com\/cloudfoundry\/buildpack-packager\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/cloudfoundry\/buildpack-packager<\/a><\/p>\n<\/li>\n<\/ul>\n<p>Another development best practice is to test your code. If you write a buildpack in Ruby, you can choose from a great number of testing frameworks. For example, you can use the Machete testing framework, since it is written specifically for buildpacks:<\/p>\n<ul>\n<li>\n<p dir=\"ltr\"><a href=\"https:\/\/github.com\/cloudfoundry\/machete\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/cloudfoundry\/machete<\/a><\/p>\n<\/li>\n<\/ul>\n<p>It\u2019s not that hard to deploy applications with custom dependencies on Cloud Foundry, you just need to be familiar with under-the-hood mechanisms of the Cloud Foundry PaaS.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Related_reading\"><\/span>Related reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/creating-a-sample-service-broker-for-cloud-foundry-with-pythons-flask\/\">Creating a Sample Service Broker for Cloud Foundry with Python\u2019s Flask<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/building-a-cloud-foundry-service-broker-for-hp-idol\/\">Introducing a Cloud Foundry Service Broker for HP IDOL<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/research-papers\/microservices-vs-monolithic-architectures-the-pros-cons-and-cloud-foundry-examples\/\" target=\"_blank\" rel=\"noopener noreferrer\">Microservices vs. Monolithic Architectures (Pros\/Cons + Cloud Foundry Examples)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Pre-history<\/p>\n<p dir=\"ltr\">Buildpack is a core link in the chain of the Cloud Foundry deployment process. It automates detection of an application framework, application compilation and running. Being a happy user of Cloud Foundry for a long time, I haven&#8217;t had any troubles while using the official buildpacks for Ruby, Java, [&#8230;]<\/p>\n","protected":false},"author":35,"featured_media":19023,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[873,206],"class_list":["post-7022","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-cloud-native","tag-oss-cloud-foundry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood | Altoros<\/title>\n<meta name=\"description\" content=\"Though the official Cloud Foundry docs provide some general guidelines on how to create a buildpack, they do not demonstrate the in-depth behavior of scripts and how to test and debug buildpacks. Here, I&#039;ll try to fill in the missing gaps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood | Altoros\" \/>\n<meta property=\"og:description\" content=\"Pre-history Buildpack is a core link in the chain of the Cloud Foundry deployment process. It automates detection of an application framework, application compilation and running. Being a happy user of Cloud Foundry for a long time, I haven&#8217;t had any troubles while using the official buildpacks for Ruby, Java, [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-12T17:18:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-03-12T01:42:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"640\" \/>\n\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Alexander Lomov\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alexander Lomov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/\",\"name\":\"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif\",\"datePublished\":\"2014-12-12T17:18:58+00:00\",\"dateModified\":\"2021-03-12T01:42:15+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/32bad30d8a66fbba345c09f5ce9503a6\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif\",\"width\":640,\"height\":360},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/32bad30d8a66fbba345c09f5ce9503a6\",\"name\":\"Alexander Lomov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Alexander-Lomov-150x150.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Alexander-Lomov-150x150.jpg\",\"caption\":\"Alexander Lomov\"},\"description\":\"Alexander Lomov is a Cloud Foundry Engineer at Altoros. With extensive experience in Ruby, Go, and Python, he was involved in development of BOSH CPIs and other Cloud Foundry-related projects for Canonical, IBM, and other companies. Alexander is a frequent speaker at various events\/meetups, mostly sharing his experience with Cloud Foundry. You may also know him as the author of several blog posts about Cloud Foundry internals.\",\"sameAs\":[\"http:\/\/altoros.com\"],\"url\":\"https:\/\/www.altoros.com\/blog\/author\/alexander-lomov\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood | Altoros","description":"Though the official Cloud Foundry docs provide some general guidelines on how to create a buildpack, they do not demonstrate the in-depth behavior of scripts and how to test and debug buildpacks. Here, I'll try to fill in the missing gaps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/","og_locale":"en_US","og_type":"article","og_title":"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood | Altoros","og_description":"Pre-history Buildpack is a core link in the chain of the Cloud Foundry deployment process. It automates detection of an application framework, application compilation and running. Being a happy user of Cloud Foundry for a long time, I haven&#8217;t had any troubles while using the official buildpacks for Ruby, Java, [...]","og_url":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/","og_site_name":"Altoros","article_published_time":"2014-12-12T17:18:58+00:00","article_modified_time":"2021-03-12T01:42:15+00:00","og_image":[{"width":640,"height":360,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif","type":"image\/gif"}],"author":"Alexander Lomov","twitter_misc":{"Written by":"Alexander Lomov","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/","url":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/","name":"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif","datePublished":"2014-12-12T17:18:58+00:00","dateModified":"2021-03-12T01:42:15+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/32bad30d8a66fbba345c09f5ce9503a6"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/12\/Creating-a-Custom-Cloud-Foundry-Buildpack-from-Scratch.gif","width":640,"height":360},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/creating-a-custom-cloud-foundry-buildpack-from-scratch-whats-under-the-hood\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Creating a Custom Cloud Foundry Buildpack from Scratch: What\u2019s Under the Hood"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/32bad30d8a66fbba345c09f5ce9503a6","name":"Alexander Lomov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Alexander-Lomov-150x150.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Alexander-Lomov-150x150.jpg","caption":"Alexander Lomov"},"description":"Alexander Lomov is a Cloud Foundry Engineer at Altoros. With extensive experience in Ruby, Go, and Python, he was involved in development of BOSH CPIs and other Cloud Foundry-related projects for Canonical, IBM, and other companies. Alexander is a frequent speaker at various events\/meetups, mostly sharing his experience with Cloud Foundry. You may also know him as the author of several blog posts about Cloud Foundry internals.","sameAs":["http:\/\/altoros.com"],"url":"https:\/\/www.altoros.com\/blog\/author\/alexander-lomov\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/7022","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=7022"}],"version-history":[{"count":9,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/7022\/revisions"}],"predecessor-version":[{"id":60553,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/7022\/revisions\/60553"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/19023"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=7022"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=7022"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=7022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}