Using Docker Containers

SkyPilot can run a Docker container either as the runtime environment for your task, or as the task itself.

Using Docker Containers as Runtime Environment

When a container is used as the runtime environment, the SkyPilot task is executed inside the container.

This means all setup and run commands in the YAML file will be executed in the container, and any files created by the task will be stored inside the container. Any GPUs assigned to the task will be automatically mapped to your Docker container and all future tasks on the cluster will also execute in the container.

To use a Docker image as your runtime environment, set the image_id field in the resources section of your task YAML file to docker:<image_id>. For example, to use the ubuntu:20.04 image from Docker Hub:

resources:
  image_id: docker:ubuntu:20.04

setup: |
  # Will run inside container

run: |
  # Will run inside container

For Docker images hosted on private registries, you can provide the registry authentication details using task environment variables:

# ecr_private_docker.yaml
resources:
  image_id: docker:<your-user-id>.dkr.ecr.us-east-1.amazonaws.com/<your-private-image>:<tag>
  # the following shorthand is also supported:
  # image_id: docker:<your-private-image>:<tag>

envs:
  SKYPILOT_DOCKER_USERNAME: AWS
  # SKYPILOT_DOCKER_PASSWORD: <password>
  SKYPILOT_DOCKER_SERVER: <your-user-id>.dkr.ecr.us-east-1.amazonaws.com

We suggest to setting the SKYPILOT_DOCKER_PASSWORD environment variable through the CLI (see passing secrets):

$ export SKYPILOT_DOCKER_PASSWORD=$(aws ecr get-login-password --region us-east-1)
$ sky launch ecr_private_docker.yaml --env SKYPILOT_DOCKER_PASSWORD

Running Docker Containers as Tasks

As an alternative, SkyPilot can run docker containers as tasks. Docker runtime is configured and ready for use on the default VM image used by SkyPilot.

To run a container as a task, you can directly invoke the docker run command in the run section of your task.

For example, to run a GPU-accelerated container that prints the output of nvidia-smi:

resources:
  accelerators: V100:1

run: |
  docker run --rm --gpus all nvidia/cuda:11.6.2-base-ubuntu20.04 nvidia-smi

Building containers remotely

If you are running the container as a task, the container image can also be built remotely on the cluster in the setup phase of the task.

The echo_app example provides an example on how to do this:

file_mounts:
  /inputs: ./echo_app  # Input to application
  /echo_app: ./echo_app  # Contains the Dockerfile and build context
  /outputs:  # Output to be written directly to S3 bucket
    name: # Set unique bucket name here
    store: s3
    mode: MOUNT

setup: |
  # Build docker image. If pushed to a registry, can also do docker pull here
  docker build -t echo:v0 /echo_app

run: |
  docker run --rm \
  --volume="/inputs:/inputs:ro" \
  --volume="/outputs:/outputs:rw" \
  echo:v0 \
  /inputs/README.md /outputs/output.txt

In this example, the Dockerfile and build context are contained in ./echo_app. The setup phase of the task builds the image, and the run phase runs the container. The inputs to the app are copied to SkyPilot using file_mounts and mounted into the container using docker volume mounts (--volume flag). The output of the app produced at /outputs path in the container is also volume mounted to /outputs on the VM, which gets directly written to a S3 bucket through SkyPilot Storage mounting.

Our GitHub repository has more examples, including running Detectron2 in a Docker container via SkyPilot.