Deployments
Infrastructure

Deployments

Deploy container images to your VMs with versioning, rollback, and vault-backed secrets. Track history, manage dependencies, and automate with config-as-code.

Deployments push container images to your VMs with vault secrets injected as environment variables. Every deploy is versioned, logged, and backed by a vault snapshot you can restore at any time.

  1. Open your organization
  2. Click Deployments in the sidebar

The deployments dashboard shows all running VMs with their latest deployed version and tag, a deployment history timeline, and controls for deploying, rolling back, and managing services.

Create a deployment

  1. Select a VM from the dropdown. Only running VMs appear
  2. Select a Container Registry resource (your connected container registry)
  3. Enter the image name (e.g., registry.example.com/org/myapp)
  4. Select a tag from the dropdown. JuhJuh fetches available tags from your registry in real time
  5. Click Deploy

JuhJuh then:

  1. Assigns the next semantic version (e.g., v1.0.3)
  2. Captures a vault snapshot
  3. Connects to the VM securely
  4. Injects vault secrets as environment variables
  5. Pulls the container image and starts the service
  6. Streams the execution log in real time
sequenceDiagram
    participant You
    participant JuhJuh
    participant Vault
    participant VM

    You->>JuhJuh: Deploy image:tag to VM
    JuhJuh->>JuhJuh: Assign version (v1.0.3)
    JuhJuh->>Vault: Capture snapshot
    JuhJuh->>VM: Connect securely
    JuhJuh->>VM: Inject secrets
    JuhJuh->>VM: Pull image and start service
    JuhJuh-->>You: Stream execution log

Deployment history

The history table lists every deployment across your organization, newest first. Each entry includes the image name and tag, semantic version, status badge, who deployed and when, and a linked ticket if the deployment was triggered from one.

Filter by VM with the instance dropdown to focus on a specific environment.

Rollback

  1. Click Rollback on the deployments dashboard
  2. Select the deployment to roll back to
  3. Click Confirm

JuhJuh creates a new deployment with the previous image tag, bumps the minor version (e.g., v1.2.3 to v1.3.0), and restores the vault snapshot from the selected deployment. The rollback is a full deployment: it goes through the same steps and produces its own execution log.

Redeploy

Click Redeploy to re-run the current deployment with the same image and tag. Useful after infrastructure changes (VM restart, network update), vault updates that need to take effect, or recovery from a transient failure.

Service controls

Action What it does
Stop Service Stops the running containers on the VM without destroying the VM itself
Start Service Starts containers back up using the last deployed configuration

Service controls affect the running containers, not the VM itself. The VM stays online. Only the application services stop or start.

Versioning

JuhJuh auto-assigns semantic versions per VM:

Scenario Version bump Example
Normal deploy Patch v1.0.2 to v1.0.3
Rollback Minor (patch resets) v1.2.3 to v1.3.0
First deploy Starts at v1.0.0

Versions are scoped to each VM. Two VMs maintain independent version histories.

Status reference

Status Meaning
Pending Deployment created, waiting to execute
Deploying Connection established, deploy commands running
Success All steps completed, service is live
Failed One or more steps failed. Check the execution log for details
Rolled Back This deployment was superseded by a rollback
stateDiagram-v2
    [*] --> Pending
    Pending --> Deploying
    Deploying --> Success
    Deploying --> Failed
    Success --> Rolled_Back: rollback triggered
    Failed --> Pending: redeploy

Execution log

Every deployment produces a step-by-step execution log. Click any deployment in the history table to view it. The log covers connection status, configuration transfer, image pull output, container startup output, health check results, and error details if any step fails.

Logs are persisted permanently and available for any past deployment.

Config-driven deployments

Instead of creating deployments through the dashboard, define them in your JuhJuh File (juhjuh.yml or a .juhjuh/ directory). The deployments section maps services and resources to VMs, configures cross-deployment dependencies, and handles registry authentication.

Basic deployment

A minimal config-driven deployment specifies the target VM, image, tag, and the services to run:

yaml deployments: production-app: vm: production-app image: registry.example.com/my-app tag: latest vault: app-vault services: [web, worker] resources: [postgres, redis]

Scoping services and resources

The services and resources lists control which parts of your config are included in the generated orchestration file for that deployment. If you omit both lists, all services and resources are included.

```yaml deployments: database: vm: db-server resources: [postgres, redis] services: []

app: vm: app-server services: [web, worker] resources: [] ```

This splits your infrastructure across two VMs: one runs the data stores, the other runs the application services.

Exposed ports

Expose ports on the organization network so other deployments can reference them:

yaml deployments: database: vm: db-server resources: [postgres] expose: - port: 5432 as: postgres protocol: tcp

Each alias must be unique within a deployment. Other deployments reference these ports using deployment references.

Registry authentication

If your container image lives in a private registry, provide credentials directly in the deployment config:

yaml deployments: app: vm: app-server image: private.registry.io/my-app tag: v2.1.0 registry: url: private.registry.io username: deploy-bot password: "${var.REGISTRY_TOKEN}"

Environment selection

Apply environment overrides to a deployment by setting the environment field:

yaml deployments: staging-app: vm: staging-server image: registry.example.com/my-app tag: develop environment: staging services: [web, worker]

JuhJuh merges the environment overrides (compute limits, resource config, service settings) before generating the orchestration file.

Network attachment

Attach a deployment to a named network defined in the networks section:

```yaml networks: internal: scope: organization driver: bridge

deployments: app: vm: app-server network: internal services: [web] ```

Deployment dependencies

Deployments can declare dependencies on other deployments using the dependsOn field. JuhJuh resolves these as a directed acyclic graph (DAG) and deploys them in the correct order. Independent deployments at the same level run in parallel, so your infrastructure comes up as fast as possible.

Circular dependencies are detected and rejected at validation time before anything is provisioned.

Each dependency accepts a condition that controls when JuhJuh considers the upstream deployment satisfied:

Condition Behavior
healthy Wait until the upstream deployment passes its health check (default)
created Wait until the upstream deployment's containers are running, no health check required
ready Wait until the upstream deployment reports full readiness (all services responding)

```yaml deployments: database: vm: db-server resources: [postgres] expose: - port: 5432 as: postgres

app: vm: app-server services: [web, worker] dependsOn: - deployment: database condition: healthy ```

In this example, app waits until database passes its health check before starting.

graph LR
    database[database deployment] --> app[app deployment]
    database --> cache[cache deployment]
    cache --> app

Deployment references

Use ${deployment.<name>.<attribute>} syntax to reference runtime values from other deployments. References are resolved at deploy time and injected into your service environment.

Available attributes:

Attribute Returns Example
host Private IP of the deployment's VM 10.0.1.5
port.<alias> Port number for a named exposed service 5432
endpoint.<alias> Combined host:port for a named exposed service 10.0.1.5:5432
status Current deployment status HEALTHY
network Network name internal

Any deployment you reference must also appear in your dependsOn list. JuhJuh enforces this at validation time to guarantee the referenced deployment exists and is healthy before your deployment starts.

yaml envGroups: app-config: clear: POSTGRES_HOST: "${deployment.database.host}" POSTGRES_PORT: "${deployment.database.port.postgres}" DATABASE_ENDPOINT: "${deployment.database.endpoint.postgres}"

References work in two modes:

  • Full-value replacement: ${deployment.database.host} resolves to the literal IP string
  • Inline replacement: postgres://user@${deployment.database.host}:5432/mydb concatenates the resolved value into the surrounding string

Deploy from the CLI

The CLI provides full deployment control from your terminal or CI pipeline.

Create a deployment

bash juhjuh deploy create production-app

The CLI auto-detects your JuhJuh File, resolves the deployment config by name, validates the configuration, runs pre-flight checks (vault entries, sync files, resource references), and creates the deployment. Add --wait to block until the deployment completes:

bash juhjuh deploy create production-app --wait

Override the image or tag from the command line:

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

Preview the deployment plan without executing:

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

Apply all infrastructure

To provision VMs, import vaults, and create deployments in one step:

bash juhjuh apply

List deployments

bash juhjuh deploy list juhjuh deploy list --vm production-app --limit 10

Check deployment status

bash juhjuh deploy status <deployment-id>

Rollback from the CLI

bash juhjuh deploy rollback production-app --wait

Destroy deployment history

bash juhjuh deploy destroy production-app --force

See the CLI reference for all available commands.

VM billing and cost management

VMs support hourly billing rates, giving you granular control over infrastructure costs. You can configure auto-stop after a set number of idle days so unused VMs do not accumulate charges. For long-running infrastructure, reserved commitment options (1-year or 3-year) are available at reduced rates.

See Billing for pricing details and cost tracking.

Constraints

  • Only one deployment can be active (pending or deploying) per VM at a time
  • Only running VMs appear in the deploy form
  • Image and tag names must follow container naming conventions
  • The vault must have all required entries filled before deployment succeeds
  • Deployment names in the JuhJuh File must be lowercase alphanumeric with hyphens or underscores
  • Expose aliases must be unique within each deployment
  • Deployment reference targets must appear in dependsOn
  • Infrastructure Overview: how deployments fit into the broader infrastructure model
  • VMs: the compute instances you deploy to
  • Networking: private networks, firewall rules, exposed ports, and deployment references
  • Vault: environment variables and secrets injected at deploy time
  • Resources: container registries and other connected services
  • JuhJuh File: define your full infrastructure as code
  • CLI: trigger deployments and rollbacks from your terminal
  • Billing: hourly rates, reserved commitments, and cost tracking
  • Observability: monitor your deployed services with logs, metrics, traces, and alerts
  • Permissions: role-based access control for deployment actions