Skip to content

Air-gapped / on-prem

Ongrid ships as one self-contained tarball precisely so it works offline. There is no apt install, no Go-module-fetch-at-build-time on the target host, no Docker Hub pull at runtime. Drop the tarball, run install.sh, and you have a working manager + edge fleet.

The tradeoffs you will hit going air-gapped are around the LLM provider, the embedding model for RAG, and ongoing upgrades. This page is the checklist.

Step 1: Download the release tarball

From a host with internet, grab the latest release asset:

sh
gh release download v0.7.167 --repo ongridio/ongrid \
    --pattern 'ongrid-*-linux-amd64.tar.xz'
gh release download v0.7.167 --repo ongridio/ongrid \
    --pattern 'ongrid-*-linux-amd64.tar.xz.sha256'
sha256sum -c ongrid-v0.7.167-linux-amd64.tar.xz.sha256

Or build the tarball yourself with make package. Either way the artefact is a single .tar.xz plus its .sha256.

Move both files to the target host via whatever air-gap channel you use (sneakernet USB, internal artefact server, signed S3 bucket, etc.).

Step 2: Tarball install

The tarball expands to a self-contained directory:

text
ongrid-v0.7.167-linux-amd64/
  install.sh
  upgrade.sh
  docker-compose.yml
  images/
    ongrid.tar              # docker image, saved
    ongrid-web.tar
    frontier.tar
    mysql.tar               # bundled so no Docker Hub pull
    prometheus.tar
    loki.tar
    tempo.tar
    grafana.tar
    searxng.tar
  bin/
    linux-amd64/ongrid-edge
    linux-arm64/ongrid-edge
    darwin-amd64/ongrid-edge
    darwin-arm64/ongrid-edge
    linux-amd64/promtail
    linux-arm64/promtail
    linux-amd64/otelcol-contrib
    linux-arm64/otelcol-contrib
    linux-amd64/node_exporter
    linux-arm64/node_exporter
    linux-amd64/process_exporter
    linux-arm64/process_exporter
  edge/
    apply-pending-upgrade.sh
  .cache/
    bge-base-en-v1.5/       # optional offline RAG embedding model

Run:

sh
tar -xf ongrid-v0.7.167-linux-amd64.tar.xz
cd ongrid-v0.7.167-linux-amd64
sudo ./install.sh

install.sh loads every images/*.tar into the local docker, writes a sensible .env, brings the stack up with docker compose up -d, and prints the URL of the new manager. The host needs Docker Engine + Compose v2 — see Linux (server).

See Air-gapped install for the full step-by-step with checksums and first-boot.

Step 3: Mirror to a private registry (optional)

If you have a private container registry (Harbor / Artifactory / ECR / GCR), and you would rather docker pull than docker load, push the bundled images once:

sh
for img in images/*.tar; do
  name=$(docker load -i "$img" | awk -F': ' '/Loaded image/ {print $2}')
  registry_tag="registry.internal/${name}"
  docker tag "$name" "$registry_tag"
  docker push "$registry_tag"
done

Then write a docker-compose.override.yml that points each service at registry.internal/... instead of the original image, and you can deploy on N hosts without re-shipping the tarball. Future upgrades become "pull new image tag, docker compose up -d".

Step 4: Edge install in an air-gapped network

The curl-pipe installer (https://<manager>/install.sh | bash) works fine inside an air-gapped network as long as the edges can reach the manager (port 443 for the static bundle + port 40012 for the tunnel). The installer downloads the agent binary and the four plugin binaries from https://<manager>/edge/, which the manager's nginx serves from the bind-mounted ./bin/ directory.

If your edges cannot reach the manager over HTTPS — for example, edges are in a network segment that only allows port 40012 — copy the binaries by hand:

sh
# on each edge host
sudo install -m 0755 ongrid-edge /usr/local/bin/ongrid-edge
sudo mkdir -p /usr/local/lib/ongrid-edge
sudo install -m 0755 promtail otelcol-contrib node_exporter process_exporter \
    /usr/local/lib/ongrid-edge/
# then write /etc/ongrid-edge/ongrid-edge.env and the systemd unit
# (see deploy/install/edge/install.sh for the exact unit content)

Or, more robustly: stand up a tiny internal HTTPS mirror that holds a copy of ./bin/linux-*/ and point a forked install.sh at it.

Step 5: LLM provider

Ongrid does not bundle an LLM. The agent kernel calls an upstream provider — Anthropic, OpenAI, Zhipu, DeepSeek, Gemini, Kimi, or any OpenAI-compatible relay — over the manager's outbound internet connection. In an air-gapped network you have three options:

  1. Outbound proxy. Set HTTPS_PROXY=http://your-proxy:3128 in the manager's env block. All provider calls flow through the proxy.
  2. Self-hosted OpenAI-compatible relay. Run vLLM / TGI / Ollama / one-api inside your network, point ONGRID_OPENAI_BASE_URL at it, set ONGRID_OPENAI_API_KEY to whatever the relay expects. This is the most common pattern for fully-disconnected installs.
  3. Custom provider in the UI. Settings → Models → Custom (OpenAI-compatible) gives you the same wiring without a restart.

If you want to use Zhipu (GLM) against a Tencent Cloud-hosted endpoint inside China, set ONGRID_ZHIPU_BASE_URL to the regional endpoint and ONGRID_ZHIPU_API_KEY to your key — no proxy needed, GLM is reachable inside the China-mainland network.

Step 6: Offline RAG (the embedding model)

Knowledge-base ingestion needs an embedding model. By default the manager calls the GLM embedding API (embedding-3) which needs internet. For a fully offline deployment, switch to the local embedding profile:

sh
ONGRID_EMBEDDING_PROVIDER=local
ONGRID_EMBEDDING_LOCAL_MODEL_PATH=/var/lib/ongrid/embeddings/bge-base-en-v1.5

The release tarball ships the BAAI/bge-base-en-v1.5 model under .cache/bge-base-en-v1.5/ (~400 MB). The install script copies it into the named volume on first boot. If you skipped make fetch-embedding-model when building the tarball, the model is absent and embedding will fail — run that step once and re-package.

The default Ongrid built-in vault (github.com/ongridio/vault) is public and contains baseline runbooks shipped in the embedded RAG seed. Synchronising it requires reaching GitHub. In an air-gapped network you can:

  • Vendor the vault into your own internal Git server and update ONGRID_VAULT_REPO_URL.
  • Or, skip vault sync entirely — the embedded seed (about 96 playbooks) lives inside the binary and is always available.

Step 7: Upgrades

Two paths:

  1. Same tarball mechanism. Download the new tarball on an internet-connected host, sneakernet it over, run ./upgrade.sh. This is install.sh minus the bootstrap — image loading + docker compose up -d. The edge agents pick up the matching agent + plugin binaries the next time they reconnect (ADR-024 whole-bundle staging).
  2. Private registry pull. If you mirrored the images (Step 3), docker compose pull && docker compose up -d is enough. Edges still need the new agent + plugin binaries, which they fetch from the manager's /edge/ static path — that updates automatically when you swap the tarball-shipped bin/ directory.

What does NOT work air-gapped

  • Built-in vault auto-sync without a mirror — the vault repo lives on GitHub.
  • Provider's hosted LLMs without an outbound proxy or relay — there is no shipped local LLM.
  • The default GLM embedding profile — switch to local (see Step 6).
  • Public marketplace skill installs (ADR-017) — point at a private registry instead.

Everything else, including the full agent kernel, alert evaluator, telemetry pipeline, and chat UI, runs fully offline.