forked from cloudfoundry/docs-buildpacks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
custom.html.md.erb
236 lines (155 loc) · 11 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
---
title: Working with Custom Buildpacks
owner: Buildpacks
---
<strong><%= modified_date %></strong>
## <a id='custom-buildpacks'></a>Buildpack Scripts ##
A buildpack repository contains three main scripts, situated in a folder named `bin`.
### <a id='detect-script'></a>bin/detect ###
The `detect` script determines whether or not to apply the buildpack to an app. The script is called with one argument, the `build` directory for the app. The `build` directory contains the app files uploaded when a user performs a `cf push`.
The `detect` script returns an exit code of `0` if the buildpack is compatible with the app. In the case of system buildpacks, the script also prints the buildpack name, version, and other helpful information to `STDOUT`.
The following is an example `detect` script written in Ruby that checks for a Ruby app 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
~~~
Optionally, the buildpack detect script can output additional details decided by the buildpack developer. These additional details include buildpack versioning information and a detailed list of configured frameworks and their associated versions.
The following is an example of the detailed information returned by the Java buildpack:
~~~
java-buildpack=v3.0-https://github.com/cloudfoundry/java-buildpack.git#3bd15e1 open-jdk-jre=1.8.0_45 spring-auto-reconfiguration=1.7.0_RELEASE tomcat-access-logging-support=2.4.0_RELEASE tomcat-instance=8.0.21 tomcat-lifecycle-support=2.4.0_RELEASE ...
~~~
### <a id='compile-script'></a>bin/compile ###
The `compile` script builds a droplet by packaging the app dependencies, assuring that the app has all the necessary components needed to run.
The script is run with two arguments: the `build` directory for the app and the `cache` directory, which is a location the buildpack can use to store assets during the build process. During the execution of the `compile` script, all output sent to `STDOUT` is relayed through the cf CLI to the user.
The following is an example of a simple `compile` script:
~~~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
# install ruby
end
~~~
### <a id='release-script'></a>bin/release ###
The `release` script provides feedback metadata to Cloud Foundry indicating how the app should be executed. The script is run with one argument, the `build` directory. The script must generate a YAML file in the following format:
~~~yaml
default_process_types:
web: start_command.filetype
~~~
`default_process_types` indicates the type of app being run and the command used to start it.
This start command is used if a start command is not specified in the `cf push` or in a Procfile.
At this time, only `web` type of apps are supported.
<p class="note"><strong>Note</strong>: To define environment variables for your buildpack, add a bash script to the <code>.profile.d</code> directory in the root folder of your app.</p>
The following example shows what a `release` script for a Rack app might return:
~~~ruby
default_process_types:
web: bundle exec rackup config.ru -p $PORT
~~~
<p class="note"><strong>Note</strong>: The <code>web</code> command runs as <code>bash -c COMMAND</code> when Cloud Foundry starts your app. Refer to <a href="../devguide/deploy-apps/manifest.html#start-commands">the command attribute</a> section for more information about custom start commands. </p>
## <a id='droplet-filesystem'></a> Droplet Filesystem ##
The buildpack staging process extracts the droplet into the `/home/vcap` directory inside the instance container, and creates the following filesystem tree:
```
app/
logs/
tmp/
staging_info.yml
```
The `app` directory contains `BUILD_DIR` contents, and `staging_info.yml` contains the staging metadata saved in the droplet.
## <a id='packaging-custom-buildpacks'></a> Package Custom Buildpacks ##
Cloud Foundry buildpacks can work with limited or no Internet connectivity. The [Buildpack Packager](https://github.com/cloudfoundry-incubator/buildpack-packager) RubyGem gives the same flexibility to custom buildpacks, enabling them to work in partially or completely disconnected environments.
### <a id='use-buildpack-packager'></a> Use the Buildpack Packager
1. Ensure that you have installed the [Buildpack Packager](https://github.com/cloudfoundry-incubator/buildpack-packager) RubyGem.
1. Create a manifest.yml in your buildpack.
1. Run the packager in cached mode:
<pre class="terminal">$ buildpack-packager --cached</pre>
The packager will add (almost) everything in your buildpack directory into a zip file. It will exclude anything marked for exclusion in your manifest.
In cached mode, the packager will download and add dependencies as described in the manifest.
The packager has the following option flags:
* `--force-download`: By default, the packager stores the dependencies that it downloads while building a cached buildpack in a local cache at `~/.buildpack-packager`. Storing dependencies enables the packager to avoid re-downloading them when repackaging similar buildpacks. Running `buildpack-packager --cached` with the `--force-download` option forces the packager to download dependencies from the S3 host and ignore the local cache. When packaging an uncached buildpack, `--force-download` does nothing.
* `--use-custom-manifest`: To include a different manifest file in your packaged buildpack, you can call the packager with the `--use-custom-manifest PATH/TO/MANIFEST.YML` option. The packager generates a buildpack with the specified manifest. If you are building a cached buildpack, the packager vendors dependencies from the specified manifest as well.
For more information, see the documentation at the [Buildpack Packager Github repository](https://github.com/cloudfoundry-incubator/buildpack-packager).
### <a id='share-buildpack-package'></a> Use and Share the Packaged Buildpack
After you have packaged your buildpack using `buildpack-packager` you can use the resulting `.zip` file locally, or share it with others by uploading it to any network location that is accessible to the CLI. Users can then specify the buildpack with the `-b` option when they push apps. See <a href="#deploying-with-custom-buildpacks">Deploying Apps with a Custom Buildpack</a> for details.
<p class="note"><strong>Note</strong>: Offline buildpack packages may contain proprietary dependencies that require distribution licensing or export control measures. For more information about offline buildpacks, refer to <a href="depend-pkg-offline.html#offline-buildpacks">Packaging Dependencies for Offline Buildpacks</a>.</p>
<%=vars.upload_custom_buildpacks%>
<%=vars.link_adminguide_buildpack%>
### <a id='specifying-default-versions'></a> Specify a Default Version ###
As of `buildpack-packager` [version 2.3.0](https://github.com/cloudfoundry/buildpack-packager/releases/tag/v2.3.0), you can specify the default version for a dependency by adding a `default_versions` object to the `manifest.yml` file.
The `default_versions` object has two properties, `name` and `version`. For example:
```yml
default_versions:
- name: go
version: 1.6.3
- name: other-dependency
version: 1.1.1
```
To specify a default version:
1. Add the `default_version` object to your manifest, following the [rules](#rules) below. You can find a complete example manifest in the Cloud Foundry [go-buildpack](https://github.com/cloudfoundry/go-buildpack/blob/f1a380f2f3a8012491c6007948af74676713dd50/manifest.yml) repository.
1. Run the `default_version_for` script from the [compile-extensions](https://github.com/cloudfoundry/compile-extensions) repository, passing the path of your `manifest.yml` and the dependency name as arguments. The following command uses the example manifest from step 1:
<pre class="terminal">
$ ./compile-extensions/bin/default\_version\_for manifest.yml go 1.6.3
</pre>
#### Rules for Specifying a Default Version
The `buildpack-packager` script validates this object according to the following rules:
* You can create at most one entry under `default_versions` for a single dependency. The following example causes `buildpack-packager` to fail with an error because the manifest specifies two default versions for the same `go` dependency.
```yml
# Incorrect; will fail to package
default_versions:
- name: go
version: 1.6.3
- name: go
version: 1.3.1
```
* If you specify a `default_version` for a dependency, you must also list that dependency and version under the `dependencies` section of the manifest. The following example causes `buildpack-packager` to fail with an error because the manifest specifies `version: 1.6.3` for the `go` dependency, but lists `version: 1.5.4` under `dependencies`.
```yml
# Incorrect; will fail to package
default_versions:
- name: go
version: 1.6.3
dependencies:
- name: go
version: 1.5.4
uri: https://storage.googleapis.com/golang/go1.5.4.linux-amd64.tar.gz
md5: 27b1c469797292064c65c995ffe30386
cf_stacks:
- cflinuxfs2
```
## <a id='deploying-with-custom-buildpacks'></a>Deploy Apps 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 CLI when pushing an app.
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, you can 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>
By default, Cloud Foundry uses the default branch of the buildpack's git repository. You can specify a different branch using the git url as shown in the following example:
<pre class="terminal">
$ cf push my-new-app -b https://github.com/johndoe/my-buildpack.git#my-branch-name
</pre>
Additionally, you can use tags or shas in a git repository, as follows:
<pre class="terminal">
$ cf push my-new-app -b https://github.com/johndoe/my-buildpack#v1.4.2
</pre>
<pre class="terminal">
$ cf push my-new-app -b https://github.com/johndoe/my-buildpack#a2951e298bd22732fceb3968d541015120dbaf93
</pre>
The app will then be deployed to Cloud Foundry, and the buildpack will be cloned from the repository and applied to the app.
<p class="note"><strong>Note</strong>: If a buildpack is specified using `cf push -b` the `detect` step will be skipped and as a result, no buildpack `detect` scripts will be run.
</p>
<%= vars.disable_custom %>
<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>