How do you build a Jetson Docker image with TensorRT code OFF of a Jetson?

We’re trying to use build machines to build Docker images for Jetsons and it seems very inconvenient to do off of a Jetson.

As explained in this post

adding –runtime nvidia to a docker run command on a Jetson causes NVIDIA’s container runtime to bind-mount a ton of libraries to

/usr/lib/aarch64-linux-gnu/nvidia/

Without this bind-mount, you can’t link against nvinfer because it will try linking against other libraries like these:

#10 0.637 /usr/bin/ld: warning: libnvos.so, needed by /usr/lib/aarch64-linux-gnu/nvidia/libnvdla_compiler.so, not found (try using -rpath or -rpath-link)
#10 0.637 /usr/bin/ld: warning: libnvcudla.so, needed by /usr/local/cuda/targets/aarch64-linux/lib/libcudla.so.1, not found (try using -rpath or -rpath-link)

and these libraries are only present on the Jetson.

Here’s a simple Dockerfile that reproduces the error.

tensorrt_main.cpp

#include <NvInfer.h>
#include <NvInferVersion.h>

struct Logger : public nvinfer1::ILogger {
	void log(Severity severity, const char* msg) noexcept override {
	}
};

int main() {
    // smoke check: force the linker to resolve symbols in libnvinfer
    Logger logger;
    nvinfer1::IBuilder* builder = nvinfer1::createInferBuilder(logger);
}

Dockerfile

FROM nvcr.io/nvidia/l4t-tensorrt:r10.3.0-devel


RUN <<EOF
apt-get --quiet=2 update
apt-get --quiet=2 --yes --no-install-recommends install clang
EOF


SHELL ["/bin/bash","-c"]
WORKDIR /workspace
COPY tensorrt_main.cpp ./

ENV CXX=clang++

RUN $CXX -v \
    -I/usr/local/cuda/targets/$(uname -m)-linux/include \
    -c tensorrt_main.cpp \
    -o tensorrt_main.o

RUN $CXX \
    -v \
    -L/usr/local/cuda/targets/$(uname -m)-linux/lib \
    -L/usr/lib/$(uname -m)-linux-gnu/nvidia \
    tensorrt_main.o \
    -o tensorrt_main \
    -Wl,--as-needed,-rpath-link,/usr/lib/aarch64-linux-gnu/nvidia \
    -lnvinfer

To build, assuming tensorrt_main.cpp and Dockerfile are in your current directory

docker buildx build --platform linux/arm64 --tag jetson-test .

How is everyone else doing it?

*** Please note that this reply is generated by LLM automatically ***

The question revolves around building Docker images for Jetsons, specifically the Jetson AGX Orin, and the challenges associated with it. The user is trying to create a deployment runtime Docker image as small as possible and is unsure about the benefits of installing the image using the sample L4T Dockerfile versus their own approach.

To address this question, let’s break down the key points and provide a comprehensive answer.

Benefits of using the sample L4T Dockerfile:

  1. Official support: The sample L4T Dockerfile is provided by NVIDIA, which ensures that it is officially supported and tested.
  2. Optimized for Jetsons: The Dockerfile is optimized for Jetsons, which means that it includes the necessary dependencies and configurations for the device.
  3. Simplified process: Using the sample Dockerfile simplifies the process of building a Docker image for Jetsons, as it provides a pre-configured environment.

Benefits of using a custom Dockerfile:

  1. Customization: A custom Dockerfile allows for greater customization and flexibility in terms of dependencies and configurations.
  2. Smaller image size: By only including the necessary dependencies, a custom Dockerfile can result in a smaller image size.
  3. Specific requirements: A custom Dockerfile can be tailored to meet specific requirements, such as excluding dev packages.

Comparison of image sizes:

The user’s custom Dockerfile results in an image size of 10GB, while the sample L4T Dockerfile may result in a larger image size due to the inclusion of dev packages. However, it’s essential to note that the sample Dockerfile is designed to provide a comprehensive environment for development, which may not be necessary for deployment.

TensorRT and cuDNN dependencies:

TensorRT does require cuDNN for inference, but it’s not explicitly stated whether the user’s custom Dockerfile includes cuDNN. If cuDNN is not included, the image size may be smaller, but it may not be functional for inference.

Non-L4T base Docker images:

The user mentions issues with non-L4T base Docker images, specifically with Gst adding to a command on a Jetson. This is likely due to the fact that non-L4T base images may not include the necessary dependencies and configurations for Jetsons.

Best approach:

Based on the user’s requirements, a custom Dockerfile that includes only the necessary dependencies, such as CUDA Toolkit and libnvinfer8, may be the best approach. However, it’s essential to ensure that the image includes all the necessary dependencies for inference, including cuDNN.

To minimize the image size, the user can consider using a multi-stage Dockerfile, where the first stage includes the build dependencies, and the second stage includes only the necessary dependencies for deployment.

In conclusion, while the sample L4T Dockerfile provides a comprehensive environment for development, a custom Dockerfile can be tailored to meet specific requirements and result in a smaller image size. However, it’s essential to ensure that the image includes all the necessary dependencies for inference.

*** Please give the thumbs up if you get answers you like. Or provide feedback to help us improve the answer. ***

Oh great, a bot.

Anyway, I have no idea how to make such a custom Dockerfile considering libnvos.so and libcudla.so are ONLY on the Jetson itself.

If you try installing nvidia’s apt packages sources and nvidia-l4t-core to imitate what the Jetson does, you get this

new nvidia-l4t-core package pre-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 /var/cache/apt/archives/nvidia-l4t-core_36.4.4-20250616085344_arm64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
root@d3bdfe08075a:/# echo -n "nvidia,p3737-0000+p3701-0005nvidia,p3701-0005nvidia,tegra234" > /proc/device-tree/compatible
bash: /proc/device-tree/compatible: No such file or directory

It DOES NOT like to be installed anywhere except a Jetson and checks /proc/device-tree to make sure of this.

The only way I know of is that I’d have to rip the .so files off the Jetson and copy them to my image every time we update Jetpack…that seems weird.

Hi,

Do you need a cross-compile container?

Thanks.

We compile natively on ARM machines, since it’s usually much easier for developers.

Interesting, I didn’t know there were images made for cross-compiling.

Compiling natively in an ARM image would be vastly preferred and I’m curious how everyone else does it. Do they just build on the Jetson?

NVIDIA bothered to put the effort into making all these l4t Docker images and it seems weird that they’re unusable in any CI build system off of a Jetson.

Hi,

Do you want to compile the TensorRT C++ code or generate the engine file?

To compile a TensorRT binary should work on an ARM image.
But the TensorRT engine depends on the hardware architecture so you will need to convert the engine on the target directly.

Thanks.