Air-Gapped Deployment#
Alpamayo1.5 NIM can run without outbound network access after its container image and one model profile have been staged on an internet-connected system. Use the same NIM image digest and GPU class on the connected and disconnected systems.
Prepare the Offline Cache#
On an internet-connected system with a supported GPU, authenticate to NGC and
create a local-disk cache that the container user (UID 1000) can write:
export IMG_NAME=nvcr.io/nim/nvidia/alpamayo1.5:1.0.0
export LOCAL_NIM_CACHE=/tmp/alpamayo-airgap-cache
export PROFILE_NAME=fp8
mkdir -p "$LOCAL_NIM_CACHE"
chmod 777 "$LOCAL_NIM_CACHE"
echo "$NGC_API_KEY" | docker login nvcr.io \
--username '$oauthtoken' --password-stdin
docker pull "$IMG_NAME"
List the profiles compatible with the connected system. The command writes machine-readable output into the mounted cache:
docker run --rm --runtime=nvidia --gpus '"device=0"' \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
"$IMG_NAME" list-model-profiles \
--output-format json \
--output-file /opt/nim/.cache/profiles.json
Select a compatible profile by its profile_name tag. The following command
selects the precision in PROFILE_NAME and fails if it is not compatible:
export NIM_MODEL_PROFILE="$(python3 -c '
import json, sys
data = json.load(open(sys.argv[1], encoding="utf-8"))
matches = [p["profile_id"] for p in data["compatible"]
if p["tags"].get("profile_name") == sys.argv[2]]
if len(matches) != 1:
raise SystemExit(f"expected one compatible {sys.argv[2]} profile, got {len(matches)}")
print(matches[0])
' "$LOCAL_NIM_CACHE/profiles.json" "$PROFILE_NAME")"
Download that exact profile without starting the inference server:
docker run --rm --runtime=nvidia --gpus '"device=0"' \
-e NGC_API_KEY="$NGC_API_KEY" \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
"$IMG_NAME" download-to-cache \
--profiles "$NIM_MODEL_PROFILE"
Package the image, cache, and selected profile ID for transfer through your approved media or artifact process:
docker save "$IMG_NAME" --output alpamayo-nim-image.tar
tar -C "$LOCAL_NIM_CACHE" -czf alpamayo-nim-cache.tgz .
printf '%s\n' "$NIM_MODEL_PROFILE" > alpamayo-profile-id.txt
docker image inspect "$IMG_NAME" --format '{{index .RepoDigests 0}}' \
> alpamayo-image-digest.txt
Start on the Air-Gapped System#
Transfer the four generated files to the disconnected system. Load the image and restore the writable cache:
export IMG_NAME=nvcr.io/nim/nvidia/alpamayo1.5:1.0.0
export AIR_GAP_NIM_CACHE=/tmp/alpamayo-airgap-cache
export NIM_MODEL_PROFILE="$(cat alpamayo-profile-id.txt)"
docker load --input alpamayo-nim-image.tar
mkdir -p "$AIR_GAP_NIM_CACHE"
chmod 777 "$AIR_GAP_NIM_CACHE"
tar -C "$AIR_GAP_NIM_CACHE" -xzf alpamayo-nim-cache.tgz
Create an internal Docker network, which permits host-to-container port publishing but has no external route, and start the NIM on that network:
docker network inspect alpamayo-airgap >/dev/null 2>&1 || \
docker network create --internal alpamayo-airgap
docker run -it --rm --name alpamayo1.5 \
--network alpamayo-airgap \
--runtime=nvidia \
--gpus '"device=0"' \
--shm-size=16g \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
-e NIM_MODEL_PROFILE="$NIM_MODEL_PROFILE" \
-v "$AIR_GAP_NIM_CACHE:/opt/nim/.cache" \
-p 8000:8000 \
-p 50051:50051 \
"$IMG_NAME"
NGC_API_KEY is not required when the complete profile is cached. If your
deployment platform injects the key, it can remain present; the internal
Docker network is the isolation control that prevents outbound access.
The cache must remain writable because startup can create profile-specific patched model metadata and local runtime artifacts. A read-only cache is not supported.
Verify the Deployment#
From the disconnected host, verify readiness and model metadata:
curl --fail http://localhost:8000/v1/health/ready
curl --fail http://localhost:8000/v1/models
If startup attempts an NGC download, confirm that NIM_MODEL_PROFILE exactly
matches the staged profile ID, the complete cache was transferred, and the
cache is mounted at /opt/nim/.cache.