> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/heavyai/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/heavyai/llms-full.txt.

## **NVIDIA HeavyAI Open Source Build**

This document outlines the steps to download, build, and deploy the open source edition of NVIDIA HeavyAI.

## **Prerequisites**

Confirm the following are in place before starting:

* `gh` CLI installed and authenticated — run `gh auth login` if you haven't already
* A GitHub token with `read:packages` + `repo` scopes — your `gh auth token` output typically satisfies this
* Docker Engine, NVIDIA drivers, and `nvidia-container-toolkit` installed on the build host (see Step 1)

---

## **1. Prepare the build environment**

The HeavyAI build process requires a Linux host running Docker Engine with NVIDIA drivers and `nvidia-container-toolkit` installed. The build environment can be the same machine that will run HeavyAI in production, or any separate system that meets these requirements — including a dedicated build server or a cloud VM.--

> **Pre-open source release:** use `heavyai/heavydb-internal` instead of `heavyai/heavydb` wherever the repository name appears in this guide.

Install the following on your Linux build host using the official documentation for each:

* [Docker Engine](https://docs.docker.com/engine/install/ubuntu/) — install and configure Docker Engine on Ubuntu
* [NVIDIA drivers](https://docs.nvidia.com/datacenter/tesla/driver-installation-guide/) — datacenter and GPU driver installation guide
* [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) — enables GPU access inside Docker containers

Additionally, if this is the first time you’re installing NVIDIA HeavyAI on the machine, please install the following Docker configuration, by writing the following into `/etc/docker/daemon.json`

```json
{
    "default-runtime": "nvidia",
    "exec-opts": ["native.cgroupdriver=cgroupfs"], 
    "runtimes": {
        "nvidia": {
            "args": [],
            "path": "nvidia-container-runtime"
        }
    }
}
```

After installing this configuration, restart Docker with this command:\
`sudo systemctl restart docker`

**Verification**\
Once all three are installed, confirm the GPU passthrough is working: `docker run --rm nvidia/cuda:12.0-base nvidia-smi`. If it prints your GPU details, the environment is ready.

---

## **2. Clone the repository**

Clone `heavyai/heavydb` to your build machine and enter the project directory:

```
gh repo clone heavyai/heavydb
cd heavydb
```

> **Note:** This repository requires a GitHub account with access to the HeavyAI organization. Ensure `gh auth login` has been run and your token has `read:packages` + `repo` scopes.

---

## **3. Pull the build container**

The HeavyAI build system compiles all components inside a deps container, ensuring a consistent toolchain regardless of what is installed on the host. Pull the deps image for your target distribution before building, executing the below in your heavydb (or heavydb-internal) cloned repository folder:

```
# Ubuntu 22.04 (default and recommended)
dev-tools/dev.sh build deps --distro=ubuntu22.04
```

Other supported distributions:

```
# Rocky Linux 8
dev-tools/dev.sh build deps --distro=rockylinux8
```

> **Note:** Pulling the deps image is a one-time operation per distro. Building the deps image from scratch (if no pre-built image is available) is a multi-hour process; pulling a pre-built image from GHCR is the expected workflow. The build system auto-detects the local deps image on subsequent runs and prefers Ubuntu over Rocky when multiple images are present. Override with `--deps-image=<image>` if needed.

---

## **4. Obtain API keys**

Immerse requires two API keys for map chart functionality. These are passed as environment variables at build time — they are baked into the Immerse artifact during compilation and never written to a config file on disk.

* **Mapbox** — basemap tiles for pointmap, choropleth, linemap, and other geo charts
* **Google Maps Geocoding** — powers the zoom-to address search box on map charts

### **4a. Create a Mapbox access token**

1. Sign in at [account.mapbox.com](https://account.mapbox.com/).
2. Open **Tokens → Create a token** and give it a descriptive name.
3. Use a **public** token (begins with `pk.`). Do not use a secret `sk.` token — Immerse runs in the browser.
4. Enable at minimum these scopes: `STYLES:READ`, `STYLES:TILES`, `FONTS:READ`, `DATASETS:READ`. `DATASETS:READ` is only required if you use custom Mapbox Studio styles.
5. Optionally add URL restrictions to limit where the token can be used:

```
http://YOUR_HEAVYAI_HOST:6273/*https://YOUR_HEAVYAI_HOST/*
```

6. Copy the token — you will need it in Step 5.

> **Warning:** Mapbox charges per map load and tile request beyond the free tier. URL restrictions and your own token are strongly recommended over any shared or vendor-supplied default.

### **4b. Create a Google Maps Geocoding API key**

1. Open [Google Cloud Console](https://console.cloud.google.com/) and create or select a project.
2. Go to **APIs & Services → Library**, search for **Geocoding API**, and enable it.
3. Go to **APIs & Services → Credentials → Create credentials → API key**.
4. Copy the key.
5. Apply key restrictions if desired or required by your IT policy. Note that because this key is used directly within the end user's browser, any IP-based restrictions must account for the full range of your users' client IP addresses rather than server IPs.
   * Under **Application restrictions**, HTTP referrer restrictions are generally preferable to IP restrictions for browser-side keys:

```
http://YOUR_HEAVYAI_HOST:6273/*https://YOUR_HEAVYAI_HOST/*
```

* Under **API restrictions**, limit to **Geocoding API** only.

6. Ensure billing is enabled on the project. Google requires this even when usage stays within the free credit tier.

---

## **5. Build the Docker image**

With both keys ready, run the full build from inside the `heavydb` directory. Pass the API keys as environment variables alongside your GitHub token — this keeps credentials out of any config file on disk.

```
MAPBOX_TOKEN=pk.xxx \
GOOGLE_API_KEY=your-google-key \
PRIVATE_PACKAGES_TOKEN=$(gh auth token) \
  dev-tools/dev.sh build all --docker
```

> **Pre-open source release:** `PRIVATE_PACKAGES_TOKEN=$(gh auth token)` is required to access private npm packages used during the Immerse build. This token requirement will be removed once the repository is public.

Replace `pk.xxx` with your Mapbox public token and `your-google-key` with your Google Geocoding API key from Step 4.

This builds all components and packages them into a single Docker image:

| Component    | Description                    |
| ------------ | ------------------------------ |
| `Immerse`    | Frontend map and chart UI      |
| `WebServer`  | HeavyAI web server             |
| `HeavyIQ`    | AI query assistant             |
| `GEOS DSOs`  | Geometry shared libraries      |
| `HeavyDB`    | Core database engine           |
| Docker image | Final packaged container image |

Build output is written to `build/ubuntu22.04/logs/`. If a step fails, the last 50 lines of the relevant log are printed automatically. You can also tail a log directly:

```
# Watch the heavydb build log in real time
tail -f build/ubuntu22.04/logs/heavydb.log
```

---

## **6. Confirm the image**

Once the build completes, confirm that the new HeavyAI product image was created:

```
docker image ls
```

You should see two new images. For example:

```
REPOSITORY                              TAG       IMAGE ID       CREATED        SIZE
heavyai-ubuntu22.04-cuda-render-x86_64  10.0.0    3f9a1c2d8e4b   2 minutes ago  18.3GB
ghcr.io/heavyai/heavydb/core-build-...  latest    7a2b4d6e8f1c   3 days ago     12.1GB
```

> **Warning:** The image whose name begins with `core-build-` is the **build container** used to compile HeavyAI — it does not run HeavyAI. Only the product image (e.g. `heavyai-ubuntu22.04-cuda-render-x86_64:10.0.0`) should be deployed to your production environment.

Note the full product image name and tag from your output — you will need it in Step 7.

---

## **7. Deploy to your production environment**

Update your existing `docker-compose.yml` with the new image name, then start the service. If you built on a separate machine from where HeavyAI will run, you'll also need to export and transfer the image first.

### **Update docker-compose.yml**

Open your existing `docker-compose.yml` and update the `image:` field for the HeavyAI service to match the product image name from Step 6:

```

services:
  heavyai:
    image: heavyai-ubuntu22.04-cuda-render-x86_64:10.0.0
    devices:
      - nvidia.com/gpu=all
    # ... rest of your existing service configuration
services:
  heavyai:
    image: heavyai-ubuntu22.04-cuda-render-x86_64:10.0.0
    # ... rest of your existing service configuration
```

> **Note:** Only the `image:` value needs to change — all other settings in your `docker-compose.yml` (volumes, ports, environment, restart policy) can remain as-is.

If you built on the same machine where HeavyAI runs, apply the updated compose file and start the service now:

```
docker compose up -d
```

### **Export and transfer to production**

Skip this section if the build machine is the same as the production host. Otherwise, save the image to a compressed archive and transfer it along with the updated `docker-compose.yml` using `rsync`.

On the **build machine**:

```
# Export the image to a compressed archive
docker save heavyai-ubuntu22.04-cuda-render-x86_64:10.0.0 \
  | gzip > heavyai-ubuntu22.04-cuda-render-x86_64-10.0.0.tar.gz

# Transfer the image and updated compose file to the production host
rsync -avz --progress \
  heavyai-ubuntu22.04-cuda-render-x86_64-10.0.0.tar.gz \
  docker-compose.yml \
  user@YOUR_HEAVYAI_HOST:/opt/heavyai/
```

On the **production host**:

```
# Load the image into Docker
docker load < /opt/heavyai/heavyai-ubuntu22.04-cuda-render-x86_64-10.0.0.tar.gz

# Start the service
cd /opt/heavyai
docker compose up -d
```

> **Note:** A full HeavyAI image is typically 15–20 GB uncompressed. Ensure sufficient disk space on both machines before exporting. The `--progress` flag on `rsync` will show live transfer throughput.

---

## **8. Verify the installation**

Open a browser and navigate to your HeavyAI host on port 6273:

```
http://YOUR_HEAVYAI_HOST:6273
```

Then perform the following checks to confirm maps and geocoding are working correctly:

1. Log in and create a new dashboard.
2. Add a new chart and select **Choropleth** as the chart type.
3. **Basemap tiles:** the map background should render fully with no gray or blank tiles. Open browser DevTools → **Network** and confirm Mapbox tile requests return HTTP 200 with your `access_token` query parameter present. Any 401 responses indicate the `MAPBOX_TOKEN` was missing or invalid at build time.
4. **Geocoder:** locate the zoom-to search box in the chart toolbar. Type a city name (e.g. *Austin*) and confirm the map pans and zooms to that location. In DevTools → Network, Geocoding API requests should return 200 with your `key` parameter present.
5. Save the dashboard. Reload the page and confirm the choropleth and basemap render correctly on load.

> **Note:** If the zoom-to search box is not visible, check that `ui/disable_map_geocoder` is not set to `true` in your `feature_flags` configuration.

---

## **9. Initial configuration (optional)**

If you are configuring a fresh HeavyAI environment rather than upgrading an existing one, consider completing the following before going live. None of these are required for a functional installation, but all are strongly recommended for security and usability.

### **Change the admin password**

Log in to Immerse as `admin` using the default password (`HyperInteractive`), then navigate to **Admin Portal → Users → admin → Edit** to set a new password. Alternatively, use `heavysql` directly:

```
docker compose exec heavyai \
  /opt/heavyai/bin/heavysql \
  -u admin -p HyperInteractive \
  --db heavyai \
  -c "ALTER USER admin (password='your-new-password');"
```

### **Configure servers.json**

Immerse's default connection behavior, feature flags, UI element visibility, and branding are all controlled through a `servers.json` file. This file must be referenced from `heavy.conf` and placed in your `HEAVYAI_STORAGE` directory.

**Step 1:** In the `[web]` section of `heavy.conf`, add:

```
[web]
servers-json = "/var/lib/heavyai/servers.json"
```

**Step 2:** Create `servers.json` in your storage directory. At minimum, set the default database connection. You can also pre-populate credentials to enable automatic login:

```
[
  {
    "database": "heavyai",
    "host": "localhost",
    "port": "6273",
    "protocol": "http",
    "username": "admin",
    "password": "your-admin-password"
  }
]
```

> **Warning:** Storing a password in `servers.json` enables auto-login for all users arriving at the Immerse URL. Only do this in controlled environments where access to the URL is already restricted. Omit `"password"` to present the login form instead.

#### **Feature flags**

The `feature_flags` object inside `servers.json` controls global Immerse UI defaults. Common settings for a new deployment:

```
"feature_flags": {
  "ui/default_theme": "dark",
  "ui/dashboard_tabs": true,
  "ui/enable_auto_dashboard_refresh": true,
  "ui/enable_map_exports": true,
  "ui/enable_joins": true
}
```

See the [full feature flags reference](https://docs.nvidia.com/heavyai/immerse/customization#feature-flags) for all available options.

#### **Controlling UI visibility with immerse\_ui\_keys**

Use `immerse_ui_keys` to show or hide parts of the Immerse interface. For example, to hide the help dropdown and data manager while keeping everything else visible:

```
"immerse_ui_keys": {
  "default": "ALL",
  "ui_off": ["help_dropdown", "data_manager"]
}
```

To start from a blank slate and only expose specific elements:

```
"immerse_ui_keys": {
  "default": "NONE",
  "ui_on": ["tabs", "sql_editor", "global_side_nav", "dashboards", "save", "refresh"]
}
```

See the [full UI keys reference](https://docs.nvidia.com/heavyai/immerse/customization#immerse-user-interface-keys) for all available key values.

#### **Branding and custom styles**

Use the `customStyles` object to add your own logo, login page text, browser tab title, and chart color palettes:

```
"customStyles": {
  "logoURL": "https://YOUR_HEAVYAI_HOST/your-logo.png",
  "darkThemeLogoURL": "https://YOUR_HEAVYAI_HOST/your-logo-dark.png",
  "loginText": "Welcome to Your Organization",
  "title": "Your Organization Analytics",
  "disableHelpMenu": false
}
```

Logo URLs must be browser-accessible `http(s)` URLs — filesystem paths are not supported. See the [full branding reference](https://docs.nvidia.com/heavyai/immerse/customization#json-branding-elements) for color palette options (`solid`, `ordinal`, `quantitative`, `custom`).

#### **Custom basemap styles**

To use Mapbox Studio styles or third-party OGC-compliant raster tile sources as basemaps in geo charts, add the `mapboxCustomStyles` array:

```
"mapboxCustomStyles": [
  {
    "label": "My Mapbox Studio Style",
    "value": "mapbox://styles/username/style-id",
    "default": true
  },
  {
    "label": "OpenStreetMap",
    "value": {
      "version": 8,
      "sources": {
        "osm": {
          "type": "raster",
          "tiles": ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"],
          "tileSize": 256
        }
      },
      "layers": [{"id": "osm", "type": "raster", "source": "osm"}]
    }
  }
]
```

Setting `"default": true` on a style makes it the initial basemap shown in new geo charts. See the [full basemap styles reference](https://docs.nvidia.com/heavyai/immerse/customization#enable-custom-basemap-styles-for-geo-charts) for more detail.

After creating or modifying `servers.json` or `heavy.conf`, restart the service for changes to take effect:

```
docker compose restart heavyai
```

### **Enable TLS termination**

If HeavyAI is exposed directly (not behind a TLS-terminating load balancer or reverse proxy), configure HTTPS in the `[web]` section of `heavy.conf`:

```
[web]
enable-https = true
https-cert = /var/lib/heavyai/certs/cert.pem
https-key  = /var/lib/heavyai/certs/key.pem
```

Mount the certificate directory into the container via your `docker-compose.yml`:

```
services:
  heavyai:
    volumes:
      - /path/to/certs:/var/lib/heavyai/certs:ro
      # ... your other volume mounts
```

> **Note:** If nginx, Traefik, or a cloud load balancer is already terminating TLS in front of HeavyAI, skip this step. Enabling TLS inside the container when it is already terminated upstream will cause connection errors.

Restart the service after any changes to `heavy.conf`:

```
docker compose restart heavyai
```

---

## **Troubleshooting**

| Symptom                                    | Likely cause                                                                                                                                                                   |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `gh repo clone` fails                      | Your GitHub account doesn't have access to `heavyai/heavydb`, or `gh auth login` hasn't been run.                                                                              |
| Deps container not found                   | The `build deps` step in Step 3 may not have completed. Re-run `dev-tools/dev.sh build deps --distro=ubuntu22.04`, or use `--deps-image=<image>` to specify an image manually. |
| No product image after build               | The build may have failed silently. Check `build/ubuntu22.04/logs/docker-build.log`. Ensure `--docker` was included in the build command.                                      |
| Deployed the wrong image                   | Ensure the `image:` in `docker-compose.yml` matches the product image (e.g. `heavyai-ubuntu22.04-cuda-render-x86_64:10.0.0`), not the `core-build-*` build container.          |
| Blank or gray map                          | `MAPBOX_TOKEN` was missing or invalid at build time, token URL restrictions block the production host, or a Mapbox billing or scope issue.                                     |
| Zoom-to does nothing                       | `GOOGLE_API_KEY` was missing at build time, Geocoding API not enabled, referrer or IP restrictions too tight, or billing disabled on the Google project.                       |
| No zoom-to search box                      | `ui/disable_map_geocoder` is set to `true` in `feature_flags`.                                                                                                                 |
| HTTPS connection errors after enabling TLS | TLS may already be terminated upstream. Disable `enable-https` in `heavy.conf` if a proxy or load balancer handles SSL in front of HeavyAI.                                    |

### **Offline / no third-party API alternatives**

* **No Mapbox:** omit `MAPBOX_TOKEN` at build time and set `"offline": true` in `servers.json` to use built-in country-outline basemaps instead.
* **No Google geocoding:** omit `GOOGLE_API_KEY` at build time and set `"ui/enable_local_geocoder": true` in `feature_flags` to use the HeavyAI `/geocoder` endpoint (requires server-side geocoder support).

---

## **References**

* [Docker Engine installation — Ubuntu](https://docs.docker.com/engine/install/ubuntu/)
* [NVIDIA driver installation guide](https://docs.nvidia.com/datacenter/tesla/driver-installation-guide/)
* [NVIDIA Container Toolkit installation guide](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
* [HeavyAI Immerse customization guide](https://docs.nvidia.com/heavyai/immerse/customization) — servers.json reference, feature flags, UI keys, branding, custom basemaps
* [HeavyAI web server configuration parameters](https://docs.nvidia.com/heavyai/installation-and-configuration/config-parameters/configuration-parameters-for-heavy.ai-web-server)
* [HeavyDB configuration parameters](https://docs.nvidia.com/heavyai/installation-and-configuration/config-parameters/configuration-parameters-for-heavydb)
* [Mapbox access tokens](https://docs.mapbox.com/help/diagnostics/how-to-use-mapbox-tokens/)
* [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding/overview)