forked from cloudfoundry/docs-buildpacks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustom.html.md.erb
133 lines (81 loc) · 5.78 KB
/
custom.html.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
---
title: Custom Buildpacks
---
Buildpacks are a convenient way of packaging framework and/or runtime support for your application.
For example, by default Cloud Foundry does not support Haskell. Using a buildpack for Haskell would allow you to add support for it at the deployment stage. When an application written using Haskell is pushed, the required buildpack is automatically installed on the Cloud Foundry Droplet Execution Agent (DEA) where the application will run.
<p class="note"><strong>Note</strong>: A common development practice for custom buildpacks is to fork existing buildpacks and sync subsequent patches from upstream. To merge upstream patches to your custom buildpack, use the approach that Github recommends for <a href="https://help.github.com/articles/syncing-a-fork">syncing a fork</a>.</p>
## <a id='custom-buildpacks'></a>Custom Buildpacks ##
The structure of a buildpack is straightforward. A buildpack repository contains three main scripts, situated in a folder named `bin`.
### <a id='detect-script'></a>bin/detect ###
The `detect` script is used to determine whether or not to apply the buildpack to an application. The script is called with one argument, the build directory for the application. It returns an exit code of `0` if the application can be supported by the buildpack. If the script does return `0`, it should also print a framework name to STDOUT.
Shown below is an example `detect` script written in Ruby that checks for a Ruby application based on the existence of a `Gemfile`:
~~~ruby
#!/usr/bin/env ruby
gemfile_path = File.join ARGV[0], "Gemfile"
if File.exist?(gemfile_path)
puts "Ruby"
exit 0
else
exit 1
end
~~~
### <a id='compile-script'></a>bin/compile ###
The `compile` script builds the droplet that will be run by the DEA and will therefore contain all the components necessary to run the application.
The script is run with two arguments, the build directory for the application and the cache directory, which is a location the buildpack can use to store assets during the build process.
During execution of this script all output sent to STDOUT will be relayed via CF back to the end user. The generally accepted pattern for this is to break out this functionality in to a 'language_pack'. A good example of this can be seen at [https://github.com/cloudfoundry/heroku-buildpack-ruby/blob/master/lib/language_pack/ruby.rb](https://github.com/cloudfoundry/heroku-buildpack-ruby/blob/master/lib/language_pack/ruby.rb)
A simple `compile` script is shown below:
~~~ruby
#!/usr/bin/env ruby
#sync output
$stdout.sync = true
build_path = ARGV[0]
cache_path = ARGV[1]
install_ruby
private
def install_ruby
puts "Installing Ruby"
# !!! build tasks go here !!!
# download ruby to cache_path
# install ruby
end
~~~
### <a id='release-script'></a>bin/release ###
The `release` script provides feedback metadata back to Cloud Foundry indicating how the application should be executed. The script is run with one argument, the build location of the application. The script must generate a YAML file in the following format:
~~~yaml
config_vars:
name: value
default_process_types:
web: commandLine
~~~
Where `config_vars` is an optional set of environment variables that will be defined in the environment in which the application is executed. `default_process_types` indicates the type of application being run and the command line used to start it. At this time only `web` type of applications are supported.
The following example shows what a Rack application's `release` script might return:
~~~ruby
config_vars:
RACK_ENV: production
default_process_type:
web: bundle exec rackup config.ru -p $PORT
~~~
### <a id='package-script'></a>bin/package ###
The `package` script provides buildpack artifacts, which are provided to Cloud Foundry as system buildpacks. `package` is
intended to provide a way for buildpack developers to package a buildpack with its dependencies. Implementing this is
entirely optional. It is a Cloud Foundry extension to the [Heroku Buildpack API](https://devcenter.heroku.com/articles/buildpack-api).
The result of running the package script must be a zip file that adheres to the api outlined above, using `detect`,
`compile`, `release`.
The `package` script accepts two commands as arguments:
* `package online` produces a zip of the buildpack, preferably excluding unnecessary content such as tests.
* `package offline` produces a zip of the buildpack with all dependencies cached.
`package offline` produces a buildpack that does not need internet connectivity to run. For more information about the tradeoffs of the dependency storage options available for custom offline buildpacks, refer to the [Packaging Buildpack Dependecies](./depend-pkg-offline.html) topic.
The `package offline` command is used to produce the [system buildpacks](./index.html) bundled with
Cloud Foundry.
For an example implementation, see the [Cloud Foundry Ruby buildpack](https://github.com/cloudfoundry/cf-buildpack-ruby/blob/master/bin/package).
## <a id='deploying-with-custom-buildpacks'></a>Deploying With a Custom Buildpack ##
Once a custom buildpack has been created and pushed to a public git repository, the git URL can be passed via the cf command when pushing an application.
For example, for a buildpack that has been pushed to Github:
<pre class="terminal">
$ cf push my-new-app -b git://github.com/johndoe/my-buildpack.git
</pre>
Alternatively, it is possible to use a private git repository (with https and username/password authentication) as follows:
<pre class="terminal">
$ cf push my-new-app -b https://username:[email protected]/johndoe/my-buildpack.git
</pre>
The application will then be deployed to Cloud Foundry, and the buildpack will be cloned from the repository and applied to the application (provided that the `detect` script returns `0`).