Deploying a ZED Application with Docker

We recommend the above workflow for building and deploying your applications with Docker. In this workflow your source code and Dockerfiles are present on your local device (host machine). The image is built from the Dockerfile on the host and is pushed on a Docker registry that makes it accessible from a remote device (target machine). On the target machine the Docker image is pulled from the registry and is run in a Docker container. In the following we provide additional details for each step.

Note that if the target machine is not running on the same architecture (x86_64 or aarch64) as the host machine, an emulation step will be required. Details regarding emulation are available here.

Build a Docker Image on the Host

To build a Docker image on the host machine you will need to:

  • Write a Dockerfile for your application
  • Run the docker build command

Write the Dockerfile

Docker will execute the instructions present in the Dockerfile to build our image. As an example we assume that a C++ application using the ZED SDK is built into a Docker Image to be deployed on several target machines. The application will run with the ZED SDK 2.8 and CUDA 10.0 on Ubuntu 18.04. The application is composed of a src folder, an include folder, a CMakeLists.txt and a Dockerfile that should look as follow:

# Use the SDK 2.8 CUDA 10.0 Ubuntu 18.04 base image
FROM stereolabs/zed:2.8-devel-cuda10.0-ubuntu18.04

# Setup your application in /home/user/app_name
WORKDIR /path/to/app

COPY CMakeLists.txt .
COPY src src
COPY include include

RUN mkdir /path/to/app/build && cd /path/to/app/build && \
    cmake .. && make

CMD ["./build/app_name"]
  • FROM: In this Dockerfile we start from an already built image provided by Stereolabs. This image contains everything required to setup the ZED SDK 2.8 with CUDA 10.0 on Ubuntu 18.0. Therefore the only thing to add in the Dockerfile are the different steps to build the custom application.

  • RUN: Next, we have to run some commands that will copy the sources and build the application. It’s important to note that this process only happens once, at the image build process. At runtime, none of this will be executed again.

  • CMD: Finally we specify what the image, should do. In this case it will run the application app_name that is present in the build folder.

For additionnal information on Dockerfiles, please refer to this documentation.

Build the Docker Image

To build an image on the host machine, go to the folder with the version of your application:

$cd path/to/app

Then run the build command to create the image:

$docker build -t {custom_image}:{custom_tag} .

In our case, the images are built automatically by a Gitlab CI job.

Once built this image can be pushed to a Docker registry. See the next section for more details on how to use Docker registries.

Push an Image to Docker Hub

Docker Hub is a public Docker registry that stores Docker images and that anyone can use. Docker is configured to look for images on Docker Hub by default.

When running the following command:

$docker push {user}/{custom_image}:{custom_tag}

Docker will push the image called {custom_image} to the Docker Hub of user {user} with the tag {custom_tag}.

Once pushed, the images are accessible from any other device and can be pulled from the Docker Hub in order to be run on a target machine.

Pull an Image from Docker Hub

To access any image available on Docker Hub you will need to pull it on the target machine from Docker Hub. To pull an image, use the docker pull or docker run commands.

When running the following command:

$docker pull {user}/{custom_image}:{custom_tag}

Docker will check if there is an image called {custom_image} pushed by the user named {user} on Dockerhub, and a version of it with the tag {custom_tag}. If the image exists it is pulled on the machine.

Run a Docker Image on the Target

Once the image is pulled on the target machine, use the following command to run it in a Docker container:

$docker run --privileged --runtime nvidia --rm {user}/{custom_image}:{custom_tag}

The --privileged option grants permission to pass through all the devices to get the Docker container. There is some security risk, but we do this because specifying the exact device to grant permissions to is very complicated given the direct, low-level connection required for the ZED.

Note that if the image has not been pulled previously, docker run will pull it from the registry.

Use a Custom Registry

Docker Hub provides a public registry accessible by anyone. However you can define your own registry and push your images there. If you use a custom registry (other than Docker Hub), you will have to specify the URL of the registry as follow:

$docker push {repo_url}/{user}/{custom_image}:{custom_tag}
$docker pull {repo_url}/{user}/{custom_image}:{custom_tag}

As an example, NVIDIA uses its own custom registry that is accessible as follow:

$docker pull nvcr.io/nvidia/pytorch:19.10-py3

In this example Docker will check if there’s an image called pytorch pushed by a user named nvidia on nvcr.io, and a version of it with the tag 19.10-py3.

To set up your own Docker registry, please refer ot this documentation.