Quick tour
A short walkthrough of Circloud® NEST.
Download
Download the latest installer bundles for Windows and Linux from the official download page:
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.
You need three things from Cloudflare:
- A domain added to your Cloudflare account
- Your Account ID
- 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
- Go to dash.cloudflare.com
- Click your profile icon (top right) → My Profile → API Tokens
- Click Create Token
- Click Get started next to Create Custom Token
- Give it a name (e.g. "Circloud NEST")
- Add these permissions:
- Account > Cloudflare Tunnel > Edit
- Account > Access: Apps and Policies > Edit
- Zone > DNS > Edit
- Under Account Resources, select Include > your account
- Under Zone Resources, select Include > Specific zone > your domain
- Click Continue to summary → Create Token
- Copy the token immediately — it is only shown once
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:
- System Check — verifies Administrator privileges, WSL2, Hyper-V, and system resources
- Install Mode — choose Create Hyper-V VMs or Use Existing Servers
- Configuration — set CPU cores, memory, number of nodes, and network switches
- Cloudflare — enter your Account ID, API Token, and domain
- Review & Install — confirm and start deployment
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.
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 binarylab-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) - Role —
control,worker, orstorage - IPv4 — the node's IP address on your network
- Username / Password — SSH credentials with sudo privileges
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.
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.
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.
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:
| Header | Who uses it | Purpose |
|---|---|---|
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.
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.
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 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.
| Field | Required | Description |
|---|---|---|
name | Yes | Tenant name (used for login and tenant isolation) |
password | No | Password for User GUI login (min 8 chars) |
max_pods | No | Maximum number of pods |
max_vpcs | No | Maximum number of VPCs |
max_subnets | No | Maximum number of subnets |
max_cpu | No | Maximum CPU cores |
max_ram | No | Maximum RAM in GB |
max_storage | No | Maximum 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.
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.
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
Log into the Dashboard
Visit the Circloud portal and log in with your tenant credentials.
Copy Your Tenant ID and API Token
Your credentials are displayed at the top of the dashboard. Click to copy them.
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
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.
Creating a VPC
Navigate to the VPCs tab and click "Create VPC". Enter a name and choose whether to enable internet access.
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.
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 |
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.
Creating a Subnet
Navigate to the Subnets tab and click "Create Subnet". Select a VPC, enter a name, CIDR block, and gateway IP.
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.
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.
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.
| Column | Meaning |
|---|---|
| Priority | Evaluation order (1–2000). The lowest number is checked first; the first matching rule wins. |
| Direction | ingress (traffic into your pods) or egress (traffic out of your pods) |
| Action | allow or deny the matched traffic |
| Protocol / Ports | tcp, udp, icmp, or all. Ports (e.g. 443, 8000-9000, or a comma list) apply only to tcp and udp; blank means all ports. |
| Remote | The other end of the connection: an IPv4 CIDR (0.0.0.0/0 is the internet) or another of your VPCs |
| Target | What the rule protects inside the VPC: all pods in the VPC, one subnet, or specific pods |
| Enabled | A 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.
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.
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.
Adding Registry Credentials
Navigate to the Registry tab and click "Add Registry". Enter a name, server URL, username, and password or token.
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.
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_accessenables outbound internet,external_inboundenables bidirectional access with a floating IP. - GPU access — Pods can request GPU resources on nodes that have GPUs configured. Set
gpu_access: trueto 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.
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.
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.
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.
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.
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.
| Probe | Meaning |
|---|---|
| 🟢 | 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
| Status | Meaning |
|---|---|
ready | Pod is running and Ready condition is true |
not_ready | Pod is running but not Ready |
pending | Pod is being scheduled or pulling images |
failed | Pod has failed or is in an Unknown phase |
unknown | Status 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.
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.
Creating a Tunnel
Navigate to the Tunnels tab and click "Create Tunnel". Select a pod and configure the tunnel hostname and port settings.
Using Custom Domains
If custom domains have been assigned, you can use them:
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
}
]
}
]
}
- 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
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
- Request — the tenant submits a domain request from the Domains tab in the User GUI
- Pending — the request appears in the admin dashboard awaiting approval
- Approval — the admin approves the domain from the CloudManager Tenants section
- 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.
Exporting Your Topology
From the Topology tab, you can view your current infrastructure as JSON and download it for backup or version control.
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.
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.
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.
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.
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.
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.
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.
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.
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.