Air-gap deployment
Reference for running Prelude Collector on disconnected networks - image transfer, offline licensing, and internal mirror options.
This page is the operational reference for running Prelude Collector on networks with no outbound internet access. It describes the shape of an air-gapped install - what moves across the boundary, what stays on the host, and which mirror options exist - rather than the step-by-step.
For a guided walkthrough, follow the Air-gapped install tutorial.
What changes in air-gap
Once installed, the collector itself does not require internet access. It speaks to your devices, your PostgreSQL, your NATS, and exposes its own API and metrics endpoints. Three things normally need egress, and you have to plan for each one explicitly:
- Container image pulls - solved by transferring the image archive across the air-gap once, and re-importing for updates.
- License activation - solved by an offline license file issued for the specific host. See Licensing.
- Optional model downloads - YANG models and vendor MIBs ship
inside the image. If you keep your own internal copies for
custom models, those load from the storage volume at
/app/storage.
The collector image is self-contained: it embeds default OpenConfig YANG models, vendor MIBs for common platforms, and all static assets, so a fresh install does not need to fetch anything after pull.
Image transfer
The standard pattern is to pull the image on a connected workstation and move an archive across your transfer mechanism (USB, write-once media, one-way diode, file-drop server).
On the connected side:
docker pull registry.arolo-solutions.com/prelude/prelude-collector:1.0.0
docker save registry.arolo-solutions.com/prelude/prelude-collector:1.0.0 \
-o prelude-collector.tar
sha256sum prelude-collector.tar > prelude-collector.tar.sha256
The collector image is published to the public registry
registry.arolo-solutions.com/prelude/prelude-collector. The
examples use the :1.0 tag, the current stable release.
Move both files across the air-gap, verify the checksum, then load on the disconnected host:
sha256sum -c prelude-collector.tar.sha256
docker load -i prelude-collector.tar
For Podman, substitute podman save and podman load.
If you also need an updated PostgreSQL or NATS image, repeat the
same save / load cycle for those tags.
Internal registry mirror
If you operate an internal OCI registry (Harbor, GitLab Registry, Nexus, an Artifactory OCI repository, or similar), you can avoid the tar-file shuffle by mirroring the collector image into it once and pulling from inside the air-gapped network from then on.
The shape:
-
On the connected side, retag the image to your internal registry hostname and push:
docker pull registry.arolo-solutions.com/prelude/prelude-collector:1.0.0 docker tag registry.arolo-solutions.com/prelude/prelude-collector:1.0.0 \ internal-registry.example.com/prelude/prelude-collector:1.0.0 docker push internal-registry.example.com/prelude/prelude-collector:1.0.0
-
On the air-gapped hosts, point Compose or Quadlet at the internal registry and pull from there:
services: collector: image: internal-registry.example.com/prelude/prelude-collector:1.0.0
-
Repeat the retag-and-push for each updated tag you ship through your release process.
This pattern scales better than save / load once you have more
than a handful of hosts, and it lets you apply image-scanning and
retention policies inside your own network.
Offline licensing
Air-gapped collectors cannot phone home for license validation, so licensing happens with a file. Request the license from your support contact with the air-gapped hostname and any deployment-scope details, copy the file to the host, and load it with the collector CLI. The full procedure - including the exact command and where to place the file - is documented in Licensing.
PostgreSQL and NATS
Both PostgreSQL and NATS run as standard upstream containers; you do not need a special air-gap variant. Pull each from your internal mirror, or transfer them as tar archives the same way as the collector image.
The collector talks to both over the cluster's internal network -
nothing about the air-gap changes the
Configuration reference values. Inside a Compose
or Podman network, services resolve each other by name: PostgreSQL
as postgres, NATS as nats://nats:4222.
Updates
Updates in an air-gap follow the same model as the initial install. Either:
- Save the new image tag on the connected side, transfer the
archive, and
docker load/podman loadit on the air-gapped host, thendocker compose up -d collectorto recreate the container. Or: - Mirror the new tag into your internal registry, then pull from the air-gapped host as usual.
Migrations run automatically on startup (COLLECTOR_AUTO_MIGRATE
defaults to true). If you set it to false, apply them after an
update:
docker compose exec collector ./prelude-collector migrate up
Migrations are idempotent.
Verification checklist
After installing on an air-gapped host, confirm:
- The collector container is running and listening on
4030. docker compose logs collectorshows no outbound connection errors.- The license loaded successfully (visible in the collector logs and in the web UI).
- The API responds to a
Bearertoken request on port4030. See the API reference linked from Getting Started for the exact endpoints.
See also
- Air-gapped install tutorial - the step-by-step walkthrough.
- Docker deployment - everything that's the same once the image is on the host.
- Podman deployment - rootless and Quadlet specifics.
- Configuration reference - every
COLLECTOR_*environment variable. - Licensing - offline license flow.