Quick tour

A short walkthrough of Circloud® NEST.

Download

Download the latest installer bundles for Windows and Linux from the official download page:

nest.circloud.net/download

Cloudflare Cloudflare Setup

Circloud® NEST uses outbound-only Cloudflare Tunnels to expose your platform to the internet. No inbound ports need to be opened and no public IP is required. The tunnel manager handles everything automatically — tunnel creation, DNS records, and access policies. You just need to provide an API token with the right permissions.

Free — Cloudflare accounts and tunnel usage are completely free. No paid plan is required.

You need three things from Cloudflare:

  1. A domain added to your Cloudflare account
  2. Your Account ID
  3. An API Token

Finding your Account ID

Go to dash.cloudflare.com, select your domain, and find the Account ID on the right side of the Overview page.

Creating the API Token

  1. Go to dash.cloudflare.com
  2. Click your profile icon (top right) → My ProfileAPI Tokens
  3. Click Create Token
  4. Click Get started next to Create Custom Token
  5. Give it a name (e.g. "Circloud NEST")
  6. Add these permissions:
    • Account > Cloudflare Tunnel > Edit
    • Account > Access: Apps and Policies > Edit
    • Zone > DNS > Edit
  7. Under Account Resources, select Include > your account
  8. Under Zone Resources, select Include > Specific zone > your domain
  9. Click Continue to summaryCreate Token
  10. Copy the token immediately — it is only shown once
You do not need to create any tunnels, DNS records, or access policies manually. The Circloud® NEST tunnel manager creates and manages all of these automatically using the API token. The three permissions above are needed so the platform can programmatically create tunnels (Cloudflare Tunnel), set up DNS records for subdomains (DNS), and configure access rules (Access: Apps and Policies) on your behalf.

Installation

Circloud® NEST provisions its own cluster and private networking stack on your hardware. The installer handles everything: cluster deployment, GUI/API setup, VPC/subnet routing, and Cloudflare tunnels.

Prerequisites

Single Desktop PC (Windows with Hyper-V)

  • RAM: 32 GB minimum (the installer creates multiple VMs)
  • CPU: 8+ cores with virtualization support (VT-x / AMD-V)
  • Disk: 200+ GB free space for VMs and images
  • OS: Windows 10/11 Pro or Enterprise (Hyper-V required)
  • Network: Internet connection for downloading packages and Cloudflare tunnel access
  • Cloudflare: A Cloudflare account with a registered domain and an API token (see Cloudflare Setup)

Multiple Linux Servers

For production or dedicated hardware, you need at least 4 servers:

  • Per server: 4+ GB RAM, 2+ CPU cores, 50+ GB disk, Ubuntu 22.04+
  • Roles: 1 control plane + 3 workers (optionally 1 storage node for the container registry)
  • Network: All servers on the same network with internet access and SSH enabled
  • Cloudflare: Same as above — a domain, Account ID, and API token

How far it scales

A single cluster scales to 100 servers — one private cloud, on your own hardware. Start with one machine and add servers as you grow; each new server joins the same cluster and the same networking, with no rebuild and no migration.

  • Start: one machine — a Core i9 with 96 GB RAM carries ~2,000 concurrent users
  • Grow: add servers at any time with Extend
  • Scale: up to 100 servers per cluster; beyond that, run a second cluster

GPU Support (Optional)

To enable GPU workloads, mark specific worker nodes with gpu: true in the installer wizard (Windows) or lab-config.yaml (Linux) before running the installer. The installer automatically installs NVIDIA drivers and configures the container runtime. Pods can then request GPU access by setting gpu_access: true.

Install on Windows

Step 1: Download

Download circloud-installer.exe from nest.circloud.net/download.

Step 2: Run as Administrator

Right-click circloud-installer.exe and select Run as Administrator. The graphical setup wizard will open and guide you through:

  1. System Check — verifies Administrator privileges, WSL2, Hyper-V, and system resources
  2. Install Mode — choose Create Hyper-V VMs or Use Existing Servers
  3. Configuration — set CPU cores, memory, number of nodes, and network switches
  4. Cloudflare — enter your Account ID, API Token, and domain
  5. Review & Install — confirm and start deployment
Administrator required: The installer needs Administrator privileges to manage Hyper-V VMs and configure networking. It will fail without elevation.

The installer handles everything: base image preparation, VM provisioning, cluster deployment, CloudManager GUI/API/DB, and Cloudflare tunnels. If a reboot is needed (e.g. Hyper-V activation), it saves progress and resumes automatically.

Step 3: Access the Platform

After installation completes:

Admin Credentials

The installer generates a random admin password and saves all credentials to state/.credentials.json. To find your admin login:

cat state/.credentials.json | python3 -m json.tool

Look for the cloudmanager_admin section — it contains your username and password for the Admin GUI. The username defaults to the value of admin_user in lab-config.yaml.

Keep this file safe. It contains all platform credentials including database passwords, Harbor registry credentials, and the admin API token.

Access URLs

Local Access

API: https://localhost:8080
Admin GUI: https://localhost:8443
User GUI: https://localhost:8444

Public Access (via Cloudflare)

API: https://api.<your-domain>
Admin GUI: https://admin.<your-domain>
User GUI: https://user.<your-domain>

Install on Linux Servers

Step 1: Download and Extract

Download the Linux bundle from nest.circloud.net/download and extract it:

tar -xf circloud-<version>.tar.gz
cd circloud

The extracted folder contains:

  • circloud-installer — the installer binary
  • lab-config.yaml — cluster configuration (Cloudflare credentials, DNS, GPU settings)
  • state/template_vm-facts.json — server inventory template

Step 2: Prepare the Server Inventory

Copy the bundled template and fill in your server details:

cp state/template_vm-facts.json state/vm-facts.json

Edit state/vm-facts.json — for each node provide:

  • Name — node identifier (e.g. cp, w1, w2)
  • Rolecontrol, worker, or storage
  • IPv4 — the node's IP address on your network
  • Username / Password — SSH credentials with sudo privileges
All nodes must have SSH enabled and the user must have sudo privileges. Nodes should be on the same network and reachable from the machine running the installer.

Step 3: Configure (Optional)

Edit lab-config.yaml if you need to pre-fill Cloudflare credentials or enable GPU on specific nodes. Otherwise the installer will prompt for Cloudflare details during installation.

Step 4: Run the Installer

./circloud-installer --vm-facts state/vm-facts.json

The installer deploys the full platform: the cluster itself, CloudManager API/GUI/DB, container registry, monitoring, and Cloudflare tunnels.

Step 5: Access the Platform

After installation completes:

Admin Credentials

The installer generates a random admin password and saves all credentials to state/.credentials.json. To find your admin login:

cat state/.credentials.json | python3 -m json.tool

Look for the cloudmanager_admin section — it contains your username and password for the Admin GUI.

Keep this file safe. It contains all platform credentials including database passwords, Harbor registry credentials, and the admin API token.

Access URLs

Local Access

API: https://localhost:8080
Admin GUI: https://localhost:8443
User GUI: https://localhost:8444

Public Access (via Cloudflare)

API: https://api.<your-domain>
Admin GUI: https://admin.<your-domain>
User GUI: https://user.<your-domain>

Getting Started

Welcome to Circloud! This guide will help you get started with deploying and managing your cloud infrastructure. Create Virtual Private Clouds (VPCs), subnets, pods, and Cloudflare tunnels to expose your services.

Your Resources: You can manage VPCs, subnets, pods, tunnels, and registry credentials from your dashboard. All resources are isolated within your environment.

VPCs

Create isolated virtual networks with optional internet access. Each VPC is completely isolated from other tenants.

Subnets

Divide your VPC into logical network segments with custom CIDR blocks.

Pods

Deploy containerized applications with auto-scaling replicas and load balancing.

Tunnels

Expose your services securely to the internet via Cloudflare tunnels.

Customizing Table Views

Every table in the dashboard has a View section with column toggles. Click the checkboxes to show or hide specific columns. This lets you focus on the information that matters most for your current task. Your column preferences are remembered within the session.

Admin Login

After installation, the first thing to do is log in to the CloudManager admin dashboard. This is where you manage tenants, configure the platform, monitor infrastructure, and control Cloudflare tunnels.

Getting Your Admin Credentials

The installer generates a random admin password during installation and displays it at the end of the process. You must copy and save these credentials before closing the installer.

The credentials are also saved to state/.credentials.json. To retrieve them later:

cat state/.credentials.json | python3 -m json.tool

Look for the cloudmanager_admin section — it contains your username and password.

Keep this file safe. It contains all platform credentials including database passwords, Harbor registry credentials, and the admin API token. Do not commit it to version control.

Accessing the Admin Dashboard

Open the CloudManager admin dashboard at https://admin.<your-domain> (or https://localhost:8443 locally) and log in with your admin username and password.

Admin API Token

The state/.credentials.json file also contains an admin API token (in the cloudmanager_admin.api_token field). This token is used for privileged API endpoints that require the X-Admin-Token header — such as creating tenants, managing service tunnels, and configuring global settings.

There are two types of authentication in the API:

HeaderWho uses itPurpose
X-Auth-Token Tenants Manage VPCs, subnets, pods, tunnels within the tenant's scope
X-Admin-Token Platform admin Create/delete tenants, manage service tunnels, approve domains, configure provider settings

AI Agent Integration

Skip the manual setup entirely. Point your AI coding agent — Claude Code, Cursor, Copilot Workspace, or anything else that speaks HTTP — at Circloud® NEST and it can provision tenants, VPCs, subnets, pods, and Cloudflare tunnels by calling the REST API directly. No clicking through dashboards, no hand-rolled infrastructure commands. The agent reads your code, builds the image, pushes it, then creates everything else automatically.

Drop the CIRCLOUD_NEST_API.md file into your project (next to your README.md or in a docs/ folder). It is the complete API reference — tenants, VPCs, subnets, pods, tunnels, domains, topology — in a single markdown document an LLM can ingest in one shot. The API itself is a standard FastAPI service, so an OpenAPI schema is also available at /openapi.json if your agent prefers a machine-readable contract. Either way the agent has everything it needs to provision the infrastructure your app needs and put it on the public internet, end to end, in under a minute.

⬇ Download CIRCLOUD_NEST_API.md ⬇ Download deployable app template (.zip)

Prefer to skip the boilerplate? The deployable app template is a working starter project — a Node.js HTTP service backed by a PostgreSQL pod, plus deploy.sh / upgrade.sh / destroy.sh that talk to the Circloud Nest API and a topology.json that wires VPC, subnets, pods, and a public Cloudflare tunnel. CIRCLOUD_NEST_API.md is bundled at the root so the agent has the full reference next to the code it's writing. Tell your agent: "unzip this template and adapt demo-app/ and cloud/topology.json to build my project, then run cloud/deploy.sh." That's the shortest path from an empty repo to a Nest-deployed application running on the public internet.

AI Agent
1
Generate Code
Analyzes requirements and writes application code
2
Build Image
Builds Docker image and pushes to registry
3
Deploy to Circloud® NEST

Example prompt

Build a gaming website with online payments
that auto-heals and auto-scales, then deploy
it on Circloud Nest using the endpoints in
CIRCLOUD_NEST_API.md, and expose it under the
subdomain games.
Want infrastructure as code? The same API also accepts a topology JSON document — see the Topology section. Your agent can produce that JSON, version-control it alongside your code, and re-apply it on every deploy.

Create Account

Circloud® NEST is multi-tenant. Each tenant gets isolated VPCs, subnets, pods, and tunnels. Before tenants can use the platform, you need to create their accounts. You can optionally set resource limits (max pods, VPCs, subnets, CPU, RAM, storage) per tenant.

In the CloudManager admin dashboard, go to the Tenants tab and click Create Tenant. Enter a tenant name and password. You can also set resource limits. The platform generates a Tenant ID and API Token that the tenant uses to log in and interact with the API.

Create Tenant from Admin Dashboard
Creating a tenant from the CloudManager admin dashboard

Create a tenant using the admin API token:

curl -k -X POST https://api.<your-domain>/tenants   -H "X-Admin-Token: YOUR_ADMIN_TOKEN"   -H "Content-Type: application/json"   -d '{
    "name": "my-tenant",
    "password": "tenant-password-here",
    "max_pods": 50,
    "max_vpcs": 5,
    "max_subnets": 10,
    "max_cpu": 16,
    "max_ram": 32,
    "max_storage": 100
  }'

The response includes the tenant's id and api_token.

FieldRequiredDescription
nameYesTenant name (used for login and tenant isolation)
passwordNoPassword for User GUI login (min 8 chars)
max_podsNoMaximum number of pods
max_vpcsNoMaximum number of VPCs
max_subnetsNoMaximum number of subnets
max_cpuNoMaximum CPU cores
max_ramNoMaximum RAM in GB
max_storageNoMaximum storage in GB

Self-Service Signup

When self-service signup is enabled in the admin settings, tenants can register directly from the User GUI login page. They choose a name and password, and receive their credentials immediately.

Self-service tenant registration
Self-service tenant registration from the User GUI login page

User Login

Tenants log in to the User GUI at https://user.<your-domain> (or https://localhost:8444 locally) using the tenant name and password created by the admin or via self-service signup.

User GUI login screen
User GUI Login

Setup & API Access

Each tenant has a Tenant ID and API Token for authenticating with the Circloud® NEST API. These are shown on the dashboard after logging in.

Step 1: Get Your Credentials

1

Log into the Dashboard

Visit the Circloud portal and log in with your tenant credentials.

2

Copy Your Tenant ID and API Token

Your credentials are displayed at the top of the dashboard. Click to copy them.

CloudUser Authentication tab with tenant credentials
Tenant Authentication (ID + API Token)

Configure API Access

Use your API token with any HTTP client (curl, Postman, Python requests, etc.):

# Set your credentials
export TENANT_ID="your-tenant-id"
export API_TOKEN="your-api-token"
export API_URL="https://api.YOUR_DOMAIN"

# Test API access
curl -k -X GET "$API_URL/tenants/$TENANT_ID/vpcs" \
  -H "X-Auth-Token: $API_TOKEN"

API Roles and Tokens

Circloud exposes two authentication scopes:

Scope Header Used For
Admin X-Admin-Token Tenant lifecycle, domains, provider config, service tunnels
Tenant X-Auth-Token VPCs, subnets, pods, tunnels, topology

Many create endpoints also expect the token field in the JSON body. The header is still required and is the primary authentication check.

Deploy Using Topology JSON

Create a topology.json file to define your infrastructure:

{
  "token": "YOUR_API_TOKEN",
  "vpcs": [
    {
      "name": "my-vpc",
      "description": "My VPC",
      "enable_internet": true
    }
  ],
  "subnets": [
    {
      "name": "my-subnet",
      "vpc_name": "my-vpc",
      "cidr": "10.100.1.0/24",
      "gateway_ip": "10.100.1.1"
    }
  ],
  "pods": [
    {
      "name": "my-app",
      "vpc_name": "my-vpc",
      "subnet_name": "my-subnet",
      "container_image": "nginx:latest",
      "replica_count": 2,
      "service_port": 80,
      "external_access": true,
      "auto_scaling": true,
      "autoscale_max_replicas": 6,
      "autoscale_cpu_target_millicores": 250
    }
  ]
}

Deploy with a single command:

curl -k -X POST "$API_URL/tenants/$TENANT_ID/topology" \
  -H "Content-Type: application/json" \
  -d @topology.json
Tip: Store your topology.json in version control to track infrastructure changes over time.

Using Private Container Registries

To pull images from private registries (Docker Hub, Harbor, etc.), add registry credentials:

{
  "token": "YOUR_API_TOKEN",
  "registry_credentials": [
    {
      "name": "dockerhub",
      "server": "https://index.docker.io/v1/",
      "username": "your-username",
      "password": "your-access-token"
    }
  ],
  "vpcs": [...],
  "subnets": [...],
  "pods": [...]
}

Virtual Private Clouds (VPCs)

A VPC is an isolated virtual network where you deploy your resources. Each VPC has its own routing table and is completely isolated from other VPCs.

CloudUser VPCs tab
VPCs Tab

Creating a VPC

Navigate to the VPCs tab and click "Create VPC". Enter a name and choose whether to enable internet access.

Create VPC form
Create VPC
curl -k -X POST https://api.YOUR_DOMAIN/vpcs \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "YOUR_TENANT_ID",
    "token": "YOUR_TOKEN",
    "name": "production-vpc",
    "enable_internet": true
  }'

Deleting a VPC

Click the delete button (×) on any VPC card to remove it. This is a cascade delete — all subnets, pods, tunnels, DNS records, and persistent storage within the VPC are permanently removed. This action cannot be undone.

Warning: Deleting a VPC destroys all resources inside it, including running pods and their data. Make sure to back up any important data before deleting.

Core Services Subnet

Every VPC automatically includes a managed core subnet reserved for platform services. This subnet is created and maintained by Circloud and is not intended for user workloads.

  • Hosts tenant-dns pods (2 replicas) for internal name resolution
  • Hosts tunnel-service (cloudflared) pods when you create tunnels
  • Provides stable VIP addresses used by DNS records

Internet Access

When you enable internet access on a VPC, Circloud configures external routing so pods can be granted outbound or inbound connectivity. Internet access is controlled at the VPC level and refined per pod.

Setting Scope Effect
enable_internet VPC Enables external routing so EIP, SNAT, and FIP can be allocated
external_access Pod Allocates an EIP and SNAT for outbound internet
external_inbound Pod Creates a FIP for bidirectional inbound/outbound access
Note: external_inbound requires external_access=true. For HTTP/HTTPS services, Cloudflare tunnels are often simpler than direct inbound IPs.

Subnets

Subnets divide your VPC into smaller network segments. Each subnet has its own CIDR block and can host multiple pods.

CloudUser Subnets tab
Subnets Tab

Creating a Subnet

Navigate to the Subnets tab and click "Create Subnet". Select a VPC, enter a name, CIDR block, and gateway IP.

Create Subnet form
Create Subnet
curl -k -X POST https://api.YOUR_DOMAIN/subnets \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "YOUR_TENANT_ID",
    "token": "YOUR_TOKEN",
    "vpc_id": "VPC_ID",
    "name": "web-tier",
    "cidr": "10.100.1.0/24",
    "gateway_ip": "10.100.1.1"
  }'

Deleting a Subnet

Click the delete button (×) on any subnet to remove it. All pods within the subnet are deleted along with their tunnels and persistent storage. Core subnets (managed by the platform) cannot be deleted.

CIDR Planning: Plan your CIDR blocks carefully. Subnets within the same VPC should not overlap. Common patterns include /24 subnets (254 usable IPs) for most workloads.

Security Rules

Security rules are a per-VPC firewall for your workloads. Each rule allows or denies ingress or egress traffic between a remote (an IPv4 CIDR — 0.0.0.0/0 is the internet, i.e. every address — or another of your VPCs) and a target inside the VPC (the whole VPC, one subnet, or specific pods), for a protocol and optional ports. Every VPC gets its own rule set, managed from the Security tab inside the VPC.

VPC Security tab with priority-ordered firewall rules
Security Tab (per-VPC firewall rules)

How Rules Are Evaluated

  • Lowest priority wins — rules are evaluated in priority order (1–2000), lowest number first, and the first match decides.
  • Deny beats allow — at the same priority, a deny rule is evaluated before an allow.
  • Implied baseline — three fixed implied rules frame everything you write: always allow the VPC's own core network (the platform's DNS, tunnels and load balancers, in both directions — no rule can block it, so a deny never takes out your own DNS), and beneath your rules allow all outbound and deny all other inbound. They cannot be edited, reordered, or deleted, and the panel shows them as a static note.
  • Seeded rule — every new VPC starts with one ordinary rule, Allow internal traffic (priority 2000), so pods in the VPC can reach each other. It is editable, disableable, and deletable like any other rule; deleting it leaves you with exactly the implied baseline.

Managing Rules

Open the VPCs tab, select a VPC, and switch to its Security tab. Click +Rule to add a rule — pick a direction, action, priority, protocol and ports, remote, and target. Use the pencil to edit a rule, the × to delete it, and the Enabled checkbox to keep a rule while pausing its enforcement. To reorder rules, edit their priorities — the lowest number is evaluated first. The direction dropdown filters the table to ingress or egress rules.

ColumnMeaning
PriorityEvaluation order (1–2000). The lowest number is checked first; the first matching rule wins.
Directioningress (traffic into your pods) or egress (traffic out of your pods)
Actionallow or deny the matched traffic
Protocol / Portstcp, udp, icmp, or all. Ports (e.g. 443, 8000-9000, or a comma list) apply only to tcp and udp; blank means all ports.
RemoteThe other end of the connection: an IPv4 CIDR (0.0.0.0/0 is the internet) or another of your VPCs
TargetWhat the rule protects inside the VPC: all pods in the VPC, one subnet, or specific pods
EnabledA disabled rule is kept but not enforced

All security-rule endpoints authenticate with your tenant token (X-Auth-Token), and all enum values (direction, action, protocol, remote_type, target_type) are lowercase. List a VPC's rules in evaluation order:

curl -k -X GET "https://api.YOUR_DOMAIN/security-rules?vpc_id=VPC_ID" \
  -H "X-Auth-Token: YOUR_TOKEN"

Create a rule — for example, allow inbound HTTPS from the internet to the whole VPC:

curl -k -X POST https://api.YOUR_DOMAIN/security-rules \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vpc_id": "VPC_ID",
    "name": "allow-https-from-internet",
    "direction": "ingress",
    "action": "allow",
    "priority": 100,
    "protocol": "tcp",
    "ports": "443",
    "remote_type": "cidr",
    "remote_cidr": "0.0.0.0/0",
    "target_type": "vpc"
  }'

Every mutation saves the rule and then applies it to the VPC's network, and the response reports the result: applied: true means the rule is in force, applied: false means it is saved but not yet in force (apply_error says why) — the platform retries automatically every few minutes.

The full reference — get, update, delete, and bulk reorder, with every parameter, validation rule, and error shape — is in CIRCLOUD_NEST_API.md under Security Rules.

Admin Read-Only View

Admins get the same table as a support view: in the CloudManager dashboard, open Tenants, select a tenant, open one of its VPCs, and switch to the Security tab. The view is read-only — no add, edit, or toggle — and is rendered from the same payload the tenant sees, so admin and tenant can never disagree about what is enforced.

CloudManager read-only firewall rules support view
Admin support view (Firewall Rules, read-only)

DNS & Service Discovery

Each VPC includes a dedicated DNS service (dnsmasq) running in the core subnet. The platform configures pod DNS settings so service names resolve inside the VPC, while external domains are forwarded to the provider DNS servers.

Resolution Flow

pod -> tenant-dns (core subnet) -> external DNS forwarder

Record Format

Pods and VIP services are registered automatically. Names are stable even when pods restart.

web.my-tenant
web

HA for DNS

DNS runs two replicas in the core subnet. Pods are configured with both DNS IPs when available, providing resilience if one replica is unavailable.

Provider DNS Settings

External DNS servers and the ndots setting come from provider configuration. For self-hosted labs, these map to pod_dns_nameservers and pod_dns_ndots in your configuration.

Registry Credentials

Registry credentials let your pods pull private images. Credentials are stored in the tenant database and synchronized to a platform credential named <tenant>-registry-creds, which is attached to your pods automatically.

When do you need this? If your container images are hosted on public Docker Hub (e.g. nginx:latest, postgres:16), no registry credentials are needed. You only need to add registry credentials when pulling from private registries like Harbor, GitHub Container Registry (ghcr.io), AWS ECR, or private Docker Hub repositories.
CloudUser Registry tab
Registry Credentials

Adding Registry Credentials

Navigate to the Registry tab and click "Add Registry". Enter a name, server URL, username, and password or token.

Add Registry form
Add Registry Credentials
curl -k -X POST https://api.YOUR_DOMAIN/tenants/TENANT_ID/registry-credentials \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dockerhub",
    "server": "https://index.docker.io/v1/",
    "username": "myuser",
    "password": "mytoken"
  }'

Reusing a credential name updates the existing entry. Listing credentials hides passwords in responses. Pods use these credentials when use_registry_credentials is true (default).

Pods

Pods are the deployable units that run your containerized applications. Each pod can have multiple replicas for high availability and automatic load balancing.

CloudUser Pods tab
Pods Tab

Pod Features

When creating a pod, you can configure these capabilities:

  • Auto-healing — When enabled, Circloud automatically restarts pods that crash or become unresponsive. The platform monitors pod health and recreates failed containers without manual intervention.
  • Auto-scaling — Pods can scale horizontally based on CPU or memory usage. Set minimum and maximum replica counts, and the platform adjusts automatically based on load.
  • Persistent storage — Pods can request node-local persistent storage. Storage is created under /storage/<tenant-id>/<pod-id> and mounted into the container. Persistent pods are pinned to a single worker node.
  • Replicas — Run multiple identical copies of a pod for redundancy and load distribution. Traffic is automatically balanced across replicas via the internal load balancer.
  • Internet access — Controlled at pod level. external_access enables outbound internet, external_inbound enables bidirectional access with a floating IP.
  • GPU access — Pods can request GPU resources on nodes that have GPUs configured. Set gpu_access: true to schedule the pod on a GPU-enabled worker.

Creating a Pod

Navigate to the Pods tab and click "Create Pod". Select a subnet, enter a name, image, and configure replicas, ports, and optional tunnel settings.

Create Pod form
Create Pod (with Tunnel)

Pod Actions (Actions Column)

Actions appear on the first row of each pod group.

Icon Action
Start a stopped pod workload
Stop the pod workload
Restart the pod workload
+ Add a replica (up to 10)
× Remove a replica (minimum 1)
📋 View pod logs with colorized output, copy, and download
🗑 Delete the pod and all its resources (VPCs, subnets, tunnels, persistent storage are removed in cascade)

The amber × is for replica removal; the red × is for deleting the pod.

When autoscaling is enabled, manual replica changes are ignored and the platform controls scaling.

Viewing Logs

Click the logs button on any pod to open the colorized logs viewer. You can copy logs to clipboard or download them as a text file. Logs are fetched in real-time from the running container.

Service VIPs and Replicas

Circloud creates a VIP service for each pod group. For single pods, the VIP provides a stable IP. For replicas, one VIP load-balances traffic across all replicas.

The Service IP column in the GUI shows this VIP address.

replica pods: api-0, api-1, api-2
VIP service: api -> 10.x.x.x (stable VIP)
curl -k -X POST https://api.YOUR_DOMAIN/pods \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "YOUR_TENANT_ID",
    "token": "YOUR_TOKEN",
    "vpc_id": "VPC_ID",
    "subnet_id": "SUBNET_ID",
    "name": "web-server",
    "container_image": "nginx:latest",
    "replica_count": 2,
    "service_port": 80,
    "external_access": true,
    "external_inbound": true,
    "auto_scaling": true,
    "autoscale_max_replicas": 6,
    "autoscale_cpu_target_millicores": 250
  }'

Pod Options

Option Description
replica_count Replica count (1-10). If auto_scaling is true, this is the initial replica count (min 2)
service_port VIP service port for load balancing and tunnels (default 80)
use_registry_credentials Use tenant registry secret for image pulls (default true)
external_access Enable outbound internet via SNAT
external_inbound Enable inbound access with external IP
auto_healing Auto-restart pods on failure
auto_scaling Enable automatic scaling (CPU-based)
autoscale_max_replicas Maximum replicas when autoscaling (default 10)
autoscale_cpu_target_millicores Target average CPU usage per pod in millicores (default 200)

Automatic Scaling

Enable auto_scaling to have the platform add and remove replicas automatically, based on average CPU usage. Auto-healing is implied (the platform manages the replica set for you), and manual replica changes are disabled. The replica_count is treated as the initial value and clamped to the autoscale min/max. When autoscaling is enabled, the minimum replica count is always 2.

Edit Pod Configuration

You can modify pod settings after creation by clicking the edit icon in the flags column. This opens the Pod Configuration modal where you can toggle auto-healing, persistent storage, and auto-scaling without recreating the pod.

Pod Configuration edit modal
Edit Pod Configuration
Note: Enabling auto-scaling automatically enables auto-healing. Disabling auto-healing also disables auto-scaling. There is brief downtime during the workload recreation.

Console Access

You can access a terminal inside your running pods using the console feature. Click the green terminal icon (>_) next to any running pod to open a web-based terminal. Console access is only available when the pod is in a Ready state.

Console button highlighted on a pod row
Click the green terminal icon on the pod row
Console modal
Pod Console (web terminal)

The terminal opens an interactive /bin/sh session via a WebSocket connection. If your image does not include /bin/sh, use a base image that provides a shell.

# Example commands inside the console
whoami
df -h
ls -la /storage

Pod Logs

The pod logs panel shows real-time container output, making it an essential tool for debugging application issues, monitoring startup sequences, and inspecting runtime behaviour.

Logs button highlighted on a pod row
Click the logs icon on the pod row to open the panel
Pod Logs panel
Real-time pod log viewer

To view logs, click the logs icon (document icon) next to a pod in the Pods table. This opens the logs panel, which streams container output in real-time. You can scroll through the log history to inspect earlier output.

Via API

You can also retrieve pod logs programmatically using the CloudManager API:

# Fetch the last 100 lines of logs for a pod
curl -H "Authorization: Bearer $API_KEY" \
  https://your-cloudmanager/api/pods/{pod_id}/logs?lines=100

The lines query parameter controls how many tail lines to return (1–5000, default 100). The response is plain text containing the raw container log output.

Monitoring

Pod status is refreshed by a monitoring service that polls the cluster and writes status records to the CloudManager database. The dashboard displays per-replica status, IP address, and restart count.

CloudUser Monitoring tab
Monitoring & Pod Status

Live Metrics

The monitoring dashboard shows real-time resource usage for each pod:

  • CPU — current CPU usage in millicores with a visual progress bar
  • RAM — memory usage in MB with a visual progress bar
  • Storage — disk usage for persistent pods

Metrics are collected by the resource monitor service running inside the cluster and updated every few seconds in the dashboard.

Node Monitoring

The admin dashboard shows node-level metrics including CPU, RAM, and disk usage per node. Node status probes indicate whether the monitoring data is fresh, stale, or offline.

Status Probes

Probes are shown as colored indicators in the Pods, System Pods, and Nodes tables. Click a probe to see detailed status information including phase, IP, reason, and error messages.

Pod status probe popover
Click a probe to see status details

ProbeMeaning
🟢Ready / Fresh (healthy)
🟡Pending / Not Ready / Stale
🔴Failed / Offline
Unknown (no data yet)

Node probes are based on the last metrics update time: ≤30s = Fresh (green), ≤60s = Stale (yellow), >60s = Offline (red).

Pod Status States

StatusMeaning
readyPod is running and Ready condition is true
not_readyPod is running but not Ready
pendingPod is being scheduled or pulling images
failedPod has failed or is in an Unknown phase
unknownStatus has not been observed yet

Auto-Healing & Auto-Scaling

When auto_healing is enabled, the platform manages your pods as a supervised workload, so they are automatically recreated on failure. Restart counts in the UI help identify unstable workloads.

When auto_scaling is enabled, the platform manages the replica count for you. The dashboard shows the live replica count as it scales up and down based on CPU usage.

High Availability

For pods with replica_count greater than 1, a VIP service load-balances across replicas. DNS points to the VIP, so clients are insulated from individual pod restarts.

Operations Log

Every mutating operation on the platform is recorded in the Ops Log — creating, deleting, starting, stopping, restarting pods, VPCs, subnets, tunnels, and configuration changes. The log tracks the source (GUI, API, or System), actor (admin or tenant), status (success or failed), and error details for failed operations.

Global Ops Log tab
Global Ops Log with server-side filters and cursor-based pagination

The Ops Log is available at three levels:

  • Global — all operations across all VPCs (main Ops Log tab)
  • VPC-level — operations within a specific VPC (Ops Log tab inside each VPC)
  • Tenant-level — all operations for a tenant (admin dashboard only)

Use the filter dropdowns (Source, Status, Resource Type, Operation) to narrow results. Filters are applied server-side for fast queries even with thousands of entries. Click Load More to fetch the next page of results.

Cloudflare Tunnels

Tunnels provide secure external access to your pods without opening inbound ports. Traffic is routed through Cloudflare's global network, providing DDoS protection, automatic SSL/TLS, and zero-trust access.

When you create a tunnel, Circloud deploys a cloudflared pod in the core subnet, allocates outbound access, and registers DNS records in Cloudflare. The tunnel origin targets the pod DNS name or VIP service.

Tunnel status is tracked as active, inactive, or failed in the dashboard.

CloudUser Tunnels tab
Tunnels Tab

Creating a Tunnel

Navigate to the Tunnels tab and click "Create Tunnel". Select a pod and configure the tunnel hostname and port settings.

Create Tunnel form
Create Tunnel

Using Custom Domains

If custom domains have been assigned, you can use them:

CloudUser Domains tab
Custom Domains (Tenant Domains)
Add Domain form
Add Custom Domain
curl -k -X POST https://api.YOUR_DOMAIN/pods/POD_ID/tunnel \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tunnel_name": "web-app",
    "subdomain": "app",
    "protocol_type": "http",
    "service_port": 80
  }'

# Access at: https://app.yourdomain.com
# Supported protocols: http, https, ssh, tcp, udp

Custom Domain via API

curl -k -X POST https://api.YOUR_DOMAIN/pods/POD_ID/tunnel \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tunnel_name": "custom-tunnel",
    "subdomain": "portal",
    "protocol_type": "http",
    "service_port": 80,
    "domain": "mycompany.com"
  }'

# Access at: https://portal.mycompany.com

Tunnels in Topology JSON

You can also define tunnels inline when deploying pods via the Topology API:

{
  "pods": [
    {
      "name": "web-server",
      "vpc_name": "my-vpc",
      "subnet_name": "my-subnet",
      "container_image": "nginx:latest",
      "service_port": 80,
      "tunnels": [
        {
          "subdomain": "www",
          "protocol_type": "http",
          "service_port": 80
        },
        {
          "subdomain": "ssh",
          "protocol_type": "ssh",
          "service_port": 22
        }
      ]
    }
  ]
}
Protocol Use Cases:
  • HTTP: Websites, REST APIs, webhooks, microservices, admin panels
  • HTTPS: Services with internal SSL, legacy apps, mTLS requirements
  • SSH: Remote administration, SFTP file transfers, Git over SSH, dev access
  • TCP: Databases (PostgreSQL, MySQL, MongoDB, Redis), RDP, custom protocols
  • UDP: Game servers (Source, Minecraft), VoIP (SIP), DNS, QUIC, media streaming
Note: You can only create tunnels using domains that have been approved for your tenant. Contact your administrator to add new custom domains.

Managing Tunnels

View and delete tunnels from the Tunnels tab on your dashboard, or via API:

# List all tunnels
curl -k -X GET https://api.YOUR_DOMAIN/tenants/TENANT_ID/tunnels \
  -H "X-Auth-Token: YOUR_TOKEN"

# Delete a tunnel
curl -k -X DELETE https://api.YOUR_DOMAIN/tunnels/TUNNEL_ID \
  -H "X-Auth-Token: YOUR_TOKEN"

Deleting a Tunnel

Click the delete button (×) on any tunnel row to remove it. The Cloudflare tunnel, DNS record, and access policy are cleaned up automatically. The cloudflared pod running the tunnel is also removed from the cluster.

Custom Domains

By default, tunnels use subdomains of the platform's main domain. Tenants can request custom domains to use with their tunnels.

Domain Workflow

  1. Request — the tenant submits a domain request from the Domains tab in the User GUI
  2. Pending — the request appears in the admin dashboard awaiting approval
  3. Approval — the admin approves the domain from the CloudManager Tenants section
  4. Active — the tenant can now create tunnels using the approved domain

To delete a domain, click the delete button next to it. Any tunnels using that domain will need to be reconfigured.

Topology (Infrastructure-as-Code)

The Topology feature allows you to define your entire infrastructure in JSON and deploy it with a single API call. This is ideal for version control, reproducible deployments, and automation.

The Topology tab displays a visual diagram of your infrastructure and lets you export or import your entire setup as JSON.

CloudUser Topology tab
Topology Tab

Exporting Your Topology

From the Topology tab, you can view your current infrastructure as JSON and download it for backup or version control.

Tip: Use the visual topology diagram in the Topology tab to understand your infrastructure at a glance. The diagram updates in real-time as you make changes.

Deploying a Topology

curl -k -X POST https://api.YOUR_DOMAIN/tenants/TENANT_ID/topology \
  -H "Content-Type: application/json" \
  -d '{
    "token": "YOUR_TOKEN",
    "vpcs": [
      {
        "name": "production",
        "enable_internet": true
      }
    ],
    "subnets": [
      {
        "name": "web",
        "vpc_name": "production",
        "cidr": "10.100.1.0/24",
        "gateway_ip": "10.100.1.1"
      },
      {
        "name": "api",
        "vpc_name": "production",
        "cidr": "10.100.2.0/24",
        "gateway_ip": "10.100.2.1"
      }
    ],
    "pods": [
      {
        "name": "nginx",
        "vpc_name": "production",
        "subnet_name": "web",
        "container_image": "nginx:latest",
        "replica_count": 2,
        "service_port": 80,
        "external_inbound": true,
        "auto_scaling": true,
        "autoscale_max_replicas": 6,
        "autoscale_cpu_target_millicores": 250
      }
    ]
  }'

CloudManager (Admin Portal)

The CloudManager GUI is the admin control plane for the entire cluster. It provides global configuration, tenant lifecycle management, monitoring, and system visibility across every tenant.

Access the Admin GUI locally at https://localhost:8443, or publicly at https://admin.<cloudflare_domain> based on lab-config.yaml.

Auth Tab

Displays the admin API token used for privileged endpoints. Use this token as the X-Admin-Token header when creating tenants or managing global settings.

CloudManager Auth tab
Admin Auth

Cloudflare Tab

Configure Cloudflare integration: API token, account ID, base domain, and Access policy settings. These values are used when creating tunnels and DNS records. Click Save Cloudflare Config to persist the changes.

CloudManager Cloudflare tab
Cloudflare Configuration

Provider Tab

Shows provider networking settings, including external subnet CIDR, gateway, management network, and excluded IP ranges. These values define how external access is allocated for pods.

CloudManager Provider tab
Provider Networking

T.Defaults Tab (Tenant Defaults)

Sets default resource limits for new tenants (pods, storage, VPCs, subnets, CPU, RAM). These defaults are applied when a tenant is created without explicit resource caps. Click Save Defaults to update.

CloudManager Defaults tab
Tenant Defaults

Monitoring Tab

Cluster overview for tenants, VPCs, pods, and node utilization. Includes aggregate CPU/RAM/storage metrics and highlights of high-usage pods to help identify hotspots.

CloudManager Monitoring tab
Monitoring

System Pods Tab

Shows two groups: platform infrastructure pods (networking, DNS, and so on) and Circloud services (API, GUI, monitor). Each row includes status, node, resource usage, VIPs, tunnels, and actions. You can restart or delete workloads when actions are enabled.

CloudManager Platform Pods tab
Platform Pods
CloudManager Circloud pods tab
Circloud Pods

Nodes Tab

Health and utilization for every node, including CPU, RAM, storage, GPU metrics, and network traffic. Use this to confirm node capacity and detect failures.

CloudManager Nodes tab
Nodes

Service Tunnels Tab

Admin-managed tunnels for platform services. Shows protocol, hostname, origin URL, Access policy, and status. Use the delete action to remove a tunnel.

CloudManager Tunnels tab
Service Tunnels

Tenants Tab

Create, search, and delete tenants. The Allow tenant self-signup toggle controls whether the CloudUser login page shows the Create Account option.

  • Create Tenant: Provide name + password, optionally set resource caps.
  • Delete Tenant: Click the × on a tenant card to remove the tenant and all resources.
  • Resources: Set per-tenant limits (pods, storage, VPCs, subnets, CPU, RAM).
  • Domains: Add custom domains to a tenant for tunnel creation.
  • Registry: Manage tenant registry credentials.
  • Topology: View or apply tenant topology JSON.
  • VPCs / Pods: Admin view of tenant networks and workloads, including pod actions.
CloudManager Tenants tab
Tenants
Create Tenant form
Create Tenant (with Resource Limits)