Skip to main content

Offline installation

This page installs navin-manager in a bank network without Internet access. The same steps work online: the only difference is where the artifacts come from.

1. Prerequisites​

ItemRequirement
Manager hostRHEL family 8, 9 or 10 (RHEL, Rocky Linux, AlmaLinux, Oracle Linux 8/9, CentOS Stream 9/10) with python3.12, or Ubuntu 24.04 with python3.12. Ubuntu 22.04 is a managed host only: it provides no maintained Python 3.11 or newer. 4 CPU, 8 GB of memory, 50 GB for the mirror.
Managed hostsCertified systems: RHEL 8/9/10, Rocky Linux 8/9/10, AlmaLinux 8/9/10, Oracle Linux 8/9, CentOS Stream 9/10, Ubuntu 22.04/24.04, Debian 12, Arch Linux (rolling). A newer release of these families (for example Ubuntu 26.04, Debian 13, Oracle Linux 10) or a derivative of Arch Linux (Manjaro, EndeavourOS) passes the preflight with a warning; an end of life release (CentOS 7 and 8, RHEL 7, Ubuntu 20.04 and older, Debian 11 and older) or another family is blocked. x86_64 or aarch64. Python 3.9 or later, openssl, tar, a synchronized clock (chronyd or systemd-timesyncd). Podman 4 or later for the podman method. Host firewall: the agent opens the public ports with firewalld or ufw; with your own nftables or iptables ruleset, open the ports the installation preflight lists.
Manager databasePostgreSQL 14 or later run by the bank in its own cluster, a database navin_manager, a role navin_manager owning it, TLS with the CA of the bank.
CertificatesA server certificate for the manager host (bank PKI), with the DNS name used by operators and agents.
NetworkOperators to the manager on 8460/tcp; managed hosts to the manager on 8460/tcp (registration) and 8461/tcp (agent API and mirror). Nothing opens towards managed hosts.

2. Build the offline bundle (outside the bank)​

On a build host connected to the Internet, from a checkout of navin-manager:

navin-manager/server/.venv/bin/python navin-manager/packaging/offline/build-bundle.py \
--catalog navin-manager/catalog --out /srv/navin-bundle/mirror \
--services all --methods binary,podman,python --arch x86_64 --python-versions 3.9,3.11,3.12 \
--gpg-key release@bank.example

The builder downloads every artifact named by the catalog, checks it against the checksum file published by its project, saves the container images with podman save and records their digests, downloads the Python wheels, and writes manifest.json with the sha256 of every file. An artifact without an upstream checksum is refused unless --trust-on-first-download is given; the manifest then records that choice for the entry. The result is bundle.tar, bundle.tar.sha256 and, with --gpg-key, a detached signature.

Behind a corporate proxy, set NM_MIRROR_PROXY=http://proxy.bank.example:3128 (and NM_MIRROR_NO_PROXY with the hosts reached directly, for example nexus.bank.example,.bank.internal) or pass --proxy and --no-proxy. The proxy carries the artifact and checksum downloads, pip download and podman pull; without it the standard https_proxy and no_proxy variables apply. The agents and the Manager never use a proxy: they talk to each other directly.

For hosts without access to a package repository, add --os-repo (with --gpg-key), and the package method when it is used, on a machine of the release of the hosts (for example Ubuntu 24.04):

navin-manager/server/.venv/bin/python navin-manager/packaging/offline/build-bundle.py \
--catalog navin-manager/catalog --out /srv/navin-bundle/mirror \
--services all --methods binary,podman,python,package --os-repo \
--gpg-key release@bank.example

The builder then adds in os/<id>-<release>-<arch>/ a signed repository of the system packages the chosen methods need: podman (with uidmap on Debian and Ubuntu), tar, every Python interpreter and its venv module, the packages of the package method and those of --os-packages, with all their dependencies for a minimal host. On the Debian family InRelease is signed and the index gives the sha256 of every package; on the RHEL family repodata/repomd.xml.asc signs the index and every package keeps the signature of its publisher, checked by rpmkeys --checksig during the build. For another release of the hosts (for example RHEL 9), copy the --out directory to a machine of that release and run the builder again with the same --out: the intact repositories of the earlier runs are kept. --os-apt-option and --os-dnf-option name the sources of the downloads, for example the internal mirror of the bank. Once the mirror is loaded, the agent of a host of that release installs the prerequisites and the packages of the package method from this repository alone, never disabling a signature check; a host of another release, or a package the repository lacks, goes through the repositories configured on the host.

The agent packages recommend podman (and uidmap on Debian and Ubuntu): apt and dnf install them with the agent when the repositories of the host carry them. An agent without root (sandbox) installs no system package: the validation of a podman installation then gives the command to run on the host.

Build the packages of navin-manager and of the agent with navin-manager/packaging/build-packages.sh (see packaging/README.md (navin-manager/packaging/README.md)): the server RPM is built in a RHEL builder with python3.12 (one RPM for the RHEL family 8, 9 and 10), the server DEB on Ubuntu 24.04, the agent packages anywhere.

3. Transfer and verify​

Copy bundle.tar, its checksum, its signature and the packages through the transfer procedure of the bank, then on the manager host:

sha256sum -c bundle.tar.sha256
gpg --import navin-bundle.pub
gpg --verify bundle.tar.asc bundle.tar

The bundle is unpacked into the mirror directory once the server is installed (step 7), where verify-bundle.py checks the size and the sha256 of every file against manifest.json.

4. Install the server​

RHEL, Rocky, AlmaLinux:

dnf install ./navin-manager-1.0.0-1.el9.x86_64.rpm

Ubuntu 24.04:

apt install ./navin-manager_1.0.0_amd64.deb

Arch Linux (the package depends on the Python of Arch Linux it was built for, pacman -S postgresql first for a local database):

pacman -U ./navin-manager-1.0.0-1-x86_64.pkg.tar.zst

The package creates the system user navin-manager, the application environment in /opt/navin-manager, the catalog in /usr/share/navin-manager/catalog, the SQL migrations in /usr/share/navin-manager/sql, the console in /usr/share/navin-manager/ui, /var/lib/navin-manager, /var/log/navin-manager and the systemd unit navin-manager.service.

5. Configure​

Edit /etc/navin-manager/server.yaml (every key can be overridden by NM_<KEY> in /etc/navin-manager/server.env):

KeyValue
database_urlpostgresql://navin_manager@<db-host>:5432/navin_manager?sslmode=verify-full&sslrootcert=/etc/navin-manager/tls/postgresql-ca.pem. Put the password in server.env (NM_DATABASE_URL, mode 0640) or in ~navin-manager/.pgpass, never in server.yaml.
tls_cert_file, tls_key_fileCertificate and key of the manager.
public_urlURL of the console, for example https://<manager-host>:8460.
agent_urlURL of the agent API, for example https://<manager-host>:8461.
NM_METRICS_TOKENIn server.env: 32 characters or more, used by Prometheus to read /metrics.
mirror_url, registryOptional: a Nexus or Artifactory of the bank holding the mirror tree, a Harbor, Quay or Nexus registry holding the images. Without them the agents use the local mirror of the manager.

The package created the master key /etc/navin-manager/master.key (32 random bytes, owned by navin-manager, mode 0600). Check the settings, then start the server (the unit applies the database migrations before serving):

navin-manager check
systemctl enable --now navin-manager

Keep a copy of /etc/navin-manager/master.key in the bank vault: every stored secret depends on it. navin-manager check lists every setting that forbids a production start (TLS, client certificates, cookie flag, metrics token, scrypt cost, master key, sslmode).

6. First sign in​

Open https://<manager-host>:8460 and sign in with navin and the initial password the package wrote to /etc/navin-manager/server.env (NM_ADMIN_PASSWORD). That password serves once: the console asks right away for your own password (12 characters or more, lower and upper case letters, digits and symbols). Lost password:

navin-manager reset-admin

In Administration, Authentication connect the LDAP or Active Directory of the bank, or an OIDC provider (Keycloak, Entra ID), map the groups to roles and adjust the security policy.

7. Load the mirror​

Unpack the verified bundle (it holds the mirror/ directory), check every file and give it to the service account:

tar -xf /media/transfer/bundle.tar -C /var/lib/navin-manager
python3 /usr/share/navin-manager/packaging/verify-bundle.py --mirror /var/lib/navin-manager/mirror
chown -R navin-manager:navin-manager /var/lib/navin-manager/mirror

Then in Administration, Mirror, select Reload (or call POST /api/v1/mirror/reload?verify=true). The page lists the services whose artifacts are missing from the mirror: they cannot be installed until a bundle that holds them is loaded.

Manifest signature (manifest.json.sig)​

By default (NM_MIRROR_SIGNATURE=required) the server refuses a manifest.json without a valid detached Ed25519 signature manifest.json.sig: error mirror_manifest_unsigned (no signature) or mirror_manifest_signature_invalid (manifest or signature altered, unknown key). The check runs at load and again at every delivery to the agents: a manifest replaced after the load is refused. Without it, anyone who can write in the mirror replaces an archive and its sha256.

  • Build: build-bundle.py ... --sign-key /secure/path/mirror-signing.pem (Ed25519 private key, PEM, never in the bundle). Create the key: openssl genpkey -algorithm ed25519 -out mirror-signing.pem then openssl pkey -in mirror-signing.pem -pubout -out mirror-signing.pub.pem.
  • Trusted keys of the server: PEM file NM_MIRROR_TRUSTED_KEYS_FILE and/or the Hub setting hub.trusted_keys_pem.
  • Check outside the server: verify-bundle.py --mirror ... --trusted-keys mirror-signing.pub.pem.
  • Migration of an existing unsigned mirror: verify it (verify-bundle.py --mirror) then sign-manifest.py --mirror /var/lib/navin-manager/mirror --sign-key mirror-signing.pem, and reload. During the migration only, NM_MIRROR_SIGNATURE=unsigned-allowed accepts an unsigned manifest; every load is then recorded in the audit (mirror.reload, signature.status = unsigned).
  • verify-bundle.py --strict also refuses the images without a digest pinned in the catalog (trust: first-download).

8. Add the hosts​

Create a cluster, then add hosts in one of two ways.

Agent package. In Hosts, Add hosts, create a bootstrap token. Install the agent on each host and run the register command shown by the console (it carries the token and the sha256 fingerprint of the manager CA). The shipped agent is the static Go binary (no Python needed on the host, see Host agent); take the package of the host architecture:

dnf install ./navin-manager-agent-go-1.0.0-1.x86_64.rpm
nm-agent register --server https://<manager-host>:8460 --token <token> --ca-sha256 <fingerprint>
systemctl enable --now navin-manager-agent

On Ubuntu use apt install ./navin-manager-agent-go_1.0.0_amd64.deb, on Arch Linux pacman -U ./navin-manager-agent-go-1.0.0-1-x86_64.pkg.tar.zst. The Python agent (navin-manager-agent-1.0.0-1.noarch.rpm, navin-manager-agent_1.0.0_all.deb, navin-manager-agent-1.0.0-1-any.pkg.tar.zst, Python 3.9 or newer) is still provided and uses the same command, configuration and unit.

SSH bootstrap. Give the host names, an SSH user, the private key and the SHA256 fingerprint of each host key. The manager checks each fingerprint, copies the agent package from the mirror, installs it and registers the host. The key stays in memory during the operation and is never stored.

The preflight checks of a host appear as soon as it registers: operating system, architecture, memory, CPU, disks, clock, SELinux, systemd, Podman, OpenSSL, Python, open files limit.

9. Install the platform​

In Clusters, Install services, choose the services, assign their components to hosts (the wizard shows the placement rules of each mode and validates them live), bind each dependency to a managed service or to an existing connection (the PostgreSQL of the bank in production), review the configuration (recommended values come from the host facts) and start the installation. The operation page shows each stage and the live logs of each task.

10. Serve the packages from a local repository​

On a site without access to the Navin repositories, serve the packages of the bundle from a local repository so that dnf, apt and pacman resolve them like any other package. <version> is the release, for example 1.0.0.

RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream (createrepo_c comes from the RHEL mirror of your organization):

dnf install -y createrepo_c
mkdir -p /srv/repo/navin && cp /var/lib/navin-manager/mirror/agent/*.rpm navin-manager-*.rpm /srv/repo/navin/
createrepo_c /srv/repo/navin
printf '[navin]\nname=Navin Enterprise\nbaseurl=file:///srv/repo/navin\ngpgcheck=0\nenabled=1\n' > /etc/yum.repos.d/navin.repo
dnf install -y navin-manager-agent-go

Expected result: dnf repolist lists navin. Set gpgcheck=1 once the packages are signed with the RPM key of your organization (rpmsign --addsign).

Ubuntu, Debian:

mkdir -p /srv/repo/navin && cp *.deb /srv/repo/navin/ && cd /srv/repo/navin
dpkg-scanpackages --multiversion . > Packages && gzip -k -f Packages
echo 'deb [trusted=yes] file:/srv/repo/navin ./' > /etc/apt/sources.list.d/navin.list
apt-get update && apt-get install -y navin-manager-agent-go

Expected result: apt-cache policy navin-manager-agent-go shows the local repository.

Arch Linux: pacman -U installs the package files directly; the signed [navin] repository of os/repo.sh can also be copied to an internal web server, its section SigLevel = Required DatabaseRequired refuses an unsigned package.

If it fails: dnf or apt cannot read the directory when SELinux or the permissions forbid it: run restorecon -R /srv/repo/navin and give it mode 0755.

11. Offline archives of the guided installer​

os/build.sh install-archive [debian|rhel|arch] builds one archive per family, navin-install-<version>-<family>.tar.gz with its .sha256: the installer, the packages of that family with their SHA256SUMS, the guide. Copy the archive with its checksum, then:

sha256sum -c navin-install-<version>-rhel.tar.gz.sha256
tar xzf navin-install-<version>-rhel.tar.gz && cd navin-install-<version>-rhel
sudo ./navin-install preflight manager

The installer checks the packages against SHA256SUMS before each installation and changes nothing while a check fails. The steps are in Install the Navin Manager.

12. Troubleshooting​

SymptomCauseFix
sha256sum -c reports FAILEDthe file was altered during the transfercopy it again from the build host
gpg --verify reports BAD signaturethe bundle or the key differs from the signed onestop: check the origin of the bundle and of navin-bundle.pub
The Mirror page lists missing artifactsthe bundle does not hold these services or methodsbuild a bundle with them (--services, --methods) and load it
An installation stops with artifact_missingthe mirror lacks the artifact of this versionload the bundle of this version, then Reload the manifest
A task fails with checksum_mismatchthe file of the mirror differs from manifest.jsonrun verify-bundle.py --mirror, then unpack the verified bundle again
The validation refuses the podman method with podman_missingthe agent runs without root (sandbox), or the host has neither dnf, apt-get nor pacmanrun on the host the command given by the message (for example sudo apt-get install -y podman uidmap), then refresh the facts of the host
apt-get update or dnf fails on the navin-os repositorya file of the embedded repository changed or its signature does not match the key of the bundlerun verify-bundle.py --mirror, unpack the verified bundle again, then Reload the manifest