lux node
Manage luxd nodes (local binary and Kubernetes deployments)
lux node
Commands for managing luxd nodes — locally and on Kubernetes.
LOCAL COMMANDS: link Symlink a luxd binary to ~/.lux/bin/luxd join Join this box to the node pool (run a validator anywhere)
KUBERNETES COMMANDS (via Helm chart): deploy Deploy/update luxd via Helm (single source of truth) upgrade Rolling upgrade with zero downtime (partition-based) status Show pod status, images, and health logs Stream logs from a luxd pod rollback Revert to previous StatefulSet revision
The deploy command uses the canonical Helm chart at ~/work/lux/devops/charts/lux/ (configurable via --chart-path or $CHART_PATH). All other k8s commands use the Kubernetes API directly for fast read/write operations.
All k8s commands require one of --mainnet, --testnet, --devnet, or --namespace. Use --context to target a specific kubeconfig context.
EXAMPLES:
Local
lux node link --auto
Deploy via Helm (uses canonical chart + values-{network}.yaml)
lux node deploy --mainnet lux node deploy --testnet --set image.tag=luxd-v1.23.15
Zero-downtime upgrade (partition-based, per-pod health checks)
lux node upgrade --mainnet --image ghcr.io/luxfi/node:v1.23.6
Check status
lux node status --mainnet
Stream logs
lux node logs --mainnet luxd-0 -f
Rollback
lux node rollback --mainnet
Usage:
lux nodelux node deploy
Deploys the luxd Helm chart to Kubernetes using helm upgrade --install.
Uses the canonical Helm chart from ~/work/lux/devops/charts/lux/ as the single source of truth. This ensures the CLI creates identical deployments to the deploy-all.sh script — same startup.sh, staking keys, bootstrap nodes, upgrade-file-content, chain configs, and per-pod services.
CHART DISCOVERY (in order):
- --chart-path flag
- $CHART_PATH environment variable
- ~/work/lux/devops/charts/lux/
EXAMPLES: lux node deploy --mainnet lux node deploy --testnet --set image.tag=luxd-v1.23.15 lux node deploy --devnet --replicas 3 lux node deploy --mainnet --chart-path /path/to/chart lux node deploy --mainnet --dry-run
Usage:
lux node deploy [flags]Flags:
--chart-path string path to Helm chart (default: auto-detect)
--context string kubeconfig context to use
--devnet target lux-devnet namespace
--dry-run helm dry-run mode (template only, no apply)
--image string override image tag (shorthand for --set image.tag=TAG)
--mainnet target lux-mainnet namespace
--namespace string k8s namespace (overrides network flags)
--replicas int32 override replica count (0 = use chart default)
--set stringArray additional Helm --set overrides (repeatable)
--testnet target lux-testnet namespacelux node join
Run this on any box and it joins the pool; the operator schedules a compact validator onto it and rebalances the fleet. Drain a box and its validator reschedules onto the others — run a node anywhere, the network spreads.
First box — become the control plane and hold history:
lux node join --init --role archive
Any other box — join and run a compact validator:
lux node join --server https://<control>:6443 --token <token>
Off-LAN boxes: put them on one tailnet first (tailscale up, or hanzozt) and pass the tailnet IP as --server, so "anywhere" really means anywhere. The role is a node label (lux.cloud/validator|archive=true) the NodeFleet schedules against — see operator/spec/examples/nodefleet-lab.yaml.
Usage:
lux node join [flags]Flags:
--init make THIS box the pool's control plane (k3s server)
--name string node name (default: hostname)
--print print the k3s command instead of running it
--role string node role: validator (compact) or archive (full history) (default "validator")
--server string control-plane API URL, e.g. https://<ip>:6443 (agent mode)
--token string node token from the control plane (agent mode)lux node link
Link luxd binary for the CLI to use.
Creates ~/.lux/bin directory if needed and symlinks the luxd binary.
PRIORITY ORDER for binary lookup:
- Command-line flags (--node-path)
- ~/.lux/bin/luxd (this symlink)
- Environment variable (NODE_PATH)
- Config file settings
- PATH lookup
- Relative paths from CLI location
EXAMPLES:
Link luxd (auto-detect from ../node/bin/luxd)
lux node link --auto
Link specific path
lux node link /path/to/luxd
Usage:
lux node link [path] [flags]Flags:
--auto auto-detect luxd from standard locationslux node logs
Streams logs from a specific luxd pod in the StatefulSet.
If no pod name is given, defaults to luxd-0.
EXAMPLES: lux node logs --mainnet lux node logs --mainnet luxd-2 lux node logs --mainnet luxd-0 -f lux node logs --testnet --tail 100
Usage:
lux node logs [pod-name] [flags]Flags:
--context string kubeconfig context to use
--devnet target lux-devnet namespace
-f, --follow follow log output
--mainnet target lux-mainnet namespace
--namespace string k8s namespace (overrides network flags)
--tail int number of recent lines to show (default 200)
--testnet target lux-testnet namespacelux node rollback
Reverts the luxd StatefulSet to its previous ControllerRevision.
By default rolls back to the immediately previous revision. Use --revision to target a specific revision number.
After rollback, performs the same partition-based rolling update to ensure zero downtime — pods are updated one at a time with health checks.
EXAMPLES: lux node rollback --mainnet lux node rollback --mainnet --revision 3 lux node rollback --testnet --timeout 10m
Usage:
lux node rollback [flags]Flags:
--context string kubeconfig context to use
--devnet target lux-devnet namespace
--mainnet target lux-mainnet namespace
--namespace string k8s namespace (overrides network flags)
--revision int target revision number (0 = previous)
--testnet target lux-testnet namespace
--timeout duration max time to wait per pod (default 5m0s)lux node status
Displays the current state of the luxd Kubernetes deployment.
Shows:
- StatefulSet metadata (replicas, revision, update strategy)
- Per-pod status (ready, image, restarts, age)
- LoadBalancer external IP
- Revision history for rollback
EXAMPLES: lux node status --mainnet lux node status --testnet lux node status --namespace my-custom-ns
Usage:
lux node status [flags]Flags:
--context string kubeconfig context to use
--devnet target lux-devnet namespace
--mainnet target lux-mainnet namespace
--namespace string k8s namespace (overrides network flags)
--testnet target lux-testnet namespacelux node upgrade
Performs a partition-based rolling upgrade of the luxd StatefulSet.
Upgrades one pod at a time (highest ordinal first), waiting for each pod to become ready and stable before proceeding. This ensures C-chain RPC clients experience no downtime since a quorum of validators remains available throughout the upgrade.
PROCESS:
- Validates the new image exists and differs from current
- Updates the StatefulSet pod template with new image
- Sets partition = replicas (no pods restart yet)
- Lowers partition one at a time (pod N-1, N-2, ... 0)
- After each pod restart: waits for readiness + stability period
- If any pod fails health check, stops and prints rollback command
EXAMPLES: lux node upgrade --mainnet --image ghcr.io/luxfi/node:v1.23.5 lux node upgrade --testnet --image ghcr.io/luxfi/node:v1.23.5 --stability-wait 60s lux node upgrade --devnet --image ghcr.io/luxfi/node:v1.23.5 --dry-run
Usage:
lux node upgrade [flags]Flags:
--context string kubeconfig context to use
--devnet target lux-devnet namespace
--dry-run show what would happen without making changes
--evm-version string EVM plugin version to update in init container
--force proceed even if image is the same
--health-timeout duration max time to wait for a pod to become ready (default 5m0s)
--image string new container image (required)
--mainnet target lux-mainnet namespace
--namespace string k8s namespace (overrides network flags)
--stability-wait duration wait time after pod ready before proceeding (default 30s)
--testnet target lux-testnet namespace