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

pip install juhjuh-cli

Verify:

juhjuh --version

Quick start

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

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

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:

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

juhjuh whoami

Returns your username, email, organization, and role.

Log out

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

juhjuh org list

The active organization is marked with a green indicator.

Set the default organization

juhjuh org set my-team

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

Check the active organization

juhjuh org current

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

Initialize a project

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:

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.

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:

juhjuh validate --strict

Online verification

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

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.

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

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):

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:

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):

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:

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:

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

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:

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

Wait for the deployment to complete:

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

Preview the payload without sending:

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

juhjuh deploy list

Filter by environment or VM:

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

juhjuh deploy status <deployment-id>

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

Rollback

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

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

juhjuh vm list

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

Check VM status

juhjuh vm status my-app-prod

Create a VM

From a JuhJuh File:

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

With explicit specs:

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

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

Destroy

juhjuh vm destroy my-app-prod

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

Vault

List all vaults

juhjuh vault list-all

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

Create a vault

juhjuh vault create my-app-prod

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

List entries

juhjuh vault list my-app-prod

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

Get a single entry

juhjuh vault get my-app-prod SECRET_KEY

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

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

Set an entry

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

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:

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:

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

juhjuh vault export my-app-prod

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

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:

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:

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