Deploy and Verify

Deploy the platform from the imported bundle, verify the install with kubectl, trust the generated CA certificate, and load the imported vulnerability data.

deploy runs against the packages and configuration from Set Up the Target Host. If either is missing, it stops with a pointer to the missing step — it never auto-runs a prerequisite or reaches for the internet.


1. Deploy

manifest-installer deploy

deploy performs the following, in order — entirely from the imported bundle, with no internet access:

  1. Host preparation — installs OS prerequisite packages, loads required kernel modules (br_netfilter, overlay), applies sysctl settings, opens firewall ports (6443 for the k3s API, 31999 for the Zarf registry, 80/443 for Traefik), and applies SELinux/nftables/fapolicyd rules where applicable.
  2. k3s installation — installs the k3s binary and systemd service. k3s embeds containerd as its container runtime, so no separate container engine is needed.
  3. In-cluster registry bootstrap — Zarf injects a temporary seed registry into the cluster, then promotes a permanent in-cluster registry. All platform images are loaded from the bundle into this registry.
  4. Platform deployment — brings up Manifest itself: platform-level dependencies and operators, then the application workloads.

A first-run deploy typically takes 10–20 minutes, depending on host performance.

deploy is safe to re-run. If it fails partway, fix the underlying issue and run it again — each step is idempotent, so a re-run skips completed work and converges to the failed point in seconds. There is nothing to clean up and no resume flag.

On success, deploy exits with code 0 and its final line confirms the last package deployed:

deployed package manifest-app, version <x.x.x>

It does not print the platform URL — reaching the web UI is covered next.


2. Verify the install

📘

status command

The manifest-installer status health-report command is not yet available in this release. Until it ships, verify the install with kubectl as below.

Point kubectl at the new cluster and confirm pods are healthy:

export KUBECONFIG=$HOME/.kube/config
kubectl get nodes
kubectl get pods -A

All pods should reach Running or Completed. Confirm Traefik is listening:

kubectl -n traefik get svc

Then resolve your domain to the host IP (via internal DNS or a temporary /etc/hosts entry) and visit the URL in a browser. The first login uses the admin email you supplied during setup; follow the password-reset flow on first sign-in.


3. Trust the Manifest CA certificate

Manifest generates a self-signed CA for the web ingress. To avoid browser warnings, export it and trust it on every machine that will access the platform:

kubectl get secret -n cert-manager mfst-ca-tls -o jsonpath='{.data.ca\.crt}' | base64 -d > manifest-ca.crt

Per-OS trust commands are in the Post-Install reference.


4. Load vulnerability data

If the bundle was built with export-bundle --include-data, load the imported vulnerability data into the running platform:

manifest-installer deploy-data

deploy-data deploys the imported data packages oldest-first, skipping any the cluster already has. Each package's in-cluster load can take up to 3 hours; the command waits for completion. If it fails partway, re-run it — already-loaded packages are recorded in the cluster and skipped.

deploy-data logs each package as it starts and finishes, and nothing in between. To watch a load progress, follow the loader Job's logs from a second shell on the target host:

kubectl logs -f job/vuln-loader -n job

Each package's deploy replaces the vuln-loader Job, so this follows the package currently loading and exits when that package's pod finishes — run it again for the next package. A finished Job and its logs stay readable until the next package replaces them, which is where to look when a load fails.

Vulnerability data does not refresh itself in an air-gapped deployment; carrying refreshes across the air gap is covered in Update an Air-Gapped Install.


Troubleshooting

  • Another manifest-installer command is running. The installer takes a per-host lock; wait for the other command to finish and re-run.
  • deploy fails with "exec format error". The target host is not x86_64; bundles are built for linux/amd64 only.
  • Pods fail to pull images from the in-cluster registry. The bundle may be incomplete (re-export it on the prep host), or the registry didn't come up cleanly — check the zarf namespace.
  • OS-prerequisite packages missing. The bundle carries packages for Debian 12, RHEL 9, and Ubuntu 24.04 on x86_64 only; other distributions fail at the OS-package step.
  • Kernel-module load failures. Some hardened kernels block br_netfilter or overlay; confirm they are available on your distribution and re-run.
  • Ports already in use. If something else on the host owns 6443, 31999, 80, or 443, stop it before running deploy.
  • deploy-data looks stuck. A single package's in-cluster load can legitimately run for up to 3 hours with no installer output. Confirm it is progressing with kubectl logs -f job/vuln-loader -n job; the same command shows why a load failed, since the Job's logs survive until the next package replaces it. If deploy-data exits with an error, re-run it — packages already loaded are skipped.

For help, contact Manifest support at [email protected].


Did this page help you?