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.
Navigate to deployments¶
- Open your organization
- 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¶
- Select a VM from the dropdown. Only running VMs appear
- Select a Container Registry resource (your connected container registry)
- Enter the image name (e.g.,
registry.example.com/org/myapp) - Select a tag from the dropdown. JuhJuh fetches available tags from your registry in real time
- Click Deploy
JuhJuh then:
- Assigns the next semantic version (e.g.,
v1.0.3) - Captures a vault snapshot
- Connects to the VM securely
- Injects vault secrets as environment variables
- Pulls the container image and starts the service
- 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 logDeployment 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¶
- Click Rollback on the deployments dashboard
- Select the deployment to roll back to
- 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: redeployExecution 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 --> appDeployment 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/mydbconcatenates 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
Related¶
- 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