CLI
Infrastructure

CLI

Install and use the JuhJuh CLI to validate configs, provision VMs, manage vaults, and deploy from your terminal. Full command reference with examples.

The JuhJuh CLI brings your full infrastructure workflow to the terminal. Validate your JuhJuh File, provision VMs, manage vault secrets, and trigger deployments without leaving the command line.

Install

bash pip install juhjuh-cli

Verify:

bash juhjuh --version

Quick start

If you already have a JuhJuh File in your repository, three commands get you from zero to running infrastructure:

bash juhjuh login juhjuh validate juhjuh apply

apply provisions VMs, syncs vault declarations, and triggers deployments in dependency order. Everything defined in your config file happens in one pass.

Authentication

Log in

bash juhjuh login

JuhJuh prompts for your server URL, username, and password. Credentials are stored in your system keyring, not on disk.

If you belong to multiple organizations, JuhJuh presents an interactive menu to choose the default. If you belong to one, it selects that org automatically.

Pass credentials directly for CI or scripted environments:

bash juhjuh login --server https://app.juhjuh.com --username your-name --password your-pass

Flag Description
--server, -s Platform URL (default: https://app.juhjuh.com)
--username, -u Your username
--password, -p Your password (input is hidden)

Check your session

bash juhjuh whoami

Returns your username, email, organization, and role.

Log out

bash juhjuh logout

Clears stored credentials from the keyring.

Organization

The CLI resolves your active organization from three sources, checked in this order:

  1. --org flag on the command (highest priority)
  2. organization field in your JuhJuh File
  3. organization field in ~/.juhjuh/config.toml

List your organizations

bash juhjuh org list

The active organization is marked with a green indicator.

Set the default organization

bash juhjuh org set my-team

Writes the slug to ~/.juhjuh/config.toml so future commands pick it up automatically.

Check the active organization

bash juhjuh org current

Shows which organization is resolved and where it came from (flag, config file, or JuhJuh File).

Initialize a project

bash juhjuh init

Walks you through an interactive wizard that generates a starter JuhJuh File. The wizard covers:

  1. Organization slug and project key
  2. VM configuration (name, environment, CPU, memory, region, disk sizes, deploy command)
  3. Deployment configuration (identifier, target VM, registry, compose file, image tag)

The output is a commented juhjuh.yml file ready to customize.

For scripted or CI environments:

bash juhjuh init --org my-team --project MYAPP --non-interactive

Flag Description
--output, -o Output file path (default: juhjuh.yml)
--org Organization slug (required in non-interactive mode)
--project Project key (required in non-interactive mode)
--non-interactive Skip prompts, generate config with defaults

Validate

Check your JuhJuh File for errors before deploying.

bash juhjuh validate

What gets checked

Validation runs 8 phases in sequence:

  1. YAML syntax across all files in the config directory
  2. Variable definitions, including type values and default-to-type consistency
  3. Variable completeness, ensuring every ${var.name} reference has a matching definition
  4. Schema conformance against the full JuhJuh File specification
  5. Vault entries, checking for empty vaults, invalid key characters, and ${from_env} placeholders
  6. Cross-references between deployments, VMs, vaults, resources, and services
  7. Online verification (optional), confirming that vaults and VMs actually exist on the server
  8. File references, checking that local files used in bind mounts exist on disk

Errors and warnings are printed as formatted tables with file and line numbers.

Strict mode

Treat warnings as errors:

bash juhjuh validate --strict

Online verification

Verify that vaults and VMs referenced in your config actually exist on the server:

bash juhjuh validate --online

Online mode fetches live vault data and compares entry counts against your config. It also checks that envGroup variables exist in the referenced vault. When --online is active, vault warnings from local cross-reference checks are suppressed since the server is the source of truth. Vaults referenced by UUID skip name-matching suggestions.

Flag Description
--file, -f Config file or directory path (auto-detected if omitted)
--strict Treat warnings as errors
--online Verify vaults and VMs exist on the server

Apply

Provision VMs, create vaults, and deploy in a single command. This is the primary way to go from a JuhJuh File to running infrastructure.

bash juhjuh apply

JuhJuh reads your config and applies changes in three phases:

  1. VMs: creates or updates VMs with the specified compute resources. If a VM referenced by a deployment does not exist yet, JuhJuh creates it from your config and waits for it to reach a running state.
  2. Vaults: ensures vaults exist and imports declared variables (with skip_existing so existing values are preserved)
  3. Deployments: triggers deployments in dependency order, grouped by level. Deployments in the same level run in parallel. Each level waits for the previous level to finish before starting.

Variables using the ${from_env} placeholder are read from your local environment at apply time. If a referenced environment variable is missing, JuhJuh skips it and reports the omission.

Preview changes

bash juhjuh apply --dry-run

Shows what would happen without making any API calls. Dry-run output includes the dependency levels, planned deployments, and their configurations.

Wait for deployments

Block until every deployment finishes (or fails):

bash juhjuh apply --wait

JuhJuh polls each deployment after creation and shows a spinner with the current status. The command exits with a non-zero code if any deployment fails or is rolled back.

Without --wait, apply returns immediately after triggering deployments.

Skip deployments

Provision VMs and vaults only:

bash juhjuh apply --skip-deploy

Keep failed VMs for debugging

By default, if a VM's first deployment fails, JuhJuh destroys the VM. Subsequent failures trigger a rollback to the last successful version. To keep the VM alive after failure (useful for debugging):

bash juhjuh apply --no-cleanup

Flag Description
--file, -f Config file or directory path
--dry-run Preview changes without applying
--wait, -w Wait for all deployments to complete
--skip-deploy Provision VMs and vaults only
--no-cleanup Keep VMs alive on deployment failure

Destroy

Tear down all VMs and deployments defined in your config:

bash juhjuh destroy

JuhJuh reads your config, then destroys resources in reverse dependency order: dependent deployments first, then their dependencies, then VMs. Each VM is only destroyed once, even if multiple deployments reference it.

Preview what would be destroyed:

bash juhjuh destroy --dry-run

Flag Description
--file, -f Config file or directory path
--force Skip confirmation prompt
--dry-run Preview without destroying

Deploy

Create a deployment

bash juhjuh deploy create production-app

The name matches a deployment defined in your JuhJuh File, or a VM name. JuhJuh resolves the image, tag, vault, and scoped services from the config.

If the target VM does not exist yet, JuhJuh creates it using specs from the config, then waits for it to reach a running state before deploying.

Override the image or tag:

bash juhjuh deploy create production-app --image registry.example.com/my-app --tag v2.1.0

Wait for the deployment to complete:

bash juhjuh deploy create production-app --tag v2.1.0 --wait

Preview the payload without sending:

bash juhjuh deploy create production-app --dry-run

Dry-run output includes the full VM specs, parsed configuration, file mappings, and resolved vault.

Flag Description
--image, -i Container image (overrides config)
--tag, -t Image tag (overrides config)
--compose, -c Compose file content or path
--vault Vault name to attach
--wait, -w Wait for deployment to complete
--dry-run Show payload without sending
--file, -f Config file or directory path

Vault resolution

JuhJuh attaches a vault to each deployment using this priority:

  1. --vault flag (explicit override)
  2. vault field in the deployment config
  3. Vault whose name matches the target VM

File sync

JuhJuh collects files referenced in your config (bind mounts from services, resources, and templates) and syncs them to the VM as part of the deployment. Only files scoped to the deployment are included.

List deployments

bash juhjuh deploy list

Filter by environment or VM:

bash juhjuh deploy list --env production juhjuh deploy list --vm my-app-prod

Flag Description
--env, -e Filter by environment
--vm Filter by VM name
--limit, -n Max results (default: 20)

Check deployment status

bash juhjuh deploy status <deployment-id>

Shows the deployment ID, VM, image, tag, environment, status, timestamps, error message (if any), and rollback info.

Rollback

bash juhjuh deploy rollback my-app-prod

Reverts the VM to its previous successful deployment. JuhJuh creates a new deployment with the prior image tag and restores the vault snapshot.

Flag Description
--force, -f Skip confirmation prompt
--wait, -w Wait for rollback to complete

Delete deployment history

bash juhjuh deploy destroy my-app-prod

Removes all deployment records for a VM. Requires confirmation.

Flag Description
--force, -f Skip confirmation prompt

VMs

List VMs

bash juhjuh vm list

Displays a table with name, environment type, status, region, CPU, memory, disk, IP address, and latest deployment.

Check VM status

bash juhjuh vm status my-app-prod

Create a VM

From a JuhJuh File:

bash juhjuh vm create my-app-prod --from-config juhjuh.yml

With explicit specs:

bash juhjuh vm create my-app-prod \ --project-key MYAPP \ --env-type production \ --cpu 4 \ --memory-gb 16 \ --disk-gb 200 \ --region europe-west

When using --from-config, JuhJuh reads all specs from the named VM in your config, including firewall rules collected from scoped resources and services.

Flag Description
--project-key, -p Project key (required without --from-config)
--env-type, -e Environment: production, staging, development, testing (required without --from-config)
--cpu Number of CPU cores
--memory-gb Memory in GB
--disk-gb Total disk in GB
--region, -r Deployment region
--deploy-command Custom deploy command
--from-config Load specs from a JuhJuh File

Start and stop

bash juhjuh vm start my-app-prod juhjuh vm stop my-app-prod

Destroy

bash juhjuh vm destroy my-app-prod

Requires confirmation. Add --force to skip the prompt.

Vault

List all vaults

bash juhjuh vault list-all

Shows every vault in the organization with its name, VM, entry count, version, and last update time.

Create a vault

bash juhjuh vault create my-app-prod

Creates a vault for the named VM. Returns the vault name and version.

List entries

bash juhjuh vault list my-app-prod

Displays all entries with key, value (masked for secrets), type, secret status, and description.

Get a single entry

bash juhjuh vault get my-app-prod SECRET_KEY

Add --quiet to print the value only, useful for piping into other commands:

bash juhjuh vault get my-app-prod SECRET_KEY --quiet

Set an entry

bash juhjuh vault set my-app-prod DATABASE_PASSWORD=supersecret --secret

The value format is always KEY=VALUE. JuhJuh validates the format before sending.

Flag Description
--secret, -s Mark as secret (value masked in listings)
--description, -d Human-readable description

Delete an entry

bash juhjuh vault delete my-app-prod DATABASE_PASSWORD

Requires confirmation. Add --force to skip.

Import from JuhJuh File

Sync vault declarations from your JuhJuh File to the server:

bash juhjuh vault import my-app-prod

This reads the vaults section of your config and pushes entries to the server. Variables with the ${from_env} placeholder pull their values from your local environment. Missing environment variables are skipped and reported.

Preview what would be imported:

bash juhjuh vault import my-app-prod --dry-run

The dry-run table shows each key, its secret status, the value source (environment or config), and description.

Flag Description
--file, -f Config file or directory path
--dry-run Preview without applying
--skip-existing Skip keys that already exist on the server

Export

bash juhjuh vault export my-app-prod

Outputs all entries in .env format to stdout. Write to a file:

bash juhjuh vault export my-app-prod --output .env.production

The output file is created with restricted permissions (owner read/write only).

Diff

Compare the current vault state against the last deployed snapshot:

bash juhjuh vault diff my-app-prod

Shows added, removed, and changed entries since the last deployment. Secret entries are labeled but their values stay hidden.

Config file auto-detection

When you run apply, validate, or deploy create without the --file flag, JuhJuh looks for configuration in this order:

  1. juhjuh.yml in the current directory
  2. juhjuh.yaml in the current directory
  3. .juhjuh/ directory in the current directory

If you use the .juhjuh/ directory format, all .yaml and .yml files inside are merged alphabetically using deep merge. See the JuhJuh File multi-file configuration section for merge rules.

Global options

These flags work on every command:

Flag Description
--version, -V Show CLI version
--org Organization slug override (takes highest priority)

Configuration file

The CLI stores global settings in ~/.juhjuh/config.toml:

toml server = "https://app.juhjuh.com" organization = "my-team" project = "MYAPP"

juhjuh login and juhjuh org set write to this file automatically. You can also edit it directly.

  • JuhJuh File: the configuration format the CLI reads and validates
  • Infrastructure Overview: how VMs, vaults, deployments, and the CLI fit together
  • VMs: provision and manage compute instances
  • Vault: store and manage secrets for your deployments
  • Deployments: ship container images to your VMs
  • Billing: understand costs for infrastructure managed through the CLI
  • MCP Server: connect Claude Code and Claude Desktop to JuhJuh for AI-assisted management