Install the CloudSmith Relay
The CloudSmith Relay is a Docker container that runs on a Linux host inside your network. It maintains a persistent outbound WebSocket connection to the CloudSmith PaaS API and forwards commands to agents running on your managed Hyper-V hosts. The relay host does not need inbound access from the internet — all PaaS connections are outbound from the relay.
One relay per site
Deploy one relay per physical site or network segment. A site typically maps to a data center, server room, or remote office — anywhere you have a group of Hyper-V hosts on the same LAN.
A single site can contain multiple clusters, multiple racks, and any number of Hyper-V hosts. All of those hosts enroll with the one relay at that site. A single CloudSmith PaaS instance can manage any number of sites, each with its own relay.
CloudSmith PaaS (Azure)
│ │
│ │
▼ ▼
Site A relay Site B relay
(DC1 / primary) (DR / secondary)
│ │
HV hosts A1–A6 HV hosts B1–B3
(3 clusters) (1 cluster)
If you have a single site today, deploy a single relay. Add more relays as you expand to additional locations.
Traffic flow
CloudSmith PaaS (Azure)
│
│ HTTPS/WSS outbound (port 443)
│ from relay → PaaS
▼
┌─────────────┐
│ Relay host │ (Linux VM or bare metal, inside your network)
│ Docker │
└─────────────┘
│
│ TCP inbound (port 8443)
│ from Hyper-V hosts → relay
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ HV Host A │ │ HV Host B │ │ HV Host C │
│ cs-agent │ │ cs-agent │ │ cs-agent │
└─────────────┘ └─────────────┘ └─────────────┘
Prerequisites
- Linux host (VM or bare metal) with Docker Engine 20.10 or later
- Outbound HTTPS (port 443) from the relay host to the CloudSmith PaaS API URL
- Inbound TCP port 8443 from managed Hyper-V hosts to the relay host
- If using PSRemote for agentless access: outbound TCP 5986 from relay to managed Windows hosts
- A named Docker volume or a persistent directory for relay identity storage (see Step 3)
Verify Docker is installed and running:
docker --version
docker info
Step 1 — Generate an enrollment token in the portal
Each relay must enroll with CloudSmith once before it can accept agent connections. The portal generates a one-time enrollment token for this purpose.
- Open the CloudSmith portal and sign in as an administrator.
- Navigate to Platform Management → Sites.
- Click Add Site.
- Enter a display name for this relay (for example,
relay-dc1). - Click Generate Token and copy the enrollment token value.
The token is valid for 24 hours. It is consumed on the relay’s first successful startup — after enrollment the token is no longer needed and subsequent relay restarts reuse the persisted identity.
Step 2 — Choose a relay-to-agent enrollment secret
Agents on your Hyper-V hosts authenticate to the relay using a shared secret you define. This is separate from the PaaS enrollment token.
Generate a strong random value now and record it — you will set it on the relay container and on every agent that connects to this relay:
openssl rand -hex 32
This value becomes RELAY_AGENT_ENROLLMENT_TOKEN on the relay and AGENT_ENROLLMENT_TOKEN on each agent. Keep it secret: anyone who knows this value can enroll new agents against your relay.
Step 3 — Deploy the relay container
You can deploy the relay using a one-liner install script or by running the Docker command directly. The install script is the recommended approach for new deployments — it resolves the latest image version, verifies the image digest, and waits for the container to become healthy before returning.
Option A — One-liner install script (recommended)
Linux:
curl -sSL https://raw.githubusercontent.com/cloudsmith-cloud/cloudsmith-installer/main/scripts/install-relay.sh \
| bash -s -- \
--api-url https://<your-paas-api-url> \
--api-key <enrollment-token-from-portal> \
--site-id <site-id-from-portal>
Windows (PowerShell 7+):
Invoke-Expression (Invoke-WebRequest `
-Uri 'https://raw.githubusercontent.com/cloudsmith-cloud/cloudsmith-installer/main/scripts/install-relay.ps1' `
-UseBasicParsing).Content; `
Install-Relay `
-ApiUrl 'https://<your-paas-api-url>' `
-ApiKey '<enrollment-token-from-portal>' `
-SiteId '<site-id-from-portal>'
| Parameter | Description |
|---|---|
--api-url / -ApiUrl |
HTTPS URL of the CloudSmith PaaS API |
--api-key / -ApiKey |
Enrollment token generated in Step 1 |
--site-id / -SiteId |
Site identifier from Platform Management → Sites |
--version / -Version |
Optional. OCI image tag to install. Defaults to the latest published release. |
The script pulls the image, optionally verifies the SHA-256 digest against the GitHub release manifest, removes any existing relay container, starts the new container with --restart unless-stopped, and waits up to 30 seconds for the container to reach a running state. Logs are printed if the container exits unexpectedly.
Option B — Manual docker run
Run the relay container with all required environment variables. Replace the placeholder values with your actual PaaS API URL, the enrollment token from Step 1, and the agent secret from Step 2:
docker run -d \
--name cloudsmith-relay \
--restart=always \
-e RELAY_PAAS_URL=https://<your-paas-api-url> \
-e RELAY_ENROLLMENT_TOKEN=<one-time-token-from-portal> \
-e RELAY_AGENT_ENROLLMENT_TOKEN=<your-chosen-agent-secret> \
-e RELAY_DISPLAY_NAME=relay-dc1 \
-p 8443:8443 \
-v cloudsmith-relay-identity:/var/lib/cloudsmith-relay/identity \
ghcr.io/cloudsmith-cloud/cloudsmith-relay:latest
Docker creates the named volume cloudsmith-relay-identity automatically on first run if it does not already exist. The relay writes its enrolled identity to this volume so that it survives container restarts and upgrades.
All environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
RELAY_PAAS_URL |
Yes | — | HTTPS URL of the CloudSmith PaaS API. The relay connects here to enroll and maintain its WebSocket. |
RELAY_ENROLLMENT_TOKEN |
Yes (first start only) | — | One-time token from the portal. Consumed on first successful enrollment and not needed on subsequent starts. |
RELAY_AGENT_ENROLLMENT_TOKEN |
Yes | — | Shared secret that agents present when enrolling with this relay. You choose this value. |
RELAY_DISPLAY_NAME |
No | container hostname | Human-readable relay name shown in the portal under Platform Management → Sites. |
RELAY_CLUSTER_ID |
No | default |
Cluster identifier associated with this relay in the portal. |
RELAY_LISTEN_PORT |
No | 8443 |
TCP port the relay listens on for incoming agent connections. |
RELAY_IDENTITY_DIR |
No | /var/lib/cloudsmith-relay/identity |
Path where the relay persists its enrolled identity. Mount a volume here. |
Step 4 — Verify the relay is connected
Check the relay logs immediately after starting the container:
docker logs cloudsmith-relay
On a successful first start you will see both of these log lines:
Relay enrolled: RelayId=relay-01hz...
Relay WebSocket connected to wss://...
On subsequent starts (after identity is already persisted), you will see only the WebSocket connected line — the enrollment line does not repeat.
In the portal, navigate to Platform Management → Sites. The relay you configured should appear with a status of Connected. If the relay does not appear or shows as Disconnected, see the troubleshooting section below.
Upgrading the relay
The relay image is updated independently of the rest of the platform. To update, pull the new image and recreate the container. The named volume preserves the relay identity across the upgrade — no re-enrollment is needed.
docker pull ghcr.io/cloudsmith-cloud/cloudsmith-relay:latest
docker stop cloudsmith-relay
docker rm cloudsmith-relay
docker run -d \
--name cloudsmith-relay \
--restart=always \
-e RELAY_PAAS_URL=https://<your-paas-api-url> \
-e RELAY_AGENT_ENROLLMENT_TOKEN=<your-agent-secret> \
-e RELAY_DISPLAY_NAME=relay-dc1 \
-p 8443:8443 \
-v cloudsmith-relay-identity:/var/lib/cloudsmith-relay/identity \
ghcr.io/cloudsmith-cloud/cloudsmith-relay:latest
Note that RELAY_ENROLLMENT_TOKEN is not required on subsequent starts — remove it from the recreated container’s environment.
Troubleshooting
Relay logs show "enrollment token is invalid or expired".
The portal-issued enrollment token has either been consumed (relay enrolled once already) or the 24-hour window has passed. Generate a new token: Platform Management → Sites → select the site → Generate Token.
Relay shows as Disconnected in the portal immediately after starting. Confirm outbound HTTPS 443 from the relay host to the PaaS API URL is not blocked. Test with:
curl -I https://<your-paas-api-url>/health
Agents cannot connect on port 8443.
Confirm the relay is listening: docker port cloudsmith-relay. Confirm no host-level firewall (ufw, iptables, or cloud security group) is blocking inbound TCP 8443 from the Hyper-V host subnet.
Relay restarts but enrollment re-triggers every time.
The identity volume is not persisted between container runs. Confirm the named volume exists (docker volume ls | grep relay) and that the container run command includes -v cloudsmith-relay-identity:/var/lib/cloudsmith-relay/identity. Without the volume mount, identity is written inside the container layer and lost on each restart.
Next step
With the relay running, install the CloudSmith Agent on each Hyper-V host that the relay should manage: Install the CloudSmith Agent.