Deployment
Use this checklist when moving an Oden setup from commissioning to unattended or production use. It focuses on the parts that must survive restarts: the Streamer service, the Streamer project file, Player display behavior, licenses, network reachability, and startup verification.
Streamer service
On Linux vehicle computers, Oden Fleet Streamer can install a systemd service named oden-streamer.service.
The service is not installed by default.
During package installation, choose to install, enable, and start the service when the Streamer should run automatically on boot.
For scripted Linux deployments, pre-seed the installer answers before installing the Fleet Streamer package:
echo "oden-streamer oden-streamer/accept-eula boolean true" | sudo debconf-set-selections
echo "oden-streamer oden-streamer/install-services boolean true" | sudo debconf-set-selections
export DEBIAN_FRONTEND=noninteractive
sudo apt-get install ./oden-fleet-streamer_*.deb
The service runs as root, uses /opt/oden-streamer as its working directory, and starts:
/usr/bin/oden-streamer --headless /opt/oden-streamer/oden-vehicle-config.vproj
Use systemctl for normal service operations:
sudo systemctl status oden-streamer.service
sudo systemctl start oden-streamer.service
sudo systemctl stop oden-streamer.service
sudo systemctl restart oden-streamer.service
sudo systemctl enable oden-streamer.service
sudo systemctl disable oden-streamer.service
--headless is a Linux Streamer mode where the GUI is not rendered.
It is intended for unattended vehicle computers and embedded platforms.
|
If you need remote access to the Streamer GUI while output is stopped, start the Streamer with --configurator as well, or make that part of the deployment’s service definition.
See Projects and Scenes for the Player-side Streamer Configurator workflow.
Do not start a second Streamer on the same computer while the service is running.
Stop oden-streamer.service before opening the same project in the local GUI.
Streamer project file
The Fleet Streamer service loads /opt/oden-streamer/oden-vehicle-config.vproj.
If that file does not exist when the service starts, the service copies /opt/oden-streamer/oden-vehicle-config-default.vproj to that path before launching Streamer.
Keep the production vehicle project at:
/opt/oden-streamer/oden-vehicle-config.vproj
To edit the project on the vehicle computer:
-
Stop the service.
-
Open the project with elevated permissions.
-
Save the project.
-
Close Streamer.
-
Start the service again.
sudo systemctl stop oden-streamer.service
sudo oden-streamer /opt/oden-streamer/oden-vehicle-config.vproj
sudo systemctl start oden-streamer.service
The project may be owned by root because the service runs as root.
If you open it as a normal user, saving may fail.
Prefer changing the project through the Streamer GUI or Streamer Configurator.
Editing the .vproj file directly is possible because it is a libconfig file, but it is easy to break a production project with an invalid edit.
Before deploying the project, confirm at least:
-
The correct
Startup Sceneis selected in Project Settings. -
All camera inputs start reliably after a cold boot.
-
The Streamer
Outputsettings match the target resolution, codec, bitrate, FEC, and bandwidth-control policy. -
Any project plugins are deployed beside the project or in the configured
Project Plugins Path.
Player display setup
For operator stations, configure the Player so the operator sees the intended view without commissioning controls.
Set these in Application Settings on the Player:
- Hide GUI on Startup
-
Enable when the Player should start with the GUI hidden.
- Inhibit Mouse Look
-
Enable when mouse movement must not move the 3D camera.
- Window Mode
-
Choose the production display mode. Use
Fullscreenfor lowest latency on one display,Windowed Fullscreenwhen the window should stay visible while another screen is clicked, orSpanning Fullscreenfor a multi-display span. - Only Show Exit Dialog
-
Enable if operators should see only the exit dialog while the GUI is hidden.
The same settings can be deployed through the application config file:
- Windows
-
%LOCALAPPDATA%\oden\oden.conf - Linux
-
$HOME/.config/oden/oden.conf
hide_gui : true;
inhibit_mouse_look : true;
window_mode : "fullscreen";
Use "windowed_fullscreen" or "spanning_fullscreen" instead of "fullscreen" when that better matches the display layout.
The GUI can still be toggled with the configured Toggle Hide GUI keyboard shortcut.
The default shortcut is Ctrl+H.
The --windowless command-line flag hides the Player window itself.
Use it only for deployments where the Player must run without a visible application window.
The windowless mode can be toggled with Ctrl+Shift+H.
HMD and VR display setup
When the Player is used with a head-mounted display, configure HMD behavior before hiding the GUI for production. Tested HMD families include Valve Index, HP Reverb G1/G2, and HTC Vive Pro 1/2. Other OpenVR/OpenXR-compatible headsets may work, but should be validated with the production GPU, driver, and runtime.
Key settings:
- HMD Selection
-
Selects the runtime backend:
Any,Oculus,OpenVR,OpenXR, orNone. UseNoneto disable HMD output andAnyonly when the deployment does not need a fixed backend. - Fixed Position
-
Locks HMD position to the origin and disables XYZ movement in the HMD world.
- Fps Cam Track HMD
-
Makes the monitor view match what the HMD user sees.
- Draw Background
-
Shows the Oden background in the HMD.
- Draw While Inactive
-
Keeps rendering to the HMD even when the headset is not currently worn.
- Draw To Screen
-
Disable screen rendering when only the HMD output is needed and GPU load must be reduced.
Avoid changing HMD field-of-view factors unless Voysys support has asked for it. Non-default FoV can cause operator discomfort and invalidates display validation.
For controller-based plugins, test controller remapping on the exact HMD model. Button and axis IDs can differ between runtimes and controller generations.
Licenses
Activate each installed Oden application on the computer where it will run before production use. Activation requires internet access and binds the license to that computer. After activation, Oden can run offline until the local activation period needs to be refreshed.
For headless Streamer service installations, activate with the same Linux command that the service uses, then restart the service:
sudo oden-streamer --activate <license-key>
sudo systemctl restart oden-streamer.service
For Player deployments, activate the installed Player application:
oden-vr --activate <license-key>
On Windows, run the installed executable from PowerShell:
& "C:\Program Files\OdenVR\OdenVR.exe" --activate <license-key>
& "C:\Program Files\Oden Streamer\OdenStreamer.exe" --activate <license-key>
Before moving a license to another computer, revoke it while the old computer still has internet access:
oden-vr --revoke
oden-streamer --revoke
Check during acceptance testing and record the activation status for each production computer. For license file locations and offline behavior, see Activate Licenses and Projects and Scenes.
Network readiness
Verify the production network from the direction Oden will actually connect. By default, the Streamer initiates the connection and the Player responds, so the Player receive port must be reachable from the Streamer.
Check these items before unattended operation:
-
The Player
Remote Streamerentity has the correct link mode, receive port, and bind settings. -
The Streamer network settings point at the Player responder address and port, or at the configured relay path.
-
Firewalls allow the Oden traffic on the configured ports.
-
If a Linux link uses
Bind Device, the named network interface exists after boot and is the intended route. -
If WireGuard encryption or relay routing is used,
Internal SrcandInternal Dstmatch the tunnel addresses. -
Target Bitrate,Target usage, FEC, and reorder settings leave headroom for the real link. -
Link stats show stable bandwidth, round-trip time, and packet loss under realistic load.
Use the Player Remote Streamer stats during tests.
Packet Loss should stay near zero on a clean link, Round Trip Time should match the expected path, and Bandwidth should stay within the available network budget.
See Network, Connect Player and Streamer, and Bitrate Control and Auto Video Packing for the detailed settings.
Docker Streamer deployments
Use Docker only when the deployment needs container isolation or a containerized vehicle runtime.
Native package installation and oden-streamer.service are simpler for most vehicles.
Prerequisites:
-
NVIDIA GPU
-
Docker
-
NVIDIA Container Toolkit
On Ubuntu, install and configure NVIDIA Container Toolkit:
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
For desktop Ubuntu containers, use an Ubuntu base image matching the Oden .deb package target.
For Jetson, use an L4T base image matching the host JetPack version.
Check Jetson L4T with cat /etc/nv_tegra_release.
On desktop NVIDIA systems, the container image does not need to include the host NVIDIA driver libraries. NVIDIA Container Toolkit injects the matching driver libraries at runtime when the container is started with GPU access. That is why a plain Ubuntu base image can be enough for desktop Oden Streamer containers, as long as the Ubuntu package target matches the image.
FROM ubuntu:24.04
ARG ODEN_INSTALLER_PATH=./oden-streamer.deb
ENV DEBIAN_FRONTEND=noninteractive
COPY "$ODEN_INSTALLER_PATH" /oden-streamer.deb
RUN apt-get update -qq && \
apt-get install -qq -y --no-install-recommends /oden-streamer.deb && \
rm -rf /var/lib/apt/lists/* /oden-streamer.deb
USER root
CMD [ "oden-streamer", "--headless", "--configurator", "/root/project/streamer.vproj" ]
For Jetson containers, use the matching L4T base image:
FROM nvcr.io/nvidia/l4t-base:36.4.0
ARG ODEN_INSTALLER_PATH=./oden-streamer.deb
ENV DEBIAN_FRONTEND=noninteractive
COPY "$ODEN_INSTALLER_PATH" /oden-streamer.deb
RUN apt-get update -qq && \
apt-get install -qq -y --no-install-recommends /oden-streamer.deb && \
rm -rf /var/lib/apt/lists/* /oden-streamer.deb
USER root
CMD [ "oden-streamer", "--headless", "--configurator", "/root/project/streamer.vproj" ]
JetPack 5.1 uses nvcr.io/nvidia/l4t-base:35.3.1.
JetPack 6.1 uses nvcr.io/nvidia/l4t-base:36.4.0.
Build with the Oden Streamer .deb next to the Dockerfile:
docker build --build-arg ODEN_INSTALLER_PATH=./oden-streamer.deb -t oden-streamer:latest .
Run with GPU access, host networking, license data, and the project directory mounted:
docker run --runtime nvidia -e NVIDIA_VISIBLE_DEVICES=all \
--network host --rm -it \
-v /run/udev:/run/udev:ro \
-v ./key.conf:/root/.config/oden/Oden_Streamer/key.conf \
-v ./project:/root/project \
oden-streamer:latest
--network host is commonly used because Oden uses realtime UDP links.
Mount camera devices and plugin folders explicitly when the project needs them.
--runtime nvidia and NVIDIA_VISIBLE_DEVICES=all give the Streamer GPU access; on newer Docker installations, --gpus all can be used instead.
The /run/udev mount lets Oden read hardware identity data used by licensing.
Mount key.conf at /root/.config/oden/Oden_Streamer/key.conf when the Streamer runs as root in the container, and mount the project directory at the same path used by the Dockerfile CMD.
In the example above, the project file must be available as /root/project/streamer.vproj.
services:
oden-streamer:
image: oden-streamer:latest
network_mode: host
volumes:
- /run/udev:/run/udev:ro
- ./key.conf:/root/.config/oden/Oden_Streamer/key.conf
- ./project:/root/project
environment:
- NVIDIA_VISIBLE_DEVICES=all
runtime: nvidia
docker compose up
For Jetson zero-copy GStreamer IPC, make sure the nvunixfd plugin is available inside the container by installing it in the image or mounting it from the host.
On JetPack 5, the Streamer installer bundles the plugin in /usr/lib/aarch64-linux-gnu/gstreamer-1.0/.
On JetPack 6 and newer, install DeepStream or build it from https://github.com/voysys/nvunixfd with make, then copy the .so to /usr/lib/aarch64-linux-gnu/gstreamer-1.0/.
For container deployments, repeat that install inside the image or mount the plugin into the same path.
Startup checks
Run these checks after every production image, package upgrade, project update, or network change.
sudo systemctl status oden-streamer.service
test -f /opt/oden-streamer/oden-vehicle-config.vproj
sudo journalctl -u oden-streamer.service -b --no-pager
Confirm that:
-
The service is
active (running)after boot. -
The expected project file was loaded.
-
No license error is shown.
-
All cameras or test sources start.
-
Output starts with the expected codec, resolution, frame rate, and bitrate.
-
The Player connects without manual steps.
-
The Player GUI is hidden or visible according to the deployment profile.
-
Remote Streamer stats show expected bandwidth, round-trip time, and packet loss.
-
Control, audio, plugins, and external integrations are active if the deployment uses them.
Finally, power-cycle the vehicle computer and the operator station. Do not sign off the deployment until the complete stream, control path, and display layout recover without manual commissioning steps.