Headless Mode on NVIDIA Jetson AGX Orin 64GB with JetPack 7.2 A developer documented a method to enable fully headless operation on the NVIDIA Jetson AGX Orin 64GB Developer Kit running JetPack 7.2. The guide uses NoMachine for remote GUI access with XFCE4 instead of GNOME, which fails due to DRI3/GPU acceleration requirements. Steps include setting a static IP, disabling network wait services, and configuring SSH for remote access. Tags: jetson jetpack-7.2 headless nomachine ubuntu-24.04 embedded-ai edge-ai This guide walks through enabling fully headless operation on the NVIDIA Jetson AGX Orin Developer Kit running JetPack 7.2. After completing these steps, the device boots without any display, keyboard, or mouse — accessible entirely via SSH for terminal use and NoMachine for full GUI access. Why NoMachine only? JetPack 7.2 ships GNOME 46 on Ubuntu 24.04. GNOME 46 requires DRI3/GPU acceleration to render its compositor Mutter . NoMachine's virtual display does not expose DRI3, causing gnome-shell to start but render nothing — only a black screen or bare wallpaper. XFCE4 has no compositor dependency, works perfectly in virtual displays, and is the stable choice for remote GUI access on this platform. | Component | Value | |---|---| | Hardware | NVIDIA Jetson AGX Orin Developer Kit 64GB | | JetPack | 7.2-b187 | | L4T | r39.2 Jetson Linux 39.2 | | OS | Ubuntu 24.04.4 LTS | | Kernel | 6.8.12-tegra | | CUDA | 13.2.1 | | Python | 3.12.3 | | NoMachine | 9.7.3 | | Remote host | Windows 11 same LAN via Ethernet | 192.168.1.100 as example Connect a monitor and open a terminal Ctrl+Alt+T . Update package lists and upgrade installed packages DO NOT run dist-upgrade on Jetson — it breaks JetPack components sudo apt update && sudo apt upgrade -y sudo apt autoremove -y sudo apt install -y \ net-tools curl wget htop tmux tree \ git nano vim \ build-essential \ python3-pip python3-venv python3-dev pipx \ software-properties-common \ apt-transport-https ca-certificates gnupg \ cmake ninja-build libopenblas-dev Install jtop , the Jetson-specific system monitor: Ubuntu 24.04 requires pipx for global Python tools pipx install jetson-stats pipx ensurepath source ~/.bashrc sudo systemctl restart jtop 2 /dev/null || true jtop --version sudo hostnamectl set-hostname jetson-orin Update /etc/hosts to match sudo nano /etc/hosts Find the line with 127.0.1.1 and change it to: 127.0.1.1 jetson-orin A static IP is required so SSH and NoMachine connections never break after reboots. Critical:The connection.permissions "" parameter makes the network connection available at boot without requiring a user graphical login. Without this, the Ethernet interface will not come up in headless mode and SSH will be unreachable. Find your Ethernet connection name nmcli connection show nmcli device status Set a variable — replace with your actual connection name CONN="Wired connection 1" Apply static IP configuration Replace values to match your network sudo nmcli connection modify "$CONN" \ ipv4.method manual \ ipv4.addresses "192.168.1.100/24" \ ipv4.gateway "192.168.1.1" \ ipv4.dns "8.8.8.8,1.1.1.1" \ ipv4.ignore-auto-dns yes \ connection.permissions "" \ connection.autoconnect yes \ connection.autoconnect-priority 100 Apply immediately sudo nmcli connection down "$CONN" && \ sudo nmcli connection up "$CONN" Confirm the IP hostname -I Disable the network boot timeout service to prevent slow headless boots: sudo systemctl disable NetworkManager-wait-online.service sudo systemctl mask NetworkManager-wait-online.service sudo apt install openssh-server -y sudo systemctl enable ssh sudo systemctl start ssh sudo systemctl status ssh Edit /etc/ssh/sshd config — back it up first: sudo cp /etc/ssh/sshd config /etc/ssh/sshd config.backup sudo nano /etc/ssh/sshd config Ensure these directives are set uncomment or add as needed : Port 22 PubkeyAuthentication yes PasswordAuthentication yes PermitRootLogin prohibit-password ClientAliveInterval 60 ClientAliveCountMax 10 TCPKeepAlive yes X11Forwarding yes MaxAuthTries 6 sudo systemctl restart ssh From the remote host replace 192.168.1.100 with your Jetson IP : Generate a key pair if you don't have one ssh-keygen -t ed25519 -C "remote-to-jetson" -f ~/.ssh/jetson orin Deploy the public key to the Jetson On Linux/macOS: ssh-copy-id -i ~/.ssh/jetson orin.pub jetson@192.168.1.100 On Windows PowerShell: type "$env:USERPROFILE\.ssh\jetson orin.pub" | ssh jetson@192.168.1.100 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat ~/.ssh/authorized keys && chmod 600 ~/.ssh/authorized keys" Once key login is confirmed, disable password authentication: sudo nano /etc/ssh/sshd config Set: PasswordAuthentication no sudo systemctl restart ssh Create or edit ~/.ssh/config on the remote machine: Host jetson HostName 192.168.1.100 User jetson IdentityFile ~/.ssh/jetson orin IdentitiesOnly yes ServerAliveInterval 60 ServerAliveCountMax 10 TCPKeepAlive yes Now you can connect with just: ssh jetson XRDP and NoMachine both require X11. Ubuntu 24.04 defaults to Wayland — disable it: sudo nano /etc/gdm3/custom.conf Set the file content to: daemon WaylandEnable=false AutomaticLoginEnable=true AutomaticLogin=jetson security xdmcp chooser debug sudo nano /etc/environment Add these lines: QT QPA PLATFORM=xcb GDK BACKEND=x11 XDG SESSION TYPE=x11 Without a physical monitor, the Tegra GPU creates a minimal 640×480 framebuffer. The dummy Xorg driver creates a proper 1920×1080 virtual display that NoMachine can use as a physical desktop target. sudo apt install xserver-xorg-video-dummy -y sudo mkdir -p /etc/X11/xorg.conf.d/ sudo tee /etc/X11/xorg.conf.d/30-tegra-headless.conf << 'EOF' Section "Device" Identifier "Tegra" Driver "nvidia" Option "AllowEmptyInitialConfiguration" "true" Option "UseDisplayDevice" "none" EndSection Section "Monitor" Identifier "Monitor0" HorizSync 28.0-80.0 VertRefresh 48.0-75.0 Modeline "1920x1080" 148.50 1920 2008 2052 2200 1080 1084 1089 1125 +hsync +vsync EndSection Section "Screen" Identifier "Screen0" Device "Tegra" Monitor "Monitor0" DefaultDepth 24 SubSection "Display" Depth 24 Virtual 1920 1080 EndSubSection EndSection EOF These settings prevent the remote session from being interrupted: Run these as your user not root gsettings set org.gnome.desktop.screensaver lock-enabled false gsettings set org.gnome.desktop.screensaver idle-activation-enabled false gsettings set org.gnome.desktop.session idle-delay 0 gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout 0 gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout 0 gsettings set org.gnome.settings-daemon.plugins.power idle-dim false gsettings set org.gnome.settings-daemon.plugins.power power-button-action 'nothing' NoMachine creates its own virtual X server and launches the desktop session independently. GDM the GNOME Display Manager is not needed and would conflict. Set boot to multi-user CLI only, no display manager sudo systemctl set-default multi-user.target Ensure GDM does not start sudo systemctl stop gdm 2 /dev/null || true Do NOT run: sudo systemctl disable gdm On Ubuntu 24.04, gdm is statically enabled via graphical.target Switching to multi-user.target is the correct method to prevent it from starting Verify systemctl get-default Expected: multi-user.target XFCE4 is the desktop environment that runs inside the NoMachine virtual display. It does not require GPU compositor support, making it fully compatible with virtual displays. sudo apt install xfce4 xfce4-goodies xfce4-terminal -y Configure it as the session to launch: bash cat ~/.xsession << 'EOF' /bin/bash unset DBUS SESSION BUS ADDRESS unset XDG RUNTIME DIR exec startxfce4 EOF chmod +x ~/.xsession Always download the latest ARM64 DEB from the official page: https://downloads.nomachine.com/download/?id=30&platform=linux&distro=arm cd ~/Downloads Check the current version at the URL above and adjust the filename wget "https://web9001.nomachine.com/download/9.7/Arm/nomachine 9.7.3 1 arm64.deb" sudo dpkg -i nomachine 9.7.3 1 arm64.deb sudo apt --fix-broken install -y The installation output will show warnings about CUPS printer support These are expected and harmless — NoMachine installs correctly Verify the server started sudo /usr/NX/bin/nxserver --status Expected: Running server at port: 4000 Find and edit node.cfg sudo nano /usr/NX/etc/node.cfg Search for DefaultDesktopCommand and VirtualDesktopCommand — add or uncomment: DefaultDesktopCommand /usr/bin/startxfce4 VirtualDesktopCommand /usr/bin/startxfce4 DisplayGeometry 1920x1080 AllowDesktopResize 1 Restart NoMachine to apply changes sudo /usr/NX/bin/nxserver --restart sudo /usr/NX/bin/nxserver --status sudo tee /etc/systemd/system/nomachine-headless.service << 'EOF' Unit Description=NoMachine Headless Server After=network.target NetworkManager.service Service Type=oneshot RemainAfterExit=yes ExecStart=/usr/NX/bin/nxserver --restart ExecStop=/usr/NX/bin/nxserver --stop Install WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable nomachine-headless sudo systemctl start nomachine-headless Note:UFW is not installed by default in JetPack 7.2 on Ubuntu 24.04. sudo apt install ufw -y Ubuntu 24.04 with kernel 6.8 uses nftables as the backend, but UFW expects iptables-legacy. Without this fix, sudo ufw enable will produce errors like RULE APPEND failed No such file or directory . Switch to iptables-legacy sudo update-alternatives --set iptables /usr/sbin/iptables-legacy sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy Verify sudo iptables --version Expected: iptables v1.8.x legacy sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp comment "SSH" sudo ufw allow 4000/tcp comment "NoMachine NX" Add additional ports as needed for your stack: sudo ufw allow 3389/tcp comment "XRDP" sudo ufw allow 11434/tcp comment "Ollama" sudo ufw allow 8000/tcp comment "vLLM" sudo ufw allow 3000/tcp comment "Open WebUI" sudo ufw allow 8888/tcp comment "Jupyter" sudo ufw enable Type 'y' when prompted sudo ufw status numbered If UFW continues to fail even after the iptables-legacy fix, use nftables directly — it is the native firewall on Ubuntu 24.04: bash sudo apt install nftables -y sudo tee /etc/nftables.conf << 'EOF' /usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority 0; policy drop; ct state established,related accept iif "lo" accept ip protocol icmp accept ip6 nexthdr icmpv6 accept tcp dport 22 accept comment "SSH" tcp dport 4000 accept comment "NoMachine" Add more ports here as needed } chain forward { type filter hook forward priority 0; policy accept; } chain output { type filter hook output priority 0; policy accept; } } EOF sudo systemctl enable nftables sudo systemctl start nftables sudo nft list ruleset sudo reboot Disconnect the physical monitor and keyboard. After approximately 30 seconds, from the remote host: Test 1: Network is up ping 192.168.1.100 Test 2: SSH is reachable ssh jetson Test 3: NoMachine port is open Linux/macOS: nc -zv 192.168.1.100 4000 Windows PowerShell: Test-NetConnection -ComputerName 192.168.1.100 -Port 4000 If all three pass, the Jetson is running fully headless. 192.168.1.100 → Port: 4000 In JetPack 7.2, the CUDA compiler nvcc is installed but not in the default PATH. Add it: Install CUDA development tools if not present sudo apt install nvidia-cuda-dev -y Add CUDA to PATH permanently echo 'export PATH=/usr/local/cuda/bin:$PATH' ~/.bashrc echo 'export LD LIBRARY PATH=/usr/local/cuda/lib64:$LD LIBRARY PATH' ~/.bashrc source ~/.bashrc Verify nvcc --version Expected: Cuda compilation tools, release 13.2, ... Run this block after a clean reboot to confirm the headless setup is complete: echo "=== Headless Mode Verification ===" echo -n "Network static IP : " hostname -I | grep -q "192.168.1.100" && echo "OK" || echo "FAIL" echo -n "SSH server: " systemctl is-active ssh echo -n "Boot target no GDM : " systemctl get-default echo -n "GDM status: " systemctl is-active gdm 2 /dev/null || echo "inactive correct " echo -n "NoMachine port 4000: " sudo ss -tlnp | grep -q ":4000" && echo "listening" || echo "NOT listening" echo -n "XFCE4 installed: " which startxfce4 && echo "OK" || echo "NOT FOUND" echo -n "~/.xsession → XFCE4: " grep -q "startxfce4" ~/.xsession && echo "OK" || echo "NOT configured" echo -n "Wayland disabled: " grep -q "WaylandEnable=false" /etc/gdm3/custom.conf && echo "OK" || echo "NOT disabled" echo -n "Xorg dummy driver: " test -f /etc/X11/xorg.conf.d/30-tegra-headless.conf && echo "OK" || echo "NOT configured" echo -n "CUDA PATH: " nvcc --version 2 /dev/null | grep -o "release 0-9. " || echo "NOT in PATH — run: source ~/.bashrc" echo "=== Done ===" Expected output all lines should show OK or the correct active status : === Headless Mode Verification === Network static IP : OK SSH server: active Boot target no GDM : multi-user.target GDM status: inactive correct NoMachine port 4000: listening XFCE4 installed: /usr/bin/startxfce4 OK ~/.xsession → XFCE4: OK Wayland disabled: OK Xorg dummy driver: OK CUDA PATH: release 13.2, === Done === This typically means gnome-shell was launched instead of XFCE4. Check ~/.xsession cat ~/.xsession Must contain: exec startxfce4 Check node.cfg grep -E "DefaultDesktop|VirtualDesktop" /usr/NX/etc/node.cfg Must point to /usr/bin/startxfce4 Fix and restart cat ~/.xsession << 'EOF' /bin/bash unset DBUS SESSION BUS ADDRESS unset XDG RUNTIME DIR exec startxfce4 EOF chmod +x ~/.xsession sudo /usr/NX/bin/nxserver --restart Then disconnect and reconnect from the NoMachine client, choosing "Create a new virtual desktop" . The SSH port is open but the connection times out. SSH may be down, or UFW may be blocking it. Via a physical connection or recovery sudo systemctl status ssh sudo systemctl start ssh sudo ufw status sudo ufw allow 22/tcp The Ethernet connection may require a user session to activate. Verify the connection.permissions fix: nmcli connection show "Wired connection 1" | grep permissions Must show: connection.permissions: empty If not empty, reapply sudo nmcli connection modify "Wired connection 1" connection.permissions "" sudo nmcli connection up "Wired connection 1" sudo update-alternatives --set iptables /usr/sbin/iptables-legacy sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy sudo ufw disable sudo ufw reset sudo ufw enable The PATH change requires sourcing the profile source ~/.bashrc Or specify the full path directly /usr/local/cuda/bin/nvcc --version Verify the binary exists ls /usr/local/cuda/bin/nvcc | Step | Action | Result | |---|---|---| | 1–3 | System update + packages + hostname | Base system ready | | 4 | Static IP + connection.permissions="" | Network up without login | | 5 | SSH + key auth | Secure remote terminal | | 6 | Disable Wayland + dummy Xorg driver | X11 display at 1920×1080 | | 7 | multi-user.target no GDM | NoMachine owns the display | | 8 | XFCE4 + ~/.xsession | Desktop environment ready | | 9 | NoMachine server + node.cfg | Virtual GUI accessible | | 10 | UFW + iptables-legacy fix | Firewall active | | 11 | Reboot test without monitor | Fully headless | | 12 | NoMachine client → virtual desktop | Full GUI via NX | | 13 | CUDA PATH | nvcc accessible | After completing all steps, the Jetson AGX Orin operates entirely without a physical display. SSH provides terminal access and NoMachine provides full XFCE4 desktop access — both available immediately after any reboot, without any physical interaction with the device. Platform: NVIDIA Jetson AGX Orin Developer Kit 64GB · JetPack 7.2 L4T r39.2 · Ubuntu 24.04 LTS · NoMachine 9.7.3