Geti™ is a full-stack web application to build and deploy computer vision AI models, powered by the getitune library. This guide covers all the supported ways to install and run Geti™ so you can choose the method that best fits your workflow.
| Component | Requirement |
|---|---|
| CPU | 8 threads |
| RAM | 16 GB |
| Disk | 40 GB free |
| GPU | Optional - Intel® XPU or NVIDIA® GPU for larger models |
Note
NVIDIA® GPUs with compute capability below 7.5 (e.g. Volta, Maxwell, Pascal) require a manual patch to work. See Troubleshooting > I have an old Nvidia GPU, does Geti support it?.
There are several ways to run Geti™, choose the one that best fits your workflow:
- Windows app - install as a native desktop application.
- Docker - download and run one of the pre-built Docker images, or build one yourself.
- Install script - download and run a script that builds and configures Geti™ automatically.
- Run from source (for development) - run the server and the UI as standalone components.
For deployment-specific log collection and troubleshooting, see Troubleshooting > Logs.
Installing Geti™ as a Windows app is the simplest way to run it on Windows.
- Download the Windows Installer suitable for your hardware (prebuilt packages for Intel® XPU, NVIDIA® CUDA, and CPU-only environments):
- Double-click the
.msixpackage and click Install in the Windows installer dialog. - Launch Geti™ from the Start menu.
If Windows shows a security prompt, verify that the package is from the official Geti™ release before continuing.
Important
Windows apps do not include Ultralytics models due to AGPL licensing constraints. If you need them, please use the install script or build a Docker image from source as described below.
The easiest and most portable way to run Geti™ is through Docker. Pre-built images are published for Intel® XPU and NVIDIA® CUDA platforms; you can also build your own image from source.
- Docker v29+ [Docs]
- (Optional, recommended) Just v1.46+ [Docs]
- (Only for Intel® XPU) the latest driver suitable with your HW [Docs]
- (Only for NVIDIA GPU) NVIDIA driver and the NVIDIA Container Toolkit [Docs]
- Ubuntu 24+ or WSL2 with Ubuntu 24+ [Docs]
Choose the most suitable image for your system:
# Choose the right image based on your hardware. Available options:
# - xpu: best choice if you have a modern Intel® CPU or GPU
# - cuda: recommended if you have a CUDA-enabled platform
# - cpu: most lightweight option (CPU-only) if you don't have a compatible GPU
docker pull ghcr.io/open-edge-platform/geti-xpuRetag the pulled image as geti-{cpu,xpu,cuda}:latest for use with just run-image:
docker tag ghcr.io/open-edge-platform/geti-cpu:latest geti-cpu:latestImportant
Pre-built container images do not include Ultralytics models due to AGPL licensing constraints. If you need them, build the image from source as described below.
Geti™ Docker images can be built from source using the Dockerfile in the application
directory. This is useful if you want to customize the application or include Ultralytics models. The instructions
below use just to simplify the build process, but you can also build the image manually with docker build if you prefer.
From the application directory:
# Build for Intel® XPU (recommended)
just build-image --accelerator xpuThe above command builds an image optimized for modern Intel® hardware. If you have an Intel® GPU (discrete or integrated),
this is the recommended configuration for best performance. Alternatively, you can build with support for NVIDIA GPUs
(--accelerator cuda) or with CPU-only support (--accelerator cpu).
Run just --usage build-image to see all build options.
Once you have downloaded or built the Geti™ image, use the run-image command to launch the application:
# Run the image built with Intel® XPU support
just run-image --accelerator xpuIf you built the image with a different accelerator, make sure to specify the same one when running.
For a full list of runtime options, run just --usage run-image.
After the container starts, you can access the Geti™ web application at https://localhost:7860 (assuming default settings).
If your browser warns about a self-signed certificate, choose to proceed.
Custom port
By default, Geti™ publishes on host port 7860. If that port is already in use on your machine, or you simply prefer a
different one, pass --port to just run-image:
just run-image --accelerator xpu --port 8080The Geti™ web application is then reachable at https://localhost:8080.
TLS certificates
By default, the container generates a self-signed certificate at startup and serves over HTTPS on the configured port.
For production deployments, mount your certificate and private key into the container using --volumes, then point
--certfile and --keyfile to the in-container paths:
just run-image --accelerator xpu \
--volumes "/path/to/certs:/certs:ro" \
--certfile /certs/server.pem \
--keyfile /certs/server-key.pemThe cert directory is mounted read-only and is separate from the data volume - it is never modified by the container.
[!NOTE] The self-signed certificate triggers a browser security warning. For a trusted local setup, generate a locally-trusted cert with mkcert and pass it the same way.
Browse the app storage
The Geti™ application uses a Docker volume named geti-data to persistently store all datasets, models, and other objects.
You can browse the contents of this volume by running a temporary container that mounts the volume and lists the files.
# List the contents of the root directory in the `geti-data` volume
docker run --rm -v geti-data:/data alpine ls -l /data
# List the model files of a specific project (replace <PROJECT_ID> with the actual ID)
docker run --rm -v geti-data:/data alpine ls -l /data/projects/<PROJECT_ID>/models
# List the media files of a specific project (replace <PROJECT_ID> with the actual ID)
docker run --rm -v geti-data:/data alpine ls -l /data/projects/<PROJECT_ID>/datasetGeti™ uses WebRTC for real-time inference streaming visualization in the UI. WebRTC requires the browser to establish a direct connection to the backend's media server. Use these options when the in-app WebRTC preview does not connect under NAT, load balancers, or restrictive firewall policies.
| Scenario | Recommended setup |
|---|---|
| Local machine / same LAN | Usually no extra setup. If needed, set a STUN server so the host advertises a reachable address. |
| Public or cloud host with dynamic public IP | Use STUN so the host can discover and advertise its public address. |
| Public host behind load balancer with fixed public IP/DNS | Configure the advertised public endpoint in your runtime setup. |
| Restrictive firewall (UDP blocked, only TCP 443 allowed) | Run a TURN relay and start Geti™ with TURN enabled. |
Local machine or local network
On localhost this often works without changes. For LAN clients, run with STUN:
just run-image --accelerator xpu --stun stun:stun.l.google.com:19302Dynamic public IP (cloud or ephemeral hosts)
Use STUN-based discovery:
just run-image --accelerator xpu --stun stun:stun.l.google.com:19302Fixed public IP or DNS
If your deployment has a stable public endpoint, set that endpoint in your runtime configuration so clients do not receive an internal/private address.
Restrictive firewall: TURN relay
When UDP media ports are blocked, relay media through TURN over TCP/443.
-
Start TURN relay:
just run-coturn
-
Start Geti™ with TURN enabled:
just run-image --accelerator xpu --coturn
-
For custom TURN endpoint settings:
just run-image --accelerator xpu --coturn --coturn-host <public_ip_or_dns> --coturn-port 443
-
Stop TURN relay:
just stop-coturn
Notes:
- TURN adds relay overhead. Prefer direct WebRTC when your network allows it.
- The default TURN recipe is suitable for development/validation. For production, use short-lived credentials and hardened TURN settings.
- If you run Docker directly (without
just), publish the WebRTC UDP media port range and keep it reachable.
For development purposes, you can run the Geti™ server and UI as standalone components without Docker.
- Just v1.46+ [Docs]
- (Only for Intel® XPU) the latest driver suitable with your HW [Docs]
- (Only for NVIDIA GPU) NVIDIA driver and the NVIDIA Container Toolkit [Docs]
- Node.js v24.2+ [Docs]
- Ubuntu 24+ or WSL2 with Ubuntu 24+ [Docs]
To run the server, use the run-server command after initializing the environment with venv:
# From the repo root
cd application/backend
# Initialize the environment with the appropriate accelerator support (cpu, xpu, or cuda)
just venv --accelerator xpu
# Run the server
just run-serverRun just --usage run-server for a full list of options for running the server. Notably, by passing the option
--setup-demo, the application will be pre-populated with demo data, including sample datasets and pre-trained models.
After running the server, build and launch the UI in a separate terminal:
# From the repo root
cd application/ui
# Install dependencies and build
npm install
npm run build
# Start the UI
npm run startAfter the UI starts, you can access the Geti™ web application at http://localhost:3000 (assuming default settings).
The quickest way to build Geti™ from source is the install script. It downloads the source code, automatically detects
your hardware (Intel® XPU, NVIDIA® CUDA, or CPU-only), installs the required build tools, builds the backend and UI, and
registers a geti command you can use to launch the application.
The installer sets up its own copy of uv, Node.js and npm under .build/, then builds the backend and UI and starts
the app. The first build downloads several GB of packages (PyTorch, OpenVINO, …) and can take a while — progress is shown
for each step. Re-running the installer reuses the cached tools and dependencies, so only the first build is slow.
Installing from source also enables native Ultralytics YOLO26 models — the latest NMS-free, edge-optimized models (Nano / Small / Medium) for object detection and instance segmentation. The integration covers the full model lifecycle: training, inference, quantization, and OpenVINO™ model export.
- Ubuntu 24+ or WSL2 with Ubuntu 24+ [Docs]
git(required on all platforms) andcurl(required on Linux/WSL)- (Only for Intel® XPU) the latest driver suitable with your HW [Docs]
- (Only for NVIDIA GPU) NVIDIA driver and the NVIDIA Container Toolkit [Docs]
Linux / WSL2
Run the command below to download the script and start the installation in one step. The --yes flag runs it
non-interactively, accepting the default prompts:
curl -fsSL https://raw.githubusercontent.com/open-edge-platform/geti/develop/install.sh | bash -s -- --yesPrefer to inspect the script before running it? Download it first, then execute it (this also lets you answer the prompts interactively):
# Download the installer
curl -fsSL https://raw.githubusercontent.com/open-edge-platform/geti/develop/install.sh -o install.sh
# (Optional) Review the script, then run it
bash install.shYou can forward flags through the pipe with bash -s --: -v/--verbose (stream full output), -y/--yes
(non-interactive), -w/--work-dir <path> (custom install directory, default ./geti):
curl -fsSL https://raw.githubusercontent.com/open-edge-platform/geti/develop/install.sh | bash -s -- --yes --work-dir ~/getiWindows (PowerShell)
irm https://raw.githubusercontent.com/open-edge-platform/geti/develop/install.ps1 | iexTo pass parameters — -Verbose (stream full output), -Yes/-y (non-interactive), -WorkDir <path>/-w (custom
install directory, default .\geti) — run the downloaded script as a script block instead:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/open-edge-platform/geti/develop/install.ps1))) -Yes -WorkDir C:\getiIf your execution policy blocks remote scripts, download first and run it explicitly (Bypass applies only to this process and does not change your machine policy):
curl.exe -L https://raw.githubusercontent.com/open-edge-platform/geti/develop/install.ps1 -o install.ps1
powershell -ExecutionPolicy Bypass -File .\install.ps1If a build step fails, re-run with --verbose (Linux) or -Verbose (Windows), or inspect the log at
<work-dir>/.build/.install.log.
When the script finishes, it can add a geti command to your shell profile (on Windows, you’ll be prompted). Reload your shell profile, then start the application:
# Reload your shell profile (use ~/.zshrc if you use zsh)
source ~/.bashrc # or: source ~/.zshrc
# Start Geti™ (optionally set HOST and PORT)
HOST=0.0.0.0 PORT=8080 geti
# Start Geti™ with STUN enabled
STUN_SERVER=stun:stun.l.google.com:19302 HOST=0.0.0.0 PORT=8080 geti
# Start Geti™ using the active COTURN server (ensuring the IP and port match the running instance)
COTURN_HOST=10.123.246.153 COTURN_PORT=443 HOST=0.0.0.0 PORT=8080 getiThen open the Geti™ web application at https://localhost:8080. If your browser warns about a self-signed certificate,
choose to proceed.
Air-gapped setup (pretrained weights cache)
When deploying Geti™ in an air-gapped or restricted network environment, the application cannot automatically download pretrained model weights from remote repositories. You must manually preconfigure and populate the pretrained weights cache before running the application.
To find the exact URLs for the pretrained weights required by a specific model:
- Navigate to the model manifest files bundled with the Geti™ application backend (e.g.,
application/backend/app/supported_models/manifests/classification/vit_tiny.yaml). - Look for the
pretrained_weights.urlattribute within the manifest file to retrieve the direct download link. - Note the corresponding
pretrained_weights.sha_sumattribute - you'll use it to verify the integrity of the downloaded file before placing it in the cache. - Note the
pretrained_weights.cache_filenameattribute, if present. This is the filename to use when placing the weights in the cache. If unspecified, use the same basename specified in the URL.
Before transferring the downloaded weights file into the air-gapped environment, verify it hasn't been tampered with or
corrupted by comparing its SHA-256 checksum against the sha_sum value from the manifest:
# Compute the SHA-256 checksum of the downloaded file
shasum -a 256 /path/to/local/downloaded/<WEIGHTS_FILE_NAME>
# Compare the output against the `pretrained_weights.sha_sum` value in the model manifest.
# The two values must match exactly before proceeding.[!CAUTION] Do not place a weights file into the cache if its checksum doesn't match the manifest's sha_sum. Geti™ performs this verification automatically when loading cached weights, and a mismatch will cause the file to be treated as invalid - but validating it upfront avoids wasting time transferring a corrupted or tampered file into an air-gapped environment.
Once you have downloaded and verified the integrity of the required weights file on an internet-connected machine, transfer it to your air-gapped environment and place it in the application data directory.
Because Geti™ stores its application data inside the geti-data Docker volume, you can use a temporary container to
inject the downloaded file into the proper cache directory:
# Copy the downloaded weights file into the application's pretrained cache folder
docker run --rm -i -v geti-data:/data alpine sh -c "mkdir -p /data/pretrained_weights/<TASK_TYPE> && cat > /data/pretrained_weights/<TASK_TYPE>/<WEIGHTS_FILE_NAME>" < /path/to/local/downloaded/<WEIGHTS_FILE_NAME>
# Verify that the file is correctly placed
docker run --rm -v geti-data:/data alpine ls -l /data/pretrained_weights/<TASK_TYPE>[!NOTE] Replace
<TASK_TYPE>with the corresponding model task type (e.g.,classification,detection, orinstance_segmentation). Replace<WEIGHTS_FILE_NAME>with the exact filename retrieved from the manifest. Replace/path/to/local/downloaded/with the path to the file on your host machine.
- Upgrading an existing Geti™ v3 installation to a newer release? See the Upgrade guide for how to move to a newer version (Docker or Windows MSIX) while preserving your projects, datasets and models, with automatic rollback if a migration fails.
- Upgrading from Geti™ v2 to v3? The two versions have different architectures and storage layouts. Follow the dedicated migration guidance in the Geti™ documentation.
-
Docker: Stop and remove the running container, then remove the pulled image. To also delete all stored data, remove the
geti-datavolume (this is irreversible):# Stop and remove the container (replace <container> with the container name or ID) docker stop <container> && docker rm <container> # (Optional) Remove the image (instead of xpu, use `geti-cuda` or `geti-cpu` if you pulled those images) docker rmi ghcr.io/open-edge-platform/geti-xpu # (Optional, irreversible) Delete all stored datasets, models, and logs docker volume rm geti-data geti-logs
-
MSIX (Windows app): Uninstall the package from the Start menu (right-click Geti™ > Uninstall) or via Settings > Apps > Installed apps > Geti™ > Uninstall.
I have an old Nvidia GPU, does Geti support it?
Geti's cuda builds use PyTorch wheels compiled against CUDA 13.0, which dropped support for NVIDIA GPU
architectures older than Ampere (compute capability < 8.0), covering Volta, Turing, Maxwell, and Pascal cards. If
your GPU falls in this range, you must patch the source to build against CUDA 12.6 instead, which still supports
compute capability >= 5.0.
-
Install script: patch
pyproject.tomlbefore running the installer:git clone https://github.com/open-edge-platform/geti.git cd geti/application just patch-for-legacy-gpu-support # Then run install.sh / install.ps1 as usual, from the repo root
-
Docker (build from source): run the patch recipe from the
applicationdirectory, then build the image as usual:cd application just patch-for-legacy-gpu-support just build-image --accelerator cuda -
Run from source (development): run the patch recipe from the
applicationdirectory before initializing the backend environment:cd application just patch-for-legacy-gpu-support cd backend just venv --accelerator cuda
[!NOTE] The Windows app (MSIX) is prebuilt and cannot be patched this way; it requires the newer PyTorch/CUDA wheels.
WSL2: WebRTC preview connects but video freezes after a few frames
When the backend runs in WSL2 and the browser runs on the Windows host, the WebRTC preview may show
the first few frames and then freeze. Typical symptoms: the browser's framesReceived stops increasing while
bytesReceived keeps growing and packetsLost climbs steadily. This means bytes reach the browser but complete
video frames can never be reassembled — the classic signature of large RTP/UDP packets being dropped by WSL2's
virtual NIC (an MTU/NAT issue), not an ICE candidate problem. Because the byte path itself is broken,
--webrtc-advertise-ip, --stun, and --coturn all fail identically.
Fixes, in order of preference:
-
Enable WSL2 mirrored networking (recommended). This makes WSL share the Windows host network stack and removes the virtual NAT/MTU boundary entirely. Add the following to
%UserProfile%\.wslconfigon Windows and restart WSL (wsl --shutdown):[wsl2] networkingMode=mirrored
-
Lower the WSL2 interface MTU so RTP packets fit without fragmentation, then reconnect the stream:
sudo ip link set dev eth0 mtu 1400If this helps, make it persistent (e.g. via a WSL boot command in
/etc/wsl.conf). -
Run the backend and browser on the same side (both inside WSL, or use the Docker image on the Windows host) to avoid crossing the WSL2 network boundary altogether.
View the logs
When running Geti™ with Docker, all logs are stored in the geti-logs Docker volume. You can view these logs by running
a temporary container that mounts the volume and prints the log files to the console.
These examples use jq to format the JSON logs; install jq on the host or omit the | jq -r '.text' part to see the
raw JSON output.
Application logs:
# Print the logs of the application container to the console
docker run --rm -v geti-logs:/logs alpine cat /logs/app.log | jq -r '.text'
# Or save the logs to a file for easier browsing
docker run --rm -v geti-logs:/logs alpine cat /logs/app.log | jq -r '.text' > geti-logs.txtJob logs:
# List the available job logs
docker run --rm -v geti-logs:/logs alpine ls -l /logs/jobs
# Print the logs of a specific job to the console
docker run --rm -v geti-logs:/logs alpine cat /logs/jobs/<job_type>-<job_id>.log | jq -r '.text'Logs of other worker processes:
# Print the logs of the inference pipeline stream loader
docker run --rm -v geti-logs:/logs alpine cat /logs/workers/streamloader.log | jq -r '.text'
# Print the logs of the inference worker
docker run --rm -v geti-logs:/logs alpine cat /logs/workers/inference.log | jq -r '.text'Note
Ultralytics YOLO models are distributed under the AGPL-3.0 license, an OSI approved license ideal for open-source research, academic, and personal projects. For commercial use, enhanced support, and tailored licensing terms, please explore flexible Ultralytics licensing options at https://www.ultralytics.com/license.
