Permalink
672 lines (471 sloc) 25.9 KB
---
title: Deploying with Application Manifests
owner:
- CAPI
- CLI
---
<strong><%= modified_date %></strong>
Application manifests tell `cf push` what to do with applications.
This includes everything from how many instances to create and how much memory
to allocate to what services applications should use.
A manifest can help you automate deployment, especially of multiple applications
at once.
##<a id='find-manifest'></a>How cf push Finds the Manifest ##
By default, the `cf push` command deploys an application using a `manifest.yml`
file in the current working directory.
<pre class="terminal">
$ cf push
Using manifest file /path_to_working_directory/manifest.yml
</pre>
If your manifest is located elsewhere, use the `-f` option to provide the path to the filename.
<pre class="terminal">
$ cf push -f ./some_directory/some_other_directory/alternate_manifest.yml
Using manifest file /path_to_working_directory/some_directory/some_other_directory/alternate_manifest.yml
</pre>
If you provide a path with no filename, the filename must be
`manifest.yml`.
<pre class="terminal">
$ cf push -f ./some_directory/some_other_directory/
Using manifest file /path_to_working_directory/some_directory/some_other_directory/manifest.yml
</pre>
##<a id='minimal-manifest'></a>Example Manifest ##
You can deploy applications without ever using a manifest.
The benefits manifests may provide include consistency and reproducibility.
When you want applications to be portable between different clouds, manifests
may prove especially useful.
Manifests are written in YAML. The manifest below illustrates some YAML conventions, as follows:
* The manifest may begin with three dashes.
* The `applications` block begins with a heading followed by a colon.
* The application `name` is preceded by a single dash and one space.
* Subsequent lines in the block are indented two spaces to align with `name`.
<pre>
---
applications:
- name: nifty-gui
memory: 512M
host: nifty
</pre>
A minimal manifest requires only an application `name`.
To create a valid minimal manifest, remove the `memory` and `host` properties
from this example.
##<a id='name'></a>Always Provide an Application Name to cf push ##
`cf push` requires an application name, which you provide either in a manifest
or at the command line.
As described in [How cf push Finds the Manifest](#find-manifest) above, the
command `cf push` locates the `manifest.yml` in the current working
directory by default, or in the path provided by the `-f` option.
If you do not use a manifest, the minimal push command looks like this:
<pre class="terminal">
$ cf push my-app
</pre>
<p class="note"><strong>Note</strong>: When you provide an application name at the command line, <code>cf push</code> uses that application name whether or not there is a different application name in the manifest. If the manifest describes multiple applications, you can push a single application by providing its name at the command line; the cf CLI does not push the others.
Use these behaviors for testing.</p>
##<a id='find-app'></a>How cf push Finds the Application ##
By default, `cf push` recursively pushes the contents of the current working directory. Alternatively, you can provide a path using either a manifest or a command line option.
- If the path is to a directory, `cf push` recursively pushes the contents of that directory instead of the current working directory.
- If the path is to a file, `cf push` pushes only that file.
<p class="note"><strong>Note</strong>: If you want to push more than a single file, but not the entire contents of a directory, consider using a <code>.cfignore</code> file to tell <code>cf push</code> what to exclude.</p>
##<a id='precedence'></a>Precedence Between Manifests, Command Line Options, and Most Recent Values ##
When you push an application for the first time, Cloud Foundry applies default values to any attributes that you do not set in a manifest or `cf push` command line options.
* For example, `cf push my-app` with no manifest might deploy one instance of the app with one gigabyte of memory.
In this case the default values for instances and memory are "1" and "1G", respectively.
Between one push and another, attribute values can change in other ways.
* For example, the `cf scale` command changes the number of instances.
The attribute values on the server at any one time represent the cumulative result of all settings applied up to that point: defaults, attributes in the manifest, `cf push` command line options, and commands like `cf scale`.
There is no special name for this resulting set of values on the server.
You can think of them as the most recent values.
`cf push` follows rules of precedence when setting attribute values:
* Manifests override most recent values, including defaults.
* Command line options override manifests.
In general, you can think of manifests as just another input to `cf push`, to be combined with command line options and most recent values.
##<a id='optional-attributes'></a>Optional Attributes ##
This section explains how to describe optional application attributes in manifests. Each of these attributes can also be specified by a command line option. Command line options override the manifest.
###<a id='buildpack'></a>buildpack ###
If your application requires a custom buildpack, you can use the `buildpack` attribute to specify it in one of three ways:
* By name: `MY-BUILDPACK`.
* By GitHub URL: `https://github.com/cloudfoundry/java-buildpack.git`.
* By GitHub URL with a branch or tag: `https://github.com/cloudfoundry/java-buildpack.git#v3.3.0` for the `v3.3.0` tag.
<pre>
---
...
buildpack: buildpack_URL
</pre>
<p class="note"><strong>Note</strong>: The <code>cf buildpacks</code> command lists the buildpacks that you can refer to by name in a manifest or a command line option.</p>
The command line option that overrides this attribute is `-b`.
###<a id='start-commands'></a>command ###
Some languages and frameworks require that you provide a custom command to start an application. Refer to the [buildpack](../../buildpacks/index.html) documentation to determine if you need to provide a custom start command.
You can provide the custom start command in your application manifest or on the command line. See <a href="./start-restart-restage.html">Starting, Restarting, and Restaging Applications</a> for more information about how Cloud Foundry determines its default start command.
To specify the custom start command in your application manifest, add it in the `command: START-COMMAND` format as the following example shows:
<pre>
---
...
command: bundle exec rake VERBOSE=true
</pre>
The start command you specify becomes the default for your application. To return to using the original default start command set by your buildpack, you must explicitly set the attribute to `null` as follows:
<pre>
---
...
command: null
</pre>
On the command line, use the `-c` option to specify the custom start command as the following example shows:
<pre class="terminal">
$ cf push my-app -c "bundle exec rake VERBOSE=true"
</pre>
<p class="note"><strong>Note</strong>: The <code>-c</code> option with a value of 'null' forces <code>cf push</code> to use the buildpack start command. See <a href="./start-restart-restage.html#revert">Forcing cf push to use the Buildpack Start Command</a> for more information.</p>
If you override the start command for a Buildpack application, Linux uses
<code>bash -c YOUR-COMMAND</code> to invoke your application.
If you override the start command for a Docker application, Linux uses <code>sh -c YOUR-COMMAND</code> to invoke your application.
Because of this, if you override a start command, you should prefix <code>exec</code> to the final command in your custom composite start command.
An app needs to catch [termination signals](./prepare-to-deploy.html#moving-apps) and clean itself up appropriately. Because of the way that shells manage process trees, the use of custom composite shell commands, particularly those that create child processes using `&`, `&&`, `||`, etc., can prevent your app from receiving signals that are sent to the top level bash process.
To resolve this issue, you can use `exec` to replace the bash process with your own process. For example:
* `bin/rake cf:on_first_instance db:migrate && bin/rails server -p $PORT -e $RAILS_ENV` The process tree is bash -> ruby, so on graceful shutdown only the bash process receives the TERM signal, not the ruby process.
* `bin/rake cf:on_first_instance db:migrate && exec bin/rails server -p $PORT -e $RAILS_ENV` Because of the `exec` prefix included on the final command, the ruby process invoked by rails takes over the bash process managing the execution of the composite command. The process tree is only ruby, so the ruby web server receives the TERM signal and can shutdown gracefully for 10 seconds.
In more complex situations, like making a custom buildpack, you may want to use bash `trap`, `wait`, and backgrounded processes to manage your process tree and shut down apps gracefully. In most situations, however, a well-placed `exec` should be sufficient.
###<a id='disk-quota'></a>disk_quota ###
Use the `disk_quota` attribute to allocate the disk space for your app instance. This attribute requires a unit of measurement: `M`, `MB`, `G`, or `GB`, in upper case or lower case.
<pre>
---
...
disk_quota: 1024M
</pre>
The command line option that overrides this attribute is `-k`.
###<a id='domain'></a>domain ###
Every `cf push` deploys applications to one particular Cloud Foundry instance.
Every Cloud Foundry instance may have a shared domain set by an admin.
Unless you specify a domain, Cloud Foundry incorporates that shared domain in the route to your application.
You can use the `domain` attribute when you want your application to be served from a domain other than the default shared domain.
<pre>
---
...
domain: unique-example.com
</pre>
The command line option that overrides this attribute is `-d`.
###<a id='domains'></a>domains ###
Use the `domains` attribute to provide multiple domains. If you define both `domain` and `domains` attributes, Cloud Foundry creates routes for domains defined in both of these fields.
<pre>
---
...
domains:
- domain-example1.com
- domain-example2.org
</pre>
The command line option that overrides this attribute is `-d`.
###<a id='health-check-http-endpoint'></a>health-check-http-endpoint ###
Use the `health-check-http-endpoint` attribute to customize the endpoint for the `http` health check type. If you do not provide a `health-check-http-endpoint` attribute,
it uses endpoint '/'.
<pre>
---
...
health-check-type: http
health-check-http-endpoint: /health
</pre>
###<a id='health-check-type'></a>health-check-type ###
Use the `health-check-type` attribute to set the `health_check_type` flag to either `port`, `process` or `http`. If you do not provide a `health-check-type` attribute,
it defaults to `port`.
<pre>
---
...
health-check-type: port
</pre>
The command line option that overrides this attribute is `-u`.
The value of `none` is deprecated in favor of `process`.
###<a id='host'></a>host ###
Use the `host` attribute to provide a hostname, or subdomain, in the form of a string. This segment of a route helps to ensure that the route is unique. If you do not provide a hostname, the URL for the app takes the form of `APP-NAME.DOMAIN`.
<pre>
---
...
host: my-app
</pre>
The command line option that overrides this attribute is `-n`.
###<a id='hosts'></a>hosts ###
Use the `hosts` attribute to provide multiple hostnames, or subdomains. Each hostname generates a unique route for the app. `hosts` can be used in conjunction with `host`. If you define both attributes, Cloud Foundry creates routes for hostnames defined in both `host` and `hosts`.
<pre>
---
...
hosts:
- app_host1
- app_host2
</pre>
The command line option that overrides this attribute is `-n`.
###<a id='instances'></a>instances ###
Use the `instances` attribute to specify the number of app instances that you want to start upon push:
<pre>
---
...
instances: 2
</pre>
We recommend that you run at least two instances of any apps for which fault tolerance matters.
The command line option that overrides this attribute is `-i`.
###<a id='memory'></a>memory ###
Use the `memory` attribute to specify the memory limit for all instances of an app. This attribute requires a unit of measurement: `M`, `MB`, `G`, or `GB`, in upper case or lower case. For example:
<pre>
---
...
memory: 1024M
</pre>
The default memory limit is 1G. You might want to specify a smaller limit to conserve <%=vars.quota_resource%> if you know that your app instances do not require 1G of memory.
The command line option that overrides this attribute is `-m`.
###<a id='nohosts'></a>no-hostname ###
By default, if you do not provide a hostname, the URL for the app takes the form of `APP-NAME.DOMAIN`. If you want to override this and map the root domain to this app then you can set no-hostname as true.
<pre>
---
...
no-hostname: true
</pre>
The command line option that corresponds to this attribute is `--no-hostname`.
###<a id='no-route'></a>no-route ###
By default, `cf push` assigns a route to every app. But, some apps process data while running in the background and should not be assigned routes.
You can use the `no-route` attribute with a value of `true` to prevent a route from being created for your app.
<pre>
---
...
no-route: true
</pre>
The command line option that corresponds to this attribute is `--no-route`.
In the newer Diego architecture, `no-route` skips creating and binding a route for the app, but does not specify which type of health check to perform. If your app does not listen on a port because it is a worker or a scheduler app, then it does not satisfy the port-based health check and Cloud Foundry marks it as crashed. To prevent this, disable the port-based health check with `cf set-health-check APP_NAME none`.
In the older Droplet Execution Agent (DEA) architecture, `cf set-health-check APP_NAME none` is unnecessary because `no-route` causes the DEAs to skip the port health-check on app startup.
To remove a route from an existing app, perform the following steps:
1. Remove the route using the `cf unmap-route` command.
1. Push the app again with the `no-route: true` attribute in the manifest or the `--no-route` command line option.
For more information, see [Describing Multiple Applications with One Manifest](#multi-apps) below.
###<a id='path'></a>path
You can use the `path` attribute to tell Cloud Foundry the directory location where it can find your application.
The directory specified as the `path`, either as an attribute or as a parameter on the command line, becomes the location where the buildpack `Detect` script executes.
The command line option that overrides this attribute is `-p`.
<pre>
---
...
path: /path/to/application/bits
</pre>
For more information, see the [How cf push Finds the Application](#find-app) topic.
###<a id='random-route'></a>random-route ###
Use the `random-route` attribute to create a URL that includes the app name and
random words.
Use this attribute to avoid URL collision when pushing the same app to multiple spaces, or to avoid managing app URLs.
The command line option that corresponds to this attribute is `--random-route`.
<pre>
---
...
random-route: true
</pre>
###<a id='routes'></a>routes ###
Use the `routes` attribute to provide multiple HTTP and TCP routes. Each route for this app is created if it does not already exist.
This attribute is a combination of `push` options that include `--hostname`, `-d`, and `--route-path`.
<pre>
---
...
routes:
- route: example.com
- route: www.example.com/foo
- route: tcp-example.com:1234
</pre>
#### Manifest Attributes
The `routes` attribute cannot be used in conjunction with the following attributes: `host`, `hosts`, `domain`, `domains`, and `no-hostname`. An error will result.
#### Push Flag Options
This attribute has unique interactions with different command line options.
<table border="1" class="nice" >
<tr>
<th>Push Flag Option</th>
<th>Resulting Behaviour</th>
</tr>
<tr>
<td><code>--no-route</code></td>
<td>All declared routes are ignored.</td>
</tr>
<td><code>-d</code></td>
<td>Overrides DOMAIN part of all declared HTTP and TCP routes.</td>
</tr>
<tr>
<td><code>--hostname, -n</code></td>
<td>Sets or overrides HOSTNAME in all HTTP routes. <br />
It has no impact on TCP routes.</td>
</tr>
<tr>
<td><code>--route-path</code></td>
<td>Sets or overrides the PATH in all HTTP routes.<br />
It has no impact on TCP routes.</td>
</tr>
<tr>
<td><code>--random-route</code></td>
<td>Sets or overrides the HOSTNAME in all HTTP routes.<br />
Sets or overrides the PORT in all TCP routes.<br />
The PORT and HOSTNAME will be randomly generated.</td>
</tr>
<tr>
</table>
###<a id='stack'></a>stack ###
Use the `stack` attribute to specify which stack to deploy your application to.
To see a list of available stacks, run `cf stacks` from the cf cli.
<pre>
---
...
stack: cflinuxfs2
</pre>
The command line option that overrides this attribute is `-s`.
###<a id='timeout'></a>timeout ###
The `timeout` attribute defines the number of seconds that Cloud Foundry allocates for starting your application.
For example:
<pre>
---
...
timeout: 80
</pre>
You can increase the timeout length for very large apps that require more time to start. The default timeout is 60 seconds, with an upper bound of 180 seconds.
<p class="note"><strong>Note</strong>: Administrators can set the upper bound of the `maximum_health_check_timeout` property to any value. Any changes to Cloud Controller properties in the deployment manifest require running `bosh deploy`.</p>
The command line option that overrides the timeout attribute is `-t`.
##<a id='env-block'></a>Environment Variables ###
The `env` block consists of a heading, then one or more environment variable/value pairs.
For example:
<pre>
---
...
env:
RAILS_ENV: production
RACK_ENV: production
</pre>
`cf push` deploys the application to a container on the server. The variables belong to the container environment.
While the application is running, you can modify environment variables.
* View all variables: `cf env my-app`
* Set an individual variable: `cf set-env my-app my-variable_name my-variable_value`
* Unset an individual variable: `cf unset-env my-app my-variable_name my-variable_value`
Environment variables interact with manifests in the following ways:
* When you deploy an application for the first time, Cloud Foundry reads the variables described in the environment block of the manifest and adds them to
the environment of the container where the application is staged, and the environment of the container where the application is deployed.
* When you stop and then restart an application, its environment variables persist.
##<a id='services-block'></a>Services ###
Applications can bind to services such as databases, messaging, and key-value stores.
Applications are deployed into App Spaces. An application can only bind to services instances that exist in the target App Space before the application is deployed.
The `services` block consists of a heading, then one or more service instance names.
Whoever creates the service chooses the service instance names. These names can convey logical information, as in `backend_queue`, describe the nature of the service, as in `mysql_5.x`, or do neither, as in the example below.
<pre>
---
...
services:
- instance_ABC
- instance_XYZ
</pre>
Binding to a service instance is a special case of setting an environment variable, namely `VCAP_SERVICES`. See the [Bind a Service](../services/application-binding.html#bind) section of the _Delivering Service Credentials to an Application_ topic.
##<a id='multi-apps'></a>Describing Multiple Applications with One Manifest ##
You can deploy multiple applications with one `cf push` command by describing them in a single manifest. In doing so, you need to pay extra attention to directory structure and path lines in the manifest.
Suppose you want to deploy two applications called respectively spark and flame, and you want Cloud Foundry to create and start spark before flame. You accomplish this by listing spark first in the manifest.
In this situation there are two sets of bits that you want to push. Let’s say that they are `spark.rb` in the spark directory and `flame.rb` in the flame directory. One level up, the `fireplace` directory contains the spark and the flame directories along with the `manifest.yml` file. Your plan is to run the cf CLI from the `fireplace` directory, where you know it can find the manifest.
Now that you have changed the directory structure and manifest location, `cf push` can no longer find your applications by its default behavior of looking in the current working directory. How can you ensure that `cf push` finds the bits you want to push?
The answer is to add a path line to each application description to lead `cf push` to the correct bits. Assume that `cf push` is run from the `fireplace` directory.
For `spark`:
<pre>
---
...
path: ./spark/
</pre>
For `flame`:
<pre>
---
...
path: ./flame/
</pre>
The manifest now consists of two applications blocks.
<pre>
---
# this manifest deploys two applications
# apps are in flame and spark directories
# flame and spark are in fireplace
# cf push should be run from fireplace
applications:
- name: spark
memory: 1G
instances: 2
host: flint-99
domain: <%=vars.app_domain%>
path: ./spark/
services:
- mysql-flint-99
- name: flame
memory: 1G
instances: 2
host: burnin-77
domain: <%=vars.app_domain%>
path: ./flame/
services:
- redis-burnin-77
</pre>
Follow these general rules when using a multiple-application manifest:
* Name and completely describe your applications in the manifest.
* Use a `no-route` line in the description of any application that provides background services to another application.
* Do not provide an application name with `cf push`.
* Do not use any command line options with `cf push`.
There are only two narrow exceptions:
* If your manifest is not named `manifest.yml` or not in the current working directory, use the `-f` command line option.
* If you want to push a single application rather than all of the applications described in the manifest, provide the desired application name by running `cf push my-app`.
##<a id='minimize-duplication'></a>Minimizing Duplication ##
In manifests where multiple applications share settings or services, you begin to see content duplicated. While the manifests still work, duplication increases the risk of typographical errors which cause deployment to fail.
The cure for this problem is to "promote" the duplicate content—that is, to move it up above the applications block, where it need appear only once. The promoted content applies to all applications described in the manifest. Note that content _in_ the applications block overrides content _above_ the applications block, if the two conflict.
The manifest becomes shorter, more readable, and more maintainable.
Notice how much content in the manifest below has been promoted in this way.
<pre>
---
...
# all applications use these settings and services
domain: <%=vars.app_domain%>
memory: 1G
instances: 1
services:
- clockwork-mysql
applications:
- name: springtock
host: tock09876
path: ./spring-music/build/libs/spring-music.war
- name: springtick
host: tick09875
path: ./spring-music/build/libs/spring-music.war
</pre>
In the next section we carry this principle further by distributing content across multiple manifests.
##<a id='multi-manifests'></a>Multiple Manifests with Inheritance ##
A single manifest can describe multiple applications. Another powerful technique is to create multiple manifests with inheritance. Here, manifests have parent-child relationships such that children inherit descriptions from a parent. Children can use inherited descriptions as-is, extend them, or override them.
Content in the child manifest overrides content in the parent manifest, if the two conflict.
This technique helps in these and other scenarios:
* An application has a set of different deployment modes, such as debug, local, and public. Each deployment mode is described in child manifests that extend the settings in a base parent manifest.
* An application is packaged with a basic configuration described by a parent manifest. Users can extend the basic configuration by creating child manifests that add new properties or override those in the parent manifest.
The benefits of multiple manifests with inheritance are similar to those of minimizing duplicated content within single manifests. With inheritance, though, we "promote" content by placing it in the parent manifest.
Every child manifest must contain an "inherit" line that points to the parent manifest. Place the inherit line immediately after the three dashes at the top of the child manifest. For example, every child of a parent manifest called `base-manifest.yml` begins like this:
<pre>
---
inherit: base-manifest.yml
...
</pre>
You do not need to add anything to the parent manifest.
In the simple example below, a parent manifest gives each application minimal resources, while a production child manifest scales them up.
**simple-base-manifest.yml**
<pre>
---
path: .
domain: <%=vars.app_domain%>
memory: 256M
instances: 1
services:
- singular-backend
# app-specific configuration
applications:
- name: springtock
host: 765shower
path: ./april/build/libs/april-weather.war
- name: wintertick
host: 321flurry
path: ./december/target/december-weather.war
</pre>
**simple-prod-manifest.yml**
<pre>
---
inherit: simple-base-manifest.yml
applications:
- name:springstorm
memory: 512M
instances: 1
host: 765deluge
path: ./april/build/libs/april-weather.war
- name: winterblast
memory: 1G
instances: 2
host: 321blizzard
path: ./december/target/december-weather.war
</pre>
<p class='note'><strong>Note</strong>: Inheritance can add an additional level of complexity to manifest creation and maintenance. Comments that precisely explain how the child manifest extends or overrides the descriptions in the parent manifest can alleviate this complexity.</p>