Bind mounts - Amazon ECS

Bind mounts

With bind mounts, a file or directory on a host, such as AWS Fargate, is mounted into a container. Bind mounts are tied to the lifecycle of the container that uses them. After all of the containers that use a bind mount are stopped, such as when a task is stopped, the data is removed. For more information, see Using bind mounts in the Docker documentation.

The following are common use cases for bind mounts.

  • To provide an empty data volume to mount in one or more containers.

  • To expose a path and its contents from a Dockerfile to one or more containers.

Considerations when using bind mounts

When using bind mounts, consider the following.

  • For tasks that are hosted on AWS Fargate using platform version 1.4.0 or later (Linux) or 1.0.0 or later (Windows), by default they receive a minimum of 20 GiB of ephemeral storage for bind mounts. For Linux tasks, the total amount of ephemeral storage can be increased to a maximum of 200 GiB by specifying the ephemeralStorage object in your task definition.

  • To expose files from a Dockerfile to a data volume when a task is run, the Amazon ECS data plane looks for a VOLUME directive. If the absolute path that's specified in the VOLUME directive is the same as the containerPath that's specified in the task definition, the data in the VOLUME directive path is copied to the data volume. In the following Dockerfile example, a file that's named examplefile in the /var/log/exported directory is written to the host and then mounted inside the container.

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN mkdir -p /var/log/exported RUN touch /var/log/exported/examplefile VOLUME ["/var/log/exported"]

    By default, the volume permissions are set to 0755 and the owner as root. You can customize these permissions in the Dockerfile. The following example defines the owner of the directory as node.

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN yum install -y shadow-utils && yum clean all RUN useradd node RUN mkdir -p /var/log/exported && chown node:node /var/log/exported RUN touch /var/log/exported/examplefile USER node VOLUME ["/var/log/exported"]

Specifying a bind mount in your task definition

For Amazon ECS tasks that are hosted on Fargate, the following task definition JSON snippet shows the syntax for the volumes, mountPoints, and ephemeralStorage objects for a task definition.

{ "family": "", ... "containerDefinitions" : [ { "mountPoints" : [ { "containerPath" : "/path/to/mount_volume", "sourceVolume" : "string" } ], "name" : "string" } ], ... "volumes" : [ { "name" : "string" } ], "ephemeralStorage": { "sizeInGiB": integer } }

The following describes each task definition parameter in more detail.

name

Type: String

Required: No

The name of the volume. Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores are allowed. This name is referenced in the sourceVolume parameter of container definition mountPoints.

mountPoints

Type: Object Array

Required: No

The mount points for data volumes in your container.

This parameter maps to Volumes in the Create a container section of the Docker Remote API and the --volume option to docker run.

Windows containers can mount whole directories on the same drive as $env:ProgramData. Windows containers cannot mount directories on a different drive, and mount point cannot be across drives.

sourceVolume

Type: String

Required: Yes, when mountPoints are used

The name of the volume to mount.

containerPath

Type: String

Required: Yes, when mountPoints are used

The path on the container to mount the volume at.

readOnly

Type: Boolean

Required: No

If this value is true, the container has read-only access to the volume. If this value is false, then the container can write to the volume. The default value is false.

ephemeralStorage

Type: Object

Required: No

The amount of ephemeral storage to allocate for the task. This parameter is used to expand the total amount of ephemeral storage available, beyond the default amount, for tasks hosted on AWS Fargate using platform version 1.4.0 or later (Linux) or 1.0.0 or later (Windows).

You can use the Copilot CLI, CloudFormation, the AWS SDK or the CLI to specify ephemeral storage for a bind mount.

Bind mount examples

The following examples cover the most common use cases for using a bind mount for your containers.

To allocate an increased amount of ephemeral storage space for a Fargate task

For Amazon ECS tasks that are hosted on Fargate using platform version 1.4.0 or later (Linux) or 1.0.0 (Windows), you can allocate more than the default amount of ephemeral storage for the containers in your task to use. This example can be incorporated into the other examples to allocate more ephemeral storage for your Fargate tasks.

  • In the task definition, define an ephemeralStorage object. The sizeInGiB must be an integer between the values of 21 and 200 and is expressed in GiB.

    "ephemeralStorage": { "sizeInGiB": integer }

To provide an empty data volume for one or more containers

In some cases, you want to provide the containers in a task some scratch space. For example, you might have two database containers that need to access the same scratch file storage location during a task. This can be achieved using a bind mount.

  1. In the task definition volumes section, define a bind mount with the name database_scratch.

    "volumes": [ { "name": "database_scratch", } ]
  2. In the containerDefinitions section, create the database container definitions. This is so that they mount the volume.

    "containerDefinitions": [ { "name": "database1", "image": "my-repo/database", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "database_scratch", "containerPath": "/var/scratch" } ] }, { "name": "database2", "image": "my-repo/database", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "database_scratch", "containerPath": "/var/scratch" } ] } ]

To expose a path and its contents in a Dockerfile to a container

In this example, you have a Dockerfile that writes data that you want to mount inside a container.

  1. Create a Dockerfile. The following example uses the public Amazon Linux 2 container image and creates a file that's named examplefile in the /var/log/exported directory that we want to mount inside the container. The VOLUME directive should specify an absolute path.

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN mkdir -p /var/log/exported RUN touch /var/log/exported/examplefile VOLUME ["/var/log/exported"]

    By default, the volume permissions are set to 0755 and the owner as root. These permissions can be changed in the Dockerfile. In the following example, the owner of the /var/log/exported directory is set to node.

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN yum install -y shadow-utils && yum clean all RUN useradd node RUN mkdir -p /var/log/exported && chown node:node /var/log/exported RUN touch /var/log/exported/examplefile USER node VOLUME ["/var/log/exported"]
  2. In the task definition volumes section, define a volume with the name application_logs.

    "volumes": [ { "name": "application_logs", } ]
  3. In the containerDefinitions section, create the application container definitions. This is so they mount the storage. The containerPath value must match the absolute path that's specified in the VOLUME directive from the Dockerfile.

    "containerDefinitions": [ { "name": "application1", "image": "my-repo/application", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "application_logs", "containerPath": "/var/log/exported" } ] }, { "name": "application2", "image": "my-repo/application", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "application_logs", "containerPath": "/var/log/exported" } ] } ]