Docs

Install in an Air-Gapped Environment

Mirror every artifact API7 Gateway needs into your own registry, activate a licence without egress, and keep upgrades working offline.

API7 Gateway runs without internet access, but only if you mirror the right things first. This page is the complete artifact list and the offline path for each install method, so that the first time you discover a missing image is not during a change window inside the isolated network.

Nothing in the product calls home for licence validation — activation is a file upload, and it works offline.

What has to cross the boundary

Four categories. Miss any one and the install stops partway.

CategoryItems
Container imagesSee the table below
Helm chartsapi7/api7ee3 (control plane) and api7/gateway (data plane), or the RPM bundle instead
The licence fileOne file, uploaded once
ADC binaryOnly if you manage configuration declaratively

Container images

Taken from the shipped charts at chart api7ee3-3.10.10 and gateway-3.10.15 (application version 3.10.7), except the Developer Portal frontend, which those charts do not deploy:

ImageNeeded for
api7/api7-ee-3-integrated:v3.10.7Dashboard and Admin API
api7/api7-ee-dp-manager:v3.10.7DP Manager — the configuration channel data planes connect to
api7/api7-ee-3-gateway:3.10.7Data plane. Note the tag has no v prefix, unlike the control-plane images
api7/api7-ee-developer-portal:v3.10.7Portal API backend, when the Developer Portal is enabled
api7/api7-ee-developer-portal-fe:v0.15.3Portal frontend, deployed with its own manifests rather than by the api7ee3 chart — see Deploy the Developer Portal. Versioned independently of everything else
api7/postgresql:15.4.0-debian-11-r45Only if you use the chart's built-in PostgreSQL rather than your own
api7/prometheus:2.48.1-debian-11-r0Only if you use the bundled Prometheus
jaegertracing/jaeger:2.14.1Only if you enable the bundled tracing backend
api7/openapi-to-mcpOnly if you expose REST APIs as MCP tools

All API7 images publish linux/amd64 and linux/arm64, so an arm64 target needs no special handling.

Derive the list yourself rather than trusting a table that will age — render the charts and read the images out:

helm template api7ee3 api7/api7ee3 --version 3.10.10 \
  | grep -oE 'image: *"?[^"]+' | sed 's/image: *"*//' | sort -u
helm template gateway api7/gateway --version 3.10.15 \
  | grep -oE 'image: *"?[^"]+' | sed 's/image: *"*//' | sort -u

Run this against the exact chart versions you intend to deploy, with the same --set values you will use — disabling the built-in PostgreSQL or the Developer Portal removes images from the list.

Step 1: Mirror the images

On a machine with internet access:

export REGISTRY=registry.internal.example.com/api7
export IMAGES="api7/api7-ee-3-integrated:v3.10.7
api7/api7-ee-dp-manager:v3.10.7
api7/api7-ee-3-gateway:3.10.7"

for img in ${IMAGES}; do
  docker pull "${img}"
  docker tag  "${img}" "${REGISTRY}/${img##*/}"
  docker push "${REGISTRY}/${img##*/}"
done

If the two networks are fully separated, save to files and carry them across instead:

docker save ${IMAGES} -o api7-images.tar
# ...transfer...
docker load -i api7-images.tar

Pin by digest for anything you must reproduce. Tags are mutable, and the gateway chart sets imagePullPolicy: Always, so the same tag can resolve to a different artifact on a later rollout. Record the digest at mirror time:

docker buildx imagetools inspect api7/api7-ee-3-gateway:3.10.7 --format '{{.Manifest.Digest}}'

Step 2: Mirror the charts

helm repo add api7 https://charts.api7.ai
helm repo update
helm pull api7/api7ee3 --version 3.10.10
helm pull api7/gateway --version 3.10.15

Transfer the resulting .tgz files and either install from them directly or push them to an internal OCI registry:

helm install api7ee3 ./api7ee3-3.10.10.tgz -f cp-values.yaml -n api7

Point the images at your mirror in the values file:

cp-values.yaml
dashboard:
  image:
    repository: registry.internal.example.com/api7/api7-ee-3-integrated
    tag: v3.10.7
dp_manager:
  image:
    repository: registry.internal.example.com/api7/api7-ee-dp-manager
    tag: v3.10.7

If your registry needs credentials, create a pull secret in the namespace and reference it — the charts accept imagePullSecrets.

Step 3: Activate the licence offline

Licence activation needs no outbound connectivity. Obtain the licence file on a connected machine, carry it in, and upload it.

Through the Dashboard, the first login prompts for it. Through the Admin API:

curl -k "https://localhost:7443/api/license" -X PUT \
  -H "X-API-KEY: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d "$(jq -Rs '{data: .}' < api7-ee-license)"

Validate before applying, which parses the licence and reports its entitlements without activating it:

curl -k "https://localhost:7443/api/license?dry-run=all" -X PUT \
  -H "X-API-KEY: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d "$(jq -Rs '{data: .}' < api7-ee-license)"

For a GitOps-managed install, mount the licence as a Secret and point the control plane at the file instead — it polls for changes every five seconds:

cp-values.yaml
dashboard_configuration:
  license:
    file_path: "/etc/api7/license.txt"

See License Management.

Step 4: Bare metal without containers

If containers are not permitted at all, the offline RPM bundle installs the control plane from a single archive with no registry involved. Note that only one 3.10 patch release is published as an RPM bundle, so the RPM path and the container path are not on the same version cadence. See Deploy with the Offline RPM Bundle.

What still needs deliberate handling

  • The model-pricing catalogue and other outbound features. Anything that fetches from a third party at runtime has to be either disabled or pointed at an internal mirror. Audit outbound destinations against Ports and Endpoints before go-live.
  • Plugin dependencies. A custom Lua plugin that pulls a LuaRocks dependency at build time needs that dependency vendored — see Develop Custom Lua Plugins.
  • ADC. Download the binary on the connected side and carry it in; pin the version so a pipeline cannot change behaviour. See Manage Gateway Configuration with GitOps.
  • Upgrades. Every upgrade repeats steps 1 and 2 for the new versions. Mirror the new images and charts before starting the upgrade, and check the chart-to-application version mapping — chart 3.10.10 ships application 3.10.7, so the numbers do not match and cannot be inferred.
  • Support bundles. Diagnostics collected inside the enclave have to be carried out the same way they came in.

Validate

Before declaring the environment ready, confirm nothing reaches for the internet:

kubectl -n api7 get pods -o jsonpath='{range .items[*].spec.containers[*]}{.image}{"\n"}{end}' | sort -u

Every image should carry your registry prefix. An image still showing docker.io/ or a bare api7/ name is one your mirror missed, and it will fail on the next pull — not necessarily today, since a cached image keeps working until the node is replaced.