Pre-requisites
Hardware
- Jetson Orin AGX devkit or
- Jetson Orin NX 16GB or 8GB devkit (self built) with 128GB(min) NVMe drive or
- Jetson Orin Nano 8GB devkit with 128GB(min) NVMe drive or
- Partner (ODM) device with one of above
This tutorial was tested on the Nvidia Jetson Orin AGX devkit
Flash your Jetson
It is required to install at least the BSP included in the JetPack 6.0 GA or newer.
Follow the official Nvidia documentation based on your board.
Install Mender
Install Mender in your Jetson board by following Mender’s docs instructions.
Also, install mender-artifact
in your workstation by following this guide.
Using Mender to deploy Jetson Platform Services (and using a demo app)
Creating the Mender Update Module
Create a file named jps-provision-mender-module
with the following content:
#!/bin/bash
set -e
STATE="$1"
FILES="$2"
WORKDIR="/opt/workdir"
VERSION="1.1.0"
case "$STATE" in
ArtifactInstall)
# Installing DEB packages
apt-get -qq update
apt-get -qq -y install nvidia-jetson-services
# Creating the WORKDIR, you can modify it above
mkdir -p $WORKDIR
# Downloading the resources from NGC
wget -P $WORKDIR --quiet -O reference-workflow-and-resources_$VERSION.zip --content-disposition https://api.ngc.nvidia.com/v2/resources/nvidia/jps/reference-workflow-and-resources/versions/$VERSION/zip
unzip $WORKDIR/reference-workflow-and-resources_$VERSION.zip -d $WORKDIR
# Set max power and clock speed
jetson_clocks
nvpmodel -m 0
# Maximize number of video streams processed by the system (for AI NVR)
echo "Maximize number of video streams processed by the system (for AI NVR)" 1>&2
sysctl -w net.core.rmem_default=2129920
sysctl -w net.core.rmem_max=10000000
# Setup VST Application
echo "Setup VST" 1>&2
tar -xvf $WORKDIR/ai_nvr-$VERSION.tar.gz -C $WORKDIR
cp $WORKDIR/ai_nvr/config/ai-nvr-nginx.conf /opt/nvidia/jetson/services/ingress/config/
cd $WORKDIR/ai_nvr
# Uncomment just one line based on your board:
# Orin AGX (default in this example)
docker compose -f compose_agx.yaml pull
# Orin NX16
#docker compose -f compose_nx16.yaml pull
# Orin NX8
#docker compose -f compose_nx8.yaml pull
# Orin Nano
#docker compose -f compose_nano.yaml pull
# Increase the OS socket buffer sizes (for NVStreamer)
echo "Increase the OS socket buffer sizes (for the Streamer)" 1>&2
sysctl -w net.core.wmem_max=2000000
sysctl -w net.core.rmem_max=2000000
# Setup NVStreamer
echo "Setup NVStreamer" 1>&2
tar -xvf $WORKDIR/nvstreamer-$VERSION.tar.gz -C $WORKDIR
# Start NVStreamer after reboot
cd $WORKDIR/nvstreamer
echo "Launch NVStreamer" 1>&2
docker compose -f compose_nvstreamer.yaml pull
;;
NeedsArtifactReboot)
echo "Automatic"
;;
ArtifactVerifyReboot)
# Setup and start Services
echo "Launch jetson's redis and ingress" 1>&2
systemctl start jetson-redis
systemctl start jetson-ingress
systemctl start jetson-vst
# Start NVStreamer after reboot
cd $WORKDIR/nvstreamer
echo "Launch NVStreamer" 1>&2
docker compose -f compose_nvstreamer.yaml up -d
# Start NVStreamer after reboot
cd $WORKDIR/ai_nvr
echo "Launch VST" 1>&2
# Uncomment just one line based on your board:
# Orin AGX (default in this example)
docker compose -f compose_agx.yaml up -d
# Orin NX16
#docker compose -f compose_nx16.yaml up -d
# Orin NX8
#docker compose -f compose_nx8.yaml up -d
# Orin Nano
#docker compose -f compose_nano.yaml up -d
;;
ArtifactCommit)
# Getting the IP Address
echo "Getting the IP address for outputs" 1>&2
ip_address=$(hostname -I | awk '{print $1}')
echo "IP Address: ${ip_address}" 1>&2
echo "Please open a browser in $ip_address:30080/vst for the VST application" 1>&2
echo "Please open a browser in $ip_address:31000 for the Streamer" 1>&2
echo "Ready, continue with Nvidia's tutorial to connect both apps" 1>&2
;;
SupportsRollback)
echo "Yes"
;;
ArtifactRollback)
echo "Removing nvidia-jetson-services package if installed" 1>&2
if [ $(dpkg-query -W -f='${Status}' nvidia-jetson-services 2>/dev/null | grep -c "ok installed") -eq 1 ];
then
apt purge nvidia-jetson-services;
fi
if [ -d $WORKDIR/nvstreamer ]; then
cd $WORKDIR/nvstreamer
docker compose -f compose_nvstreamer.yaml down --remove-orphans
fi
if [ -d $WORKDIR/ai_nvr ]; then
cd $WORKDIR/ai_nvr
# Uncomment just one line based on your board:
# Orin AGX (default in this example)
docker compose -f compose_agx.yaml down --remove-orphans
# Orin NX16
#docker compose -f compose_nx16.yaml down --remove-orphans
# Orin NX8
#docker compose -f compose_nx8.yaml down --remove-orphans
# Orin Nano
#docker compose -f compose_nano.yaml down --remove-orphans
fi
;;
Cleanup)
rm -rf $WORKDIR
;;
esac
exit 0
Install the Update Module
Copy the Update Module from above to your Jetson by following this guide.
Create a Mender Artifact
Replace the device-type
per the one set in the mender setup
process on the Jetson during the “Install Mender” part above. Ideally follow Nvidia’s standards, for example, jetson-agx-orin-devkit
for the Jetson AGX Orin DevKit.
Feel free to change the artifact-name
as this is how this artifact will be named in the Mender ecosystem.
The type
must match the name of the Update Module. In our example, we named it as jps-provision-mender-module
.
Notice it will download the required files from NGC.
mender-artifact write module-image \
--artifact-name "jps-installation" \
--output-path "jps-installation.mender" \
--device-type "jetson-agx-orin-devkit" \
--type "jps-provision-mender-module"
This will generate a Mender’s artifact named jps-installation.mender
that we can upload into our Mender Server and deploy into multiple Jetson devices from our fleet.
Verify your installation
After this artifact is deployed into a Jetson board, you should be able to open in your workstation’s browser the two webapps we installed: NV Streamer (in port 31000) and VST (in port 30080) and you should be able to follow this Nvidia’s tutorial for uploading a video into the NV Streamer and this one to import that video stream into VST.