Cross Compilation of docker images between amd64 and arm64 architecture

Hi,
I created a docker image using the base image nvcr.io/nvidia/deepstream:6.3-triton-multiarch in Ubuntu 20.04, since it is multiarch it supports both amd64 and arm64 architecture (I confirmed it using command docker manifest inspect nvcr.io/nvidia/deepstream:6.3-triton-multiarch). On the base image, I built my project and installed its dependencies and did docker commit. It runs fine when I tested in another Ubuntu machine.
I have Nvidia Seeed reComputer J4012 with Jetson Orin NX board and I pulled the same docker image on Seed studio and when I run the docker image using the command docker run -it --rm --gpus all --name docker -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix my-docker-image:latest, it gives me warning: The requested image’s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested exec /opt/nvidia/deepstream/deepstream-6.3/entrypoint.sh: exec format error.
Please help.

Sorry for the long delay because a holiday.

Try the following command line. This seems to be a issue caused by the docker run parameter. Please refer to the documentation of l4t below

docker run -it --rm --network=host --runtime nvidia  -e DISPLAY=$DISPLAY -w /opt/nvidia/deepstream/deepstream-6.3 -v /tmp/.X11-unix/:/tmp/.X11-unix nvcr.io/nvidia/deepstream:6.3-triton-multiarch

No luck, it shows the same error, Also I don’t have deepstream installed on Nvidia Seed, I just set up the Seed based on the unboxing video Unboxing & Plug in reComputer J4012 - Powered by NVIDIA Jetson Orin NX. Deepstream is within the docker container I am trying to run.

This error seems to be caused by the incorrect format of the docker image. Did you build my-docker-image on x86?

You need to install qemu first

# Install qemu packages
sudo apt-get install qemu binfmt-support qemu-user-static

# Execute the registering scripts
docker run --rm --privileged dockerhub.nvidia.com/multiarch/qemu-user-static --reset -p yes

Then add --platform linux/aarch64 parameters to docker build

In addition, because the host and Docker image share BSP (including CUDA) on Jetson, you can only run DeepStream versions compatible with the host in Docker.

Please provide complete information as applicable to your setup.
• Hardware Platform (Jetson / GPU)
• DeepStream Version
• JetPack Version (valid for Jetson only)
• TensorRT Version
• NVIDIA GPU Driver Version (valid for GPU only)
• Issue Type( questions, new requirements, bugs)
• How to reproduce the issue ? (This is for bugs. Including which sample app is using, the configuration files content, the command line used and other details for reproducing)
• Requirement details( This is for new requirement. Including the module name-for which plugin or for which sample application, the function description)
• The pipeline being used

I need to know the JetPack Version you installed

Hardware Platform: NVIDIA Seeed reComputer J4012 (Jetson Orin NX)
Jetpack Version: 5.1.1 [L4T 35.3.1]
CUDA: 11.4.315
TensorRT: 8.5.2.2
Also please note instead of writing a dockerfile, I manually installed all dependencies and did docker commit on the base image nvcr.io/nvidia/deepstream:6.3-triton-multiarch to create my docker image, and I believe that is the root cause of the issue. docker commit doesn’t work for multiarch support since it only captures a snapshot for the current architecture. Please correct me if I am wrong.

This can also be achieved. After completing the steps above to install qemu, add the --platform arm64 parameter when docker run, and then docker commit, you can also get the aarch64 docker image.

However, I recommend building the docker image directly on Jetson

@junshengy Okay, I understand now we can use qemu to build aarch64 docker image on x86 machine..
But my intention is to create a docker image that should work on both x86 and aarch64 machine. For that objective I used multiarch base image nvcr.io/nvidia/deepstream:6.3-triton-multiarch that works on both arm64 and amd64, but when I install my project dependencies on this base image and did docker commit, I lost multiarch nature in the new image. I want this new image to run on both arm64 and amd64 architecture irrespective of where it is build on.

Multi-architecture docker images are just different layers pulled during docker pull. You cannot achieve this goal simply through docker commit. You need to tag the x86/aarch images with different tags and then use docker manifest push or docker buildx build

This is not a deepstream issue, please discuss in the docker community

@junshengy I was very confused by the idea of creating multiarch images and cross compilation. I tried building multiarch images using buildx tool, its like embedding 2 variants (amd64 and arm64) of docker image together and when I pull we will get corresponding docker image based on host machine architecture. Its not like I can work on one docker image on both x86_64 and arm. What I really want to achieve is I need to build binaries for arm64 on x86_64 so that jetson is only for deploying binaries. For that I installed qemu on x86_64 sudo apt install -y qemu binfmt-support qemu-user-static and build using docker buildx build --platform linux/arm64 -t my-image:arm64 -f Dockerfile . --load . I checked using docker run --rm --platform linux/arm64 my-image:arm64 uname -m and it returns aarch64 as output. Now when i run the docker image on x86_64 and try to run deepstream 6.3 sample programs, I am getting so many errors. I need to try building a simple helloworld program on ubuntu and try running the binaries on jetson.

This topic is not related to deepstream, please discuss it in the Docker community.

You can refer to the command line below. I use the internal gitlab hosted container registry and everything works as expected.

Save as Dockerfile.arm64

FROM arm64v8/busybox AS base

ENTRYPOINT [ "uname", "-a" ]

Save as Dockerfile

FROM busybox AS base

ENTRYPOINT [ "uname", "-a" ]

Save as build.sh

#!/usr/bin/env bash

set -e

docker build --platform linux/amd64 -t xxx:xxx/amd64 -f Dockerfile .
docker push xxx:xxx/amd64

docker build --platform linux/arm64 -t xxx:xxx/arm64 -f Dockerfile.arm64 .
docker push xxx:xxx/arm64

docker manifest create \
   xxx:xxx/multiarch \
    --amend xxx:xxx/amd64 \
    --amend xxx:xxx/arm64

docker manifest push xxx:xxx/multiarch 

Run the build.sh script, build and publish the multiarch image to gitlab.

run on x64

docker run --rm xxx:xxx/multiarch

# Linux 14941986250b 6.8.0-60-generic #63~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 22 19:00:15 UTC 2 x86_64 GNU/Linux

run on Jetson

docker run --rm xxx:xxx/multiarch

# Linux 023bace1850e 5.15.148-tegra #1 SMP PREEMPT Tue Jan 7 17:14:38 PST 2025 aarch64 GNU/Linux

There is no update from you for a period, assuming this is not an issue anymore. Hence we are closing this topic. If need further support, please open a new one. Thanks

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.