Routes and Domains

Page last updated:

This topic describes how routes and domains work in Pivotal Web Services (PWS), and how developers and administrators configure routes and domains for their applications using the Cloud Foundry Command Line Interface (cf CLI).

For more information about routing capabilities in PWS, see the HTTP Routing topic.

Routes

The PWS Gorouter routes requests to applications by associating an app with an address, known as a route. We call this association a mapping. Use the cf CLI cf map-route command to associate an app and route.

The routing tier compares each request with a list of all the routes mapped to apps and attempts to find the best match. For example, the Gorouter would make the following matches for the two routes myapp.cfapps. and myapp.cfapps./products:

Request Matched Route
http://myapp.cfapps. myapp.cfapps.
http://myapp.cfapps./contact myapp.cfapps.
http://myapp.cfapps./products myapp.cfapps./products
http://myapp.cfapps./products/123 myapp.cfapps./products
http://products.cfapps. No match; 404

The Gorouter does not use a route to match requests until the route is mapped to an app. In the above example, products.cfapps. may have been created as a route in Cloud Foundry, but until it is mapped to an app, requests for the route receive a 404.

The routing tier knows the location of instances for apps mapped to routes. Once the routing tier determines a route as the best match for a request, it makes a load-balancing calculation using a round-robin algorithm, and forwards the request to an instance of the mapped app.

Developers can map many apps to a single route, resulting in load-balanced requests for the route across all instances of all mapped apps. This approach enables the blue/green zero-downtime deployment strategy. Developers can also map an individual app to multiple routes, enabling access to the app from many URLs.

Routes belong to a space, and developers can only map apps to a route in the same space.

Note: Routes are globally unique. Developers in one space cannot create a route with the same URL as developers in another space, regardless of which orgs control these spaces.

HTTP vs. TCP Routes

Note: By default, PWS only supports routing of HTTP requests to applications.

Routes are considered HTTP if they are created from HTTP domains, and TCP if the are created from TCP domains. See HTTP vs. TCP Shared Domains.

HTTP routes include a domain, an optional hostname, and an optional context path. cfapps., myapp.cfapps., and myapp.cfapps./products are all examples of HTTP routes. Applications should listen to the localhost port defined by the $PORT environment variable, which is 8080 on Diego. As an example, requests to myapp.cfapps. would be routed to the application container at localhost:8080.

  • Requests to HTTP routes must be sent to ports 80 or 443.
  • Ports cannot be reserved for HTTP routes.

TCP routes include a domain and a route port. A route port is the port clients make requests to. This is not the same port as what an application pushed to Cloud Foundry listens on. tcp.shared-domain.example.com:60000 is an example of a TCP route. Just as for HTTP routes, applications should listen to the localhost port defined by the $PORT environment variable, which is 8080 on Diego. As an example, requests to tcp.shared-domain.example.com:60000 would be routed to the application container at localhost:8080.

  • Once a port is reserved for a route, it cannot be reserved for another route.
  • Hostname and path are not supported for TCP routes.

Create a Route

When a developer creates a route using the cf CLI, PWS determines whether the route is an HTTP or a TCP route based on the domain. To create a HTTP route, a developer must choose an HTTP domain. To create a TCP route, a developer must choose a TCP domain.

Domains in PWS provide a namespace from which to create routes. To list available domains for a targeted organization, use the cf domains command. For more information about domains, see the Domains section.

The following sections describe how developers can create HTTP and TCP routes for different use cases.

Create an HTTP Route with Hostname

In PWS, a hostname is the label that indicates a subdomain of the domain associated with the route. Given a domain cfapps., a developer can create the route myapp.cfapps. in space my-space by specifying the hostname myapp with the cf create-route command as shown in this example:

$ cf create-route my-space cfapps. --hostname myapp
Creating route myapp.cfapps. for org my-org / space my-space as username@example.com...
OK

This command instructs PWS to only route requests to apps mapped to this route for the following URLs:

  • http://myapp.cfapps.
  • https://myapp.cfapps.
  • Any path under either of the above URLs, such as http://myapp.cfapps./bar

Create an HTTP Route without Hostname

This approach creates a route with the same address as the domain itself and is permitted for private domains only. For more information, see the Private Domains section.

A developer can create a route in space my-space from the domain private-domain.example.com with no hostname with the cf create-route command:

$ cf create-route my-space private-domain.example.com
Creating route private-domain.example.com for org my-org / space my-space as username@example.com...
OK

If DNS has been configured correctly, this command instructs PWS to route requests to apps mapped to this route from the following URLs:

  • http://private-domain.example.com
  • https://private-domain.example.com
  • Any path under either of the above URLs, such as http://private-domain.example.com/foo

If there are no other routes for the domain, requests to any subdomain, such as http://foo.private-domain.example.com, will fail.

A developer can also create routes for subdomains with no hostnames. The following command creates a route in space my-space from the subdomain foo.private-domain.example.com:

$ cf create-route my-space foo.private-domain.example.com
Creating route foo.private-domain.example.com for org my-org / space my-space as username@example.com...
OK

Assuming DNS has been configured for this subdomain, this command instructs PWS to route requests to apps mapped to this route from the following URLs:

  • http://foo.private-domain.example.com
  • https://foo.private-domain.example.com
  • Any path under either of the above URLs, such as http://foo.private-domain.example.com/foo

Create an HTTP Route with Wildcard Hostname

An application mapped to a wildcard route acts as a fallback app for route requests if the requested route does not exist. To create a wildcard route, use an asterisk for the hostname.

A developer can create a wildcard route in space my-space from the domain foo.cfapps. with the following command:

$ cf create-route my-space foo.cfapps. --hostname '*'
Creating route *.foo.cfapps. for org my-org / space my-space as username@example.com...
OK

If a client sends a request to http://app.foo.cfapps. by accident, attempting to reach myapp.foo.cfapps., PWS routes the request to the app mapped to the route *.foo.cfapps..

Create an HTTP Route with a Path

Developers can use paths to route requests for the same hostname and domain to different apps.

A developer can create three routes using the same hostname and domain in the space my-space with the following commands:

$ cf create-route my-space cfapps. --hostname store --path products
Creating route store.cfapps./products for org my-org / space my-space as username@example.com...
OK

$ cf create-route my-space cfapps. --hostname store --path orders
Creating route store.cfapps./orders for org my-org / space my-space as username@example.com...
OK

$ cf create-route my-space cfapps. --hostname store
Creating route store.cfapps. for org my-org / space my-space as username@example.com...
OK

The developer can then map the new routes to different apps by following the steps in the Map a Route to Your Application section below.

If the developer maps the first route with path products to the products app, the second route with path orders to the orders app, and the last route to the storefront app. After this, the following occurs:

  • PWS routes requests to http://store.cfapps./products to the products app.
  • PWS routes requests to http://store.cfapps./orders to the orders app.
  • PWS routes requests to http://store.cfapps. to the storefront app.

PWS attempts to match routes with a path first, and then attempts to match host and domain.

Note: Routes with the same domain and hostname but different paths can only be created in the same space. Private domains do not have this limitation.

Note: PWS does not route requests for context paths to the root context of an application. Applications must serve requests on the context path.

Create a TCP Route with a Port

A developer can create a TCP route for tcp.cfapps. on an arbitrary port with the following command. If the clients of the app can accommodate addressing an arbitrary port, then developers should use the --random-port to instruct PWS to pick a port for your route.

$ cf create-route my-space tcp.cfapps. --random-port
Creating route tcp.cfapps. for org my-org / space my-space as user@example.com...
OK
Route tcp.cfapps.:60034 has been created

In this example, PWS routes requests to tcp.cfapps.:60034 to apps mapped to this route.

To request a specific port, a developer can use the --port flag, so long as the port is not reserved for another space. The following command creates a TCP route for tcp.cfapps. on port 60035:

$ cf create-route my-space tcp.cfapps. --port 60035
Creating route tcp.cfapps.:60035 for org my-org / space my-space as user@example.com...
OK

List Routes

Developers can list routes for the current space with the cf routes command. A route is uniquely identified by the combination of hostname, domain, port, and path.

$ cf routes
Getting routes as user@private-domain.example.com ...

space      host     domain                      port   path       type  apps
my-space   myapp    cfapps.                         myapp
my-space   myapp    private-domain.example.com                          myapp
my-space   store    cfapps.        /products        products
my-space   store    cfapps.        /orders          orders
my-space   store    cfapps.                         storefront
my-space            cfapps. 60000             tcp   tcp-app

Developers can only see routes in spaces where they are members.

Check Routes

Developers cannot create a route that is already taken. To check whether a route is available, developers can use the cf check-route command.

The following command checks whether a route with the hostname store and the domain cfapps. and the path products exists:

$ cf check-route store cfapps. --path /products
Checking for route...
OK
Route store.cfapps./products does exist

Map a Route to Your Application

For an app to receive requests to a route, developers must map the route to the app with the cf map-route command. If the route does not already exist, this command creates it.

Developers can create and reserve routes for later use by following the steps in the Manually Map a Route section. Or they can map routes to their app immediately as part of a push by following the steps in the Map a Route with Application Push section.

Note: Changes to route mappings are executed asynchronously. On startup, an application will be accessible at its route within a few seconds. Similarly, upon mapping a new route to a running app, the app will be accessible at this route within a few seconds of the CLI exiting successfully.

Manually Map a Route

Given the following routes and applications:

Route Application
store.cfapps./products products
store.cfapps./orders orders
store.cfapps. storefront
tcp.cfapps.:60000 tcp-app

The following commands map the above routes to their respective apps. Developers use hostname, domain, and path to uniquely identify a route to map their apps to.

$ cf map-route products cfapps. --hostname store --path products
$ cf map-route orders cfapps. --hostname store --path orders
$ cf map-route storefront cfapps. --hostname store
$ cf map-route tcp-app tcp.cfapps. --port 60000

The following command maps the wildcard route *.foo.cfapps. to the app myfallbackapp.

$ cf map-route myfallbackapp foo.cfapps. --hostname '*'

Map a Route with Application Push

Developers can map a route to their app with the cf push command.

If a domain or hostname is not specified, then a route will be created using the app name and the default shared domain (see Shared Domains). The following command pushes the app myapp, creating the route myapp.cfapps. from the default shared domain cfapps.. If the route has not already been created in another space this command also maps it to the app.

$ cf push myapp

To customize the route during push, specify the domain using the -d flag and the hostname with the --hostname flag. The following command creates the foo.private-domain.example.com route for myapp:

$ cf push myapp -d private-domain.example.com --hostname foo

To map a TCP route during push, specify a TCP domain and request a random port using --random-route. To specify a port, push the app without a route, then create and map the route manually by following the steps in the Create a TCP Route with a Port section.

$ cf push tcp-app -d tcp.cfapps. --random-route

Map a Route Using Application Manifest

Developers can map a route to their app with a manifest by editing the route attribute to specify the host, domain, port and/or path components of the route. For more information, see the Deploying with Application Manifests topic.

Map a Route to Multiple Apps

PWS allows multiple apps, or versions of the same app, to be mapped to the same route. This feature enables Blue-Green deployment. For more information see Using Blue-Green Deployment to Reduce Downtime and Risk.

Routing multiple apps to the same route may cause undesirable behavior in some situations by routing incoming requests randomly to one of the apps on the shared route.

See the Routing Conflict section of the Troubleshooting Application Deployment and Health topic for more information about troubleshooting this problem.

Unmap a Route

Developers can remove a route from an app using the cf unmap-route command. The route remains reserved for later use in the space where it was created until the route is deleted.

To unmap an HTTP route from an app, identify the route using the hostname, domain, and path:

$ cf unmap-route tcp-app private-domain.example.com --hostname myapp --path mypath

To unmap a TCP route from an app, identify the route using the domain and port:

$ cf unmap-route tcp-app tcp.cfapps. --port 60000

Delete a Route

Developers can delete a route from a space using the cf delete-route command.

To delete a HTTP route, identify the route using the hostname, domain, and path:

$ cf delete-route private-domain.example.com --hostname myapp --path mypath

To delete a TCP route, identify the route using the domain and port.

$ cf delete-route tcp.private-domain.example.com --port 60000

Routing Requests to a Specific App Instance

Users can route HTTP requests to a specific application instance using the header X-CF-APP-INSTANCE. The format of the header should be X-CF-APP-INSTANCE: APP_GUID:APP_INDEX.

APP_GUID is an internal identifier for your application. Use the cf APP-NAME --guid command to discover the APP_GUID for your application.

$ cf app myapp --guid

APP_INDEX, for example 1, 2, or 3, is an identifier for a particular app instance. Use the CLI command cf app APP-NAME to get statistics on each instance of a particular app.

$ cf app myapp

The following example shows a request made to instance 9 of an application with GUID 5cdc7595-2e9b-4f62-8d5a-a86b92f2df0e and mapped to route myapp.private-domain.example.com.

$ curl myapp.private-domain.example.com -H "X-Cf-App-Instance: 5cdc7595-2e9b-4f62-8d5a-a86b92f2df0e:9"

If the cf CLI cannot find the instance the format is incorrect, a 404 status code is returned.

Domains

Note: The term domain in this topic differs from its common use and is specific to Cloud Foundry. Likewise, shared domain and private domain refer to resources with specific meaning in Cloud Foundry. The use of domain name, root domain, and subdomain refers to DNS records.

Domains indicate to a developer that requests for any route created from the domain will be routed to PWS. This requires DNS to be configured out-of-band to resolve the domain name to the IP address of a load balancer configured to forward requests to the CF routers. For more information about configuring DNS, see the DNS for Domains section.

List Domains for an Org

When creating a route, developers will select from domains available to them. Use the cf domains command to view a list of available domains for the targeted org:

$ cf domains
Getting domains in org my-org as user@example.com... OK
name                     status   type
cfapps.        shared
tcp.cfapps.    shared   tcp
private-domain.example.com       owned

This example displays three available domains: a shared HTTP domain cfapps., a shared TCP domain tcp.cfapps., and a private domain private-domain.example.com. See Shared Domains and Private Domains.

HTTP vs. TCP Domains

HTTP domains indicate to a developer that only requests using the HTTP protocol will be routed to applications mapped to routes created from the domain. Routing for HTTP domains is layer 7 and offers features like custom hostnames, sticky sessions, and TLS termination.

TCP domains indicate to a developer that requests over any TCP protocol, including HTTP, will be routed to applications mapped to routes created from the domain. Routing for TCP domains is layer 4 and protocol agnostic, so many features available to HTTP routing are not available for TCP routing. TCP domains are defined as being associated with the TCP Router Group. The TCP Router Group defines the range of ports available to be reserved with TCP Routes. Currently, only Shared Domains can be TCP.

Note: By default, PWS only supports routing of HTTP requests to applications.

Shared Domains

Admins manage shared domains, which are available to users in all orgs of a PWS deployment. An admin can offer multiple shared domains to users. For example, an admin may offer developers the choice of creating routes for their apps from cfapps. and cf.some-company.com.

There is not technically a default shared domain. If a developer pushes an app without specifying a domain (see Map a Route with Application Push), a route will be created for it from the first shared domain created in the system. All other operations involving route require the domain be specified (see Routes).

Shared domains are HTTP by default, but can be configured to be TCP when associated with the TCP Router Group.

Create a Shared Domain

Admins can create an HTTP shared domain with the cf create-shared-domain command:

$ cf create-shared-domain cfapps.

To create a TCP shared domain, first discover the name of the TCP Router Group.

$ cf router-groups
Getting router groups as admin ...
name          type
default-tcp   tcp
Then create the shared domain using the --router-group option to associate the domain with the TCP router group.
$ cf create-shared-domain tcp.cfapps. --router-group default-tcp

Delete a Shared Domain

Admins can delete a shared domain from PWS with the cf delete-shared-domain command:

$ cf delete-shared-domain example.com

Private Domains

Org Managers can add private domains, or custom domains, and give members of the org permission to create routes for privately registered domain names. Private domains can be shared with other orgs, enabling users of those orgs to create routes from the domain.

Private domains can be HTTP or HTTPS only. TCP Routing is supported for Shared Domains only.

Create a Private Domain

Org Managers can create a private domain with the following command:

$ cf create-domain my-org private-domain.example.com

Org Managers can create a private domain for a subdomain with the following command:

$ cf create-domain my-org foo.private-domain.example.com

Sharing a Private Domain with One or More Orgs

Org Managers can grant or revoke access to a private domain to other orgs if they have permissions for these orgs with the following commands:

$ cf share-private-domain test-org private-domain.example.com

$ cf unshare-private-domain test-org private-domain.example.com

Delete a Private Domain

Org Managers can delete a domain from PWS with the cf delete-domain command:

$ cf delete-domain private-domain.example.com

Requirements for Parent and Child Domains

In the domain myapp.cfapps., cfapps. is the parent domain of subdomain myapp. Note the following requirements for domains:

  • You can only create a private domain that is parent to a private subdomain.
  • You can create a shared domain that is parent to either a shared or a private subdomain.

The domain foo.myapp.cfapps. is the child subdomain of myapp.cfapps.. Note the following requirements for subdomains:

  • You can create a private subdomain for a private parent domain only if the domains belong to the same org.
  • You can create a private subdomain for a shared parent domain.
  • You can only create a shared subdomain for a shared parent domain.
  • You cannot create a shared subdomain for a private parent domain.

DNS for Domains

To create customized access to your apps, you can map specific or wildcard custom domains to PWS by using your DNS provider.

Mapping Domains to Your Custom Domain

To associate a registered domain name with a domain on PWS, configure a CNAME record with your DNS provider, pointing at any shared domain offered in PWS.

Mapping a Single Domain to Your Custom Domain

To map a single domain to a custom domain to PWS, configure a CNAME record with your DNS provider.

The following table provides some example CNAME record mappings.

Record Set in Custom Domain Type Target in PWS
myapp.yourcustomdomain.com. CNAME myapp.cfapps.
www.yourcustomdomain.com. CNAME myapp.cfapps.

After you create the CNAME mapping, your DNS provider routes your custom domain to myapp.cfapps..

Note: Refer to your DNS provider documentation to determine whether the trailing . is required.

Mapping Multiple Subdomains to Your Custom Domain

Use a wildcard CNAME record to point all of the subdomains in your custom domain to cfapps..

Each separately configured subdomain has priority over the wildcard configuration.

The following table provides some example wildcard CNAME record mappings.

Record Set in Custom Domain Type Target in PWS
*.yourcustomdomain.com. CNAME *.cfapps.
*.yourcustomdomain.com. CNAME *.myapp.cfapps.

If you use a wildcard as the subdomain name, then your DNS provider can route from *.YOURCUSTOMDOMAIN to any of the following:

  • *.cfapps.
  • foo.myapp.cfapps.
  • bar.foo.myapp.cfapps.

Configuring DNS for Your Registered Root Domain

To use your root domain (for example, example.com) for apps on PWS you can either use custom DNS record types like ALIAS and ANAME, if your DNS provider offers them, or subdomain redirection.

Note: Root domains are also called zone apex domains.

If your DNS provider supports using an ALIAS or ANAME record, configure your root domain with your DNS provider to point at a shared domain in PWS.

Record Name Target Note
ALIAS or ANAME empty or @ private-domain.example.com. Refer to your DNS provider documentation to determine whether to use an empty or @ value for the Name entry.

If your DNS provider does not support ANAME or ALIAS records you can use subdomain redirection, also known as domain forwarding, to redirect requests for your root domain to a subdomain configured as a CNAME.

Note: If you use domain forwarding, SSL requests to the root domain may fail if the SSL certificate only matches the subdomain.

Configure the root domain to point at a subdomain such as www, and configure the subdomain as a CNAME record pointing at a shared domain in PWS.

Record Name Target Note
URL or Forward private-domain.example.com www.private-domain.example.com This method results in a 301 permanent redirect to the subdomain you configure.
CNAME www myapp.cfapps.
Was this helpful?
What can we do to improve?
View the source for this page in GitHub