Skip to main content

Overview

Containers are lightweight, isolated environments that package everything needed to run an application — code, dependencies, and system libraries — so it behaves consistently across platforms. Advantages of containerization include:
  • Consistency: Containers provide a consistent environment across multiple platforms and operating systems. Developers can create images that transform into containers when deployed, ensuring uniformity regardless of the underlying infrastructure.
  • Automation: Containerization supports automated tasks. Developers can schedule actions without manual intervention, reducing repetitive work.
  • Stability: Containers are based on Linux, with the Linux kernel present in every container. This stability extends to systems and devices, including when containers run on macOS or Windows.
  • Space efficiency: Unlike traditional virtual machines, which consume significant server space and memory, containers include only application code and dependencies. They can run entirely in the cloud and minimize resource requirements.
Container architecture overview

IMSDK in Docker

This container targets Ubuntu, and QLI 2.x and later. QLI 1.x is not supported.
IMSDK in a Docker container means the full Qualcomm multimedia and AI software stack is delivered as containerized environments instead of being manually installed directly on a host or target system. In practice, a build container compiles and assembles all required components, including cross-compiled artifacts for Qualcomm ARM64 targets. The build then produces a deploy container that contains only the runtime pieces needed on the device. Key benefits of this approach:
  • Reproducible builds: Use the same toolchain, package versions, and scripts across developers and CI. Reduces “works on my machine” failures.
  • Build and runtime separation: Use a heavy build image to compile artifacts and a lean deploy image that contains only runtime essentials.
  • Efficient cross-compilation: Build on the host and target ARM64 Qualcomm devices reliably, faster than compiling directly on the target.
  • Secure runtime posture: Run as a non-root user by default, avoid broad privileged-container dependencies, and use CDI-based explicit hardware passthrough for GPU, camera, and media devices.
  • Operational consistency: Use versioned images that are testable, promotable, and rollback-friendly, with a predictable deployment flow using environment and CDI configuration on the target.

Features

  • Debian (Trixie) base: Built on Debian Trixie for a streamlined and lightweight foundation.
  • No platform dependencies: Entirely self-sufficient — no eSDK or host platform content required to build or deploy.
  • Self-contained dependencies: All necessary dependencies are installed directly inside the container, minimizing host-container compatibility issues and simplifying deployment on edge devices.
  • GStreamer 1.26: Includes GStreamer 1.26 with the latest gst-qti-oss-patches for optimized performance on Qualcomm platforms.
  • Broad target support: Validated across QLI 2.x, Ubuntu Server, and Ubuntu Desktop. Supports QCS615, QCS6490, IQ8, and IQ9.

Versions

Architecture

The following diagram explains the build and deployment flow of the IMSDK Docker image.
IMSDK Docker build and deployment flow
  • The host machine runs a development container that compiles all IMSDK sources and dependencies into Debian artifacts.
  • The generated artifacts are transferred to a Debian-based deploy container with CDI-managed hardware access that runs on the Qualcomm device.

Quick Start Guide

Before getting started, ensure the device is set up by following the Installation guide.
QIMSDK Docker is not supported on SELinux-enabled QLI builds.
Camera is not supported in the container.

Download configuration files

Before setting up the device, download the CDI and environment files for the target chipset and OS. The CDI JSON file provides platform-specific device mountings; the environment file sets the required variables inside the container. Select your chipset to download the corresponding files:

Set up and run on the device

1

SSH into the device

2

Create required directories

3

Copy the downloaded configuration files to the device

An additional step is required for Talos (qcs615) to configure the video node, as it uses an upstream video driver. This upstream driver can assign any device node between /dev/video0 and /dev/video28.Run the following command to list the video devices:
Example:
Identify the relevant video device nodes and add them to the cdi.json file that has been deployed to the target system before creating the container.
4

Pull the container image

Tag the image locally:
5

Run the container

After the container is running, execute a new terminal process in it:
Once inside the container, refer to the Examples section to run sample AI pipelines, multimedia pipelines, GStreamer C/C++ AI applications, or GStreamer C/C++ multimedia applications.
Gstreamer Python sample applications are not supported in this QIMSDK container.

Build an IMSDK container

All steps in this section are performed on a Ubuntu 22.04 or 24.04 machine which can be x86 or ARM64.

Prerequisites

Install prerequisite packages on the host (one time only).
Do not install yq via snap. If it was installed via snap, remove it and reinstall using the commands above:
Increase the maximum user watches and instances on the host to prevent this error during development:
Add these lines to /etc/sysctl.conf:
Save the file and reboot the host system.
To build Docker image files, the host system requires at least 64 GB of RAM and a swap image of at least half the available RAM plus a small reserve.For example, with 64 GB of RAM, the recommended swap size is at least 32 GB. With an 8 GB reserve, total RAM + swap + reserved memory is 104 GB.Check whether swap is enabled:
If swap is missing or too small, create a new swap file:
Edit /etc/default/grub and set:
Update GRUB:
Edit /etc/fstab and add this line at the end of the file:
Save and close all opened system files, then reboot the host system.After rebooting, verify the swap image matches the expected size:
Docker must be configured on the host system once before building images.
Remove old Docker Desktop versions if present:
Install repository dependencies:
Create the Docker keyring directory:
Add the Docker GPG key:
Add the Docker repository:
Add the user to the Docker group to run Docker commands without sudo:
Until the host is rebooted, run newgrp docker in every newly opened terminal.
Tabs, unexpected spaces, and other invisible whitespace characters can break JSON configuration files and may cause a docker.service failed to start error.
Add the registry mirror configuration to /etc/docker/daemon.json:
Restart Docker:
If network downloads require a proxy, add the proxy configuration to the Docker daemon.
Tabs, unexpected spaces, and other invisible whitespace characters can break JSON configuration files and may cause a docker.service failed to start error.
Add the proxy configuration to /etc/docker/daemon.json:
Restart Docker:
Set proxy environment variables before invoking Docker build commands:
This ensures that both the Docker daemon and build processes use the same proxy settings as the host system.
Until the host is rebooted, run newgrp docker in every newly opened terminal.
Run the Docker hello-world container:
If the build image script fails with a No space left on device error, move the Docker directory to /local/mnt.
All containers must be restarted after moving the Docker directory because the Docker service is stopped during this procedure.
Stop Docker:
Verify that no Docker process is running:
Check the Docker directory structure:
Back up the current Docker directory:
Move the Docker directory to the new partition:
Create a symlink to the Docker directory in the new partition:
Verify that the Docker directory structure is unchanged:
Start Docker:
List container names:
Start a listed container:
Check that there are no active cgroup CPU and memory utilization restrictions on the host. The Docker service cgroup memory configuration entries should have max set as the value.
If the host system has 64 GB RAM or less, tune system VM page swap and dentry and inode cache reclaim behavior.vm.swappinessHigher values cause more aggressive application memory page swapping; lower values favor keeping pages in memory longer. The default is usually 60 on recent Ubuntu and Debian versions, which may not fit the Docker build environment on systems with low available RAM. A value of 10 is recommended.vm.vfs_cache_pressureIntermittent high VFS pressure can result from creating many small temporary files during package installation, causing the OS to prematurely swap memory pages associated with cached dentries and inodes. The default is usually 100. Setting it to 400 relaxes cache management by freeing cached pages earlier, reducing the chance of running out of memory during high multi-threaded load.vm.min_free_kbytesIn heavy multi-stage Docker builds with many buildx threads, the host OS can exhaust available RAM quickly. The mandatory VM free memory watermark is controlled by vm.min_free_kbytes. Too low risks deadlocks under load; too high causes premature OOM kills. A value of 262144 KB better balances free memory under excessive load.Edit /etc/sysctl.conf and add:

Build steps

1

Fetch the source code

Run the following commands on the host machine:
2

Build the container

Build qimsdk_deploy_arm64, which contains the minimal set of runtime binaries needed to execute GStreamer use cases:
For example:
If QIMSDK_ARG_QNP_VERSION is not provided, the QNN and SNPE plugins are disabled in the image.
See qimsdk-debian/README.md for more information about the Docker image composition and workflow.
3

Save the image

Save the built image as a tar file:
4

Copy and load the image on the device

Copy the tar file to the device:
Load the image on the device:
On a QLI device $HOME is /root; on a Ubuntu device it is /home/ubuntu.
5

Run the container on the device

With the image copied to the device, follow the Set up and run on the device steps to configure CDI and start the container.

Install additional packages inside the container

Use this procedure to install packages into an already running qimsdk-debian deploy container. The container must have been started with the --net host option. The following steps use Python as an example.
1

Execute a shell in the container as root

2

Install apt packages

In the root shell, install the required packages:
3

Install pip packages

Create a Python virtual environment and install the required pip packages:
4

Activate the virtual environment automatically (optional)

Add the virtual environment activation to shell startup files to avoid sourcing it manually in every new shell:
After setup is complete, Python examples can be run from each new shell executed as the qimsdk user:
If automatic activation was not configured, run this command in every new shell executed as the qimsdk user inside the container:

Debugging

The following techniques apply to the QIMSDK container running on the Qualcomm device.

Check container logs

1

Stream live logs

2

Print the last 100 lines and follow

Inspect container state

1

List all containers and their status

2

Inspect container metadata

Inspect detailed container metadata including environment variables, mounts, and network settings:

Restart a container

1

Stop the container

2

Start the container