# Provisioning "Jetson Platform Services" to Nvidia Jetson devices

**URL:** https://hub.mender.io/t/provisioning-jetson-platform-services-to-nvidia-jetson-devices/6629
**Category:** Debian family
**Tags:** nvidia
**Created:** [March 15, 2024, 6:14am UTC](https://hub.mender.io/t/provisioning-jetson-platform-services-to-nvidia-jetson-devices/6629 "2024-03-15T06:14:33Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![lramirez](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/lramirez/32/1195_2.png) [@lramirez](https://hub.mender.io/u/lramirez)
#### Post date: [March 15, 2024, 6:14am UTC](https://hub.mender.io/t/provisioning-jetson-platform-services-to-nvidia-jetson-devices/6629/1 "2024-03-15T06:14:33Z")

</div>

## 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](https://docs.nvidia.com/jetson/jetpack/install-setup/index.html) based on your board.

### Install Mender

Install Mender in your Jetson board by following [Mender’s docs instructions](https://docs.mender.io/client-installation/install-with-debian-package).

Also, install `mender-artifact` in your workstation by following [this guide](https://docs.mender.io/downloads#mender-artifact).

## 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:

```bash
#!/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](https://hub.mender.io/t/how-to-install-a-new-update-module/6630).

### 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.

```bash
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](https://docs.nvidia.com/moj/nvstreamer/moj-nvstreamer.html#uploading-videos-to-nvstreamer) and this one to [import that video stream into VST](https://docs.nvidia.com/moj/nvstreamer/moj-nvstreamer.html#adding-rtsp-stream-to-vst).
