Skip to main content Skip to content

Deploy to a VM

Ship a container to a Linux VM instead of a Kubernetes cluster; same pipeline, Docker + Caddy substrate, TLS and multi-service routing handled for you.

4 min read Last updated: 

Not every workload wants Kubernetes. ZopDay can ship a container straight to a Linux VM as an alternative substrate; same catalog, same revisions, same live progress; but the target is a Docker host with Caddy in front instead of a cluster. You still hand over no kubeconfigs, no SSH keys, and no standing credentials.

Provision Infrastructure drawer with Virtual Machine selected: "EC2, Compute Engine, or Azure VM, provisioner sets up VPC + IAM + security groups; Docker and Caddy install automatically on first deploy", with cloud account, region, name/size, and VPC options below

The Virtual Machine substrate; ZopDay sets up the VM and installs Docker + Caddy automatically, so the first deploy has a container host and TLS router ready.

When a VM is the right target

  • A single service (or a handful) that doesn’t need cluster orchestration
  • A cost-sensitive environment where a full cluster is overkill
  • A legacy or simple app you want live with TLS in minutes

For orchestration-heavy, multi-service, autoscaling workloads, deploy to a cluster instead.

How it differs from a cluster deploy

A VM substrate is a deployment space with space_type = vm. The pipeline is identical: the same claim → build (GitHub Actions) → deploy flow, only the final executor arm changes: it runs a runcommand (docker pull/run + a Caddy route update) instead of a helm release.

Cluster substrateVM substrate
RuntimeHelm release on KubernetesDocker container on a Linux VM
Router / TLSIngress controller + cert-managerCaddy (Let’s Encrypt via ACME) on the VM
Exec channelkubeauth (ephemeral kubeconfig)IAM-gated exec (SSM / IAP / Azure Run Command), no public SSH
Multi-tenant routingNamespacesPer-service Caddy site blocks on a shared host

Baseline components

Every VM in a substrate has two idempotent components installed: Docker and Caddy. Caddy’s bootstrap config includes a :80 health responder so the cloud load balancer reports healthy from the moment install finishes; there’s no unhealthy window before the first deploy.

Caddy is the router when a VM is used as a ZopDay deploy substrate; a VM provisioned as standalone infrastructure uses NGINX instead (see Provisioning VMs).

TLS and hostnames

  • TLS terminates at Caddy via Let’s Encrypt (HTTP-01 on :80, TLS-ALPN-01 on :443). No cert wrangling.
  • Automatic hostname: if a deployment has no explicit expose config but its space carries wildcard domain patterns, ZopDay synthesises a stable hostname of the form <name>-<short-id>.<space-suffix>. The short-id suffix prevents same-name collisions across deployments. The Quick Deploy “Live at” preview shows exactly the host Caddy will serve.

Multiple services on one VM

Several deployments can share one VM. Each deploy adds its own Caddy site block without touching co-resident services; their routes and containers are preserved across your deploy. Teardown is symmetric: removing one service leaves the others running. ZopDay fails a deploy that would collide on host or port rather than silently overwriting.

No public SSH

ZopDay never opens a public SSH session to your VM. The deploy runs over the cloud’s IAM-gated exec channel: aws ssm send-command, gcloud compute ssh --tunnel-through-iap, or az vm run-command, dispatched from the GitHub Actions runner, not from a ZopDay pod. Port 22 is not publicly reachable; interactive access is only through that IAM-gated channel.

Private registries

For images in a private registry (GAR / ECR / ACR), ZopDay mints a short-lived registry token server-side and injects a docker login before the pull, so the VM never holds long-lived cloud credentials.

Reliability

If the build’s success callback can’t reach ZopDay, a watchdog scrapes the build log for the canonical “successfully pushed” marker and recovers the deploy, covering both the callback-failed-after-success and the failure-but-push-completed cases.

Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001 · zero-trust· 30% average cloud cost cut· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001 · zero-trust· 30% average cloud cost cut· 4 platforms · 1 console·