Using Docker in Cloud Foundry

Page last updated:

This topic provides information about how Docker works in Cloud Foundry and describes how to push an application with a Docker image. For information about Diego, see the Diego Architecture topic.

In addition to the default Linux environment provided by Cloud Foundry, operators can specify a Docker image that provides the file system used by the container. When pushing an app, you can specify the location of the Docker image you want to use.

A Docker image consists of a collection of layers. Each layer consists of one or both of the following:

  • Raw bits to download and mount. These bits form the file system.
  • Metadata that describes commands, users, and environment for the layer. This metadata includes the ENTRYPOINT and CMD directives, and is specified in the Dockerfile.

How Garden-runC Creates Containers

Diego currently uses Garden-runC to construct Linux containers. Earlier versions of Diego used Garden-Linux. For more information, see the Garden topic.

Both Docker and Garden-runC use libraries from the Open Container Initiative (OCI) to build Linux containers. After creation, these containers use name space isolation, or namespaces, and control groups, or cgroups, to isolate processes in containers and limit resource usage. These are common kernel resource isolation features used by all Linux containers.

Before Garden-runC creates a Linux container, it creates a file system that is mounted as the root file system of the container. Garden-runC supports mounting Docker images as the root file systems for the containers it creates.

When creating a container, both Docker and Garden-runC perform the following actions:

  • Fetch and cache the individual layers associated with a Docker image
  • Combine and mount the layers as the root file system

These actions produce a container whose contents exactly match the contents of the associated Docker image.

How Diego Runs and Monitors Processes

After Garden-runC creates a container, Diego runs and monitors the processes inside of it.

To determine which processes to run, the Cloud Controller fetches and stores the metadata associated with the Docker image. The Cloud Controller uses this metadata to perform the following actions:

  • Runs the start command as the user specified in the Docker image
  • Instructs Diego and the Gorouter to route traffic to the lowest-numbered port exposed in the Docker image

Note: When launching an application on Diego, the Cloud Controller honors any user-specified overrides such as a custom start command or custom environment variables.

Docker Security Concerns in a Multi-Tenant Environment

The attack surface area for a Docker-based container running on Diego remains somewhat higher than that of a buildpack application because Docker allows users to fully specify the contents of their root file systems. A buildpack application runs on a trusted root filesystem.

Garden-runC provides features that allow the platform to run Docker images more securely in a multi-tenant context. In particular, Cloud Foundry uses the user-namespacing feature found on modern Linux kernels to ensure that users cannot gain escalated privileges on the host even if they escalate privileges within a container.

The Cloud Controller always runs Docker containers on Diego with user namespaces enabled. This security restriction prevents certain features, such as the ability to mount FuseFS devices, from working in Docker containers. Docker applications can use fuse mounts through volume services, but they cannot directly mount fuse devices from within the container.

To mitigate security concerns, Cloud Foundry recommends that you run only trusted Docker containers on the platform. By default, the Cloud Controller does not allow Docker-based applications to run on the platform.

To allow Docker-based applications to run, a Cloud Controller administrator can enable the diego_docker feature flag with the following command:

$ cf enable-feature-flag diego_docker

To disallow Docker-based applications, a Cloud Controller administrator can run the following command:

$ cf disable-feature-flag diego_docker

Note: Disabling the diego_docker feature flag stops all Docker-based apps in your deployment within a few convergence cycles, on the order of a minute.

Push a Docker Image

Follow these instructions to deploy updated or new Docker images using the Cloud Foundry Command Line Interface (cf CLI).

When pushing an app, you specify either a Docker image on Docker Hub or the URI to a Docker registry.

Also, when using a Docker image with Cloud Foundry, you must use a registry that does the following:

Push a Docker Image Using Docker Hub

To deploy a Docker image using Docker Hub, run the following command:

$ cf push APP-NAME --docker-image REPO/IMAGE

Replace the following values in the command above:

  • APP-NAME: the name of the app being pushed
  • REPO: the name of the repository where the image is stored
  • IMAGE: the name of an image from Docker Hub

For example, the following command pushes the my-image image from Docker Hub to a Cloud Foundry app:

$ cf push my-app --docker-image cloudfoundry/my-image

Push a Docker Image from Another Registry

As an alternative to Docker Hub, you can use any Docker image registry that presents a valid certificate for HTTPS traffic.

To deploy a Docker image using a specified Docker registry, run the following command:

$ cf push APP-NAME --docker-image MY-PRIVATE-REGISTRY.DOMAIN:PORT/REPO/IMAGE:TAG

Replace the following values in the command above:

  • APP-NAME: the name of the app being pushed
  • MY-PRIVATE-REGISTRY.DOMAIN: the path to the Docker registry
  • PORT: the port where the registry serves traffic
  • REPO: the name of the repository where the image is stored
  • IMAGE: the name of the image being pushed
  • TAG: the tag or version for the image

For example:

$ cf push my-app --docker-image internal-registry.example.com:5000/my-repo/my-image:v2

Push a Private Docker Image

Most Docker registries support authentication mechanisms in order to control access to Docker images.

To deploy a Private Docker image, run the following command:

$ cf push APP-NAME --docker-image REPO/IMAGE:TAG --docker-username USER

Replace the following values in the command above:

  • APP-NAME: the name of the app being pushed
  • REPO: the name of the repository where the image is stored
  • IMAGE: the name of the image being pushed
  • USER: the username that should be used for the authentication with the registry
  • TAG: the tag or version for the image

A password for USER must also be provided by specifying the CF_DOCKER_PASSWORD environment variable. For example:

$ export CF_DOCKER_PASSWORD=yourpassword

To deploy a private Docker image using a specified Docker registry, run the following command:

$ cf push APP-NAME --docker-image MY-PRIVATE-REGISTRY.DOMAIN:PORT/REPO/IMAGE:TAG --docker-username USER

See the previous section for replacing MY-PRIVATE-REGISTRY.DOMAIN and PORT with the appropriate values.

Docker Volume Support

Diego supports Docker volumes. For more information about enabling volume support, see the Using an External File System (Volume Services) topic. For information about the limitations of NFS volumes, see the NFS Bosh Volume Release.

Create a pull request or raise an issue on the source for this page in GitHub