docs: refresh readme and legal info
This commit is contained in:
@@ -1,258 +1,262 @@
|
|||||||
# @serve.zone/cloudly 🚀
|
# @serve.zone/cloudly
|
||||||
|
|
||||||
**Multi-cloud orchestration made simple.** Manage containerized applications across cloud providers with Docker Swarmkit, featuring web dashboards, CLI tools, and powerful APIs.
|
Cloudly is the serve.zone control plane: a TypeScript service and browser dashboard that stores desired infrastructure state, authenticates humans and machines, coordinates clusters, serves an OCI registry, manages workload metadata, and pushes runtime configuration to connected node components.
|
||||||
|
|
||||||
## 🎯 What is Cloudly?
|
## Issue Reporting and Security
|
||||||
|
|
||||||
Cloudly is your command center for multi-cloud infrastructure. It abstracts away the complexity of managing resources across different cloud providers while giving you the power and flexibility you need for modern DevOps workflows.
|
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
||||||
|
|
||||||
### ✨ Key Features
|
## Why It Exists
|
||||||
|
|
||||||
- **🌐 Multi-Cloud Management** - Seamlessly orchestrate resources across Cloudflare, Hetzner, DigitalOcean and more
|
Cloudly is the place where serve.zone operators describe what should run. It does not directly run every workload itself. Instead, it keeps the authoritative desired state in MongoDB and exposes TypedRequest/TypedSocket APIs so runtime components can reconcile that state where the containers actually live.
|
||||||
- **🐳 Docker Swarmkit Integration** - Native container orchestration with production-grade reliability
|
|
||||||
- **🔐 Secret Management** - Secure handling of credentials, API keys, and sensitive configuration
|
|
||||||
- **🎨 Web Dashboard** - Beautiful, responsive UI built with modern web components
|
|
||||||
- **⚡ CLI & API** - Full programmatic control through TypeScript/JavaScript APIs and command-line tools
|
|
||||||
- **🔒 SSL/TLS Automation** - Automatic certificate provisioning via Let's Encrypt
|
|
||||||
- **📊 Comprehensive Logging** - Built-in log aggregation and monitoring capabilities
|
|
||||||
- **🔄 Task Scheduling** - Automated workflows and background job management
|
|
||||||
|
|
||||||
## 🚀 Quick Start
|
The current runtime pattern is reverse-connect:
|
||||||
|
|
||||||
### Installation
|
```text
|
||||||
|
browser / CLI / SDK
|
||||||
```bash
|
-> Cloudly HTTP + TypedSocket API
|
||||||
# Install the main package
|
-> MongoDB-backed managers
|
||||||
pnpm add @serve.zone/cloudly
|
-> S3-backed image and artifact storage
|
||||||
|
<- Coreflow cluster agents connect outward
|
||||||
# Or install the CLI globally
|
-> Docker Swarm reconciliation
|
||||||
pnpm add -g @serve.zone/cli
|
-> Coretraffic routing updates
|
||||||
|
-> Corestore platform resources and backups
|
||||||
# Or just the API client
|
|
||||||
pnpm add @serve.zone/api
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Basic Setup
|
## What Cloudly Manages
|
||||||
|
|
||||||
```typescript
|
Cloudly currently coordinates these areas:
|
||||||
|
|
||||||
|
- **Authentication and identity**: human admin login, JWT identities, machine tokens, and cluster identities.
|
||||||
|
- **Clusters**: desired cluster records and machine users used by Coreflow to authenticate back to Cloudly.
|
||||||
|
- **Services**: workload definitions, image references, domains, ports, scale factors, secret bundles, volumes, and deployment metadata.
|
||||||
|
- **Images and registries**: image metadata, S3-backed image storage, external registry records, and an embedded OCI registry mounted at `/v2`.
|
||||||
|
- **Secrets**: secret groups and bundles that Coreflow flattens into Docker secrets for workloads.
|
||||||
|
- **Domains and DNS**: domain records, DNS entries, and optional domain sync from a dcrouter external gateway.
|
||||||
|
- **Platform bindings**: first-class `database` and `objectstorage` bindings that Coreflow provisions through Corestore.
|
||||||
|
- **Backups**: backup records, service backup/restore requests, scheduled backup tasks, and archive replication handshakes with Coreflow/Corestore.
|
||||||
|
- **BaseOS**: managed BaseOS node registration, heartbeat handling, desired-state response, image build tracking, and image download URLs.
|
||||||
|
- **CoreBuild workers**: selection of external build workers for BaseOS ISO/raw-image artifact generation.
|
||||||
|
- **Node and bare-metal inventory**: Hetzner-backed node creation paths and bare-metal metadata records where configured.
|
||||||
|
- **Dashboard**: a web component UI rendered from `ts_web` with views for clusters, services, images, secrets, domains, DNS, tasks, backups, BaseOS, and settings.
|
||||||
|
|
||||||
|
## Runtime Components
|
||||||
|
|
||||||
|
| Component | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `Cloudly` | Main service coordinator. Creates connectors and managers, then starts the API server. |
|
||||||
|
| `CloudlyServer` | TypedServer/TypedSocket HTTP server, dashboard static server, OCI registry HTTP bridge, and BaseOS HTTP endpoints. |
|
||||||
|
| `MongodbConnector` | SmartData persistence layer for Cloudly records. |
|
||||||
|
| `CloudflareConnector` | Optional Cloudflare account used by ACME DNS-01 when `cloudflareToken` is configured in settings. |
|
||||||
|
| `LetsencryptConnector` | SmartACME certificate issuance and certificate lookup. |
|
||||||
|
| `CloudlyCoreflowManager` | Authenticates Coreflow, returns cluster config payloads, and pushes config updates to connected Coreflow clients. |
|
||||||
|
| `CloudlyRegistryManager` | Embedded OCI registry backed by configured S3 storage, including deploy-on-push metadata updates. |
|
||||||
|
| `CloudlyBaseOsManager` | BaseOS registration, heartbeat, image build orchestration, worker selection, and artifact downloads. |
|
||||||
|
| `CloudlyBackupManager` | Service backup/restore orchestration and remote archive object replication. |
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Cloudly uses `@push.rocks/npmextra` app data and environment mappings. Values can be supplied through environment variables, `.nogit` app-data files, or by constructing `new Cloudly(config)` programmatically.
|
||||||
|
|
||||||
|
Required runtime configuration:
|
||||||
|
|
||||||
|
| Variable | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| `SERVEZONE_ENVIRONMENT` | ACME/runtime environment, currently `production` or `integration`. |
|
||||||
|
| `SERVEZONE_URL` | Public Cloudly hostname without protocol. |
|
||||||
|
| `SERVEZONE_PORT` | Public API/dashboard port as a string. |
|
||||||
|
| `SERVEZONE_SSLMODE` | `none`, `external`, or `letsencrypt`. |
|
||||||
|
| `SERVEZONE_ADMINACCOUNT` | First-run admin bootstrap in `username:password` format. |
|
||||||
|
| `MONGODB_URL` | MongoDB connection URL used by SmartData. |
|
||||||
|
| `MONGODB_NAME` | MongoDB database name. |
|
||||||
|
| `MONGODB_USER` | MongoDB username. |
|
||||||
|
| `MONGODB_PASS` | MongoDB password. |
|
||||||
|
| `S3_ENDPOINT` | S3-compatible endpoint for registry, images, and artifacts. |
|
||||||
|
| `S3_ACCESSKEY` | S3 access key. |
|
||||||
|
| `S3_SECRETKEY` | S3 secret key. |
|
||||||
|
| `S3_BUCKET` | S3 bucket name. |
|
||||||
|
| `S3_PORT` | S3 endpoint port. |
|
||||||
|
| `S3_USESSL` | Boolean SSL flag for the S3 endpoint. |
|
||||||
|
|
||||||
|
Common optional settings are stored through the Cloudly settings manager rather than direct environment variables:
|
||||||
|
|
||||||
|
| Setting | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| `cloudflareToken` | Enables Cloudflare-backed ACME DNS-01 challenges. |
|
||||||
|
| `hetznerToken` | Enables Hetzner node and bare-metal provisioning paths. |
|
||||||
|
| `baseosJoinToken` | Allows BaseOS devices to enroll without a one-time image provisioning token. |
|
||||||
|
| `corebuildWorkersJson` | JSON array of CoreBuild worker URLs or `{ "url", "token", "id" }` objects. |
|
||||||
|
| `corebuildWorkerUrl` / `corebuildWorkerToken` | Legacy single-worker CoreBuild settings. |
|
||||||
|
| `dcrouterGatewayUrl` / `dcrouterGatewayApiToken` | Optional external gateway integration for domain and route sync. |
|
||||||
|
|
||||||
|
## Starting Cloudly
|
||||||
|
|
||||||
|
Install and build with pnpm:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm install
|
||||||
|
pnpm build
|
||||||
|
pnpm start
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the TypeScript entry point during development:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm run startTs
|
||||||
|
```
|
||||||
|
|
||||||
|
Start from code when embedding the control plane in another Node.js process:
|
||||||
|
|
||||||
|
```ts
|
||||||
import { Cloudly } from '@serve.zone/cloudly';
|
import { Cloudly } from '@serve.zone/cloudly';
|
||||||
|
|
||||||
// Initialize Cloudly with your configuration
|
|
||||||
const cloudly = new Cloudly({
|
const cloudly = new Cloudly({
|
||||||
cfToken: process.env.CLOUDFLARE_TOKEN,
|
|
||||||
hetznerToken: process.env.HETZNER_TOKEN,
|
|
||||||
environment: 'production',
|
environment: 'production',
|
||||||
letsEncryptEmail: 'certs@example.com',
|
|
||||||
publicUrl: 'cloudly.example.com',
|
publicUrl: 'cloudly.example.com',
|
||||||
publicPort: 443,
|
publicPort: '443',
|
||||||
|
sslMode: 'external',
|
||||||
|
servezoneAdminaccount: 'admin:change-me',
|
||||||
mongoDescriptor: {
|
mongoDescriptor: {
|
||||||
mongoDbUrl: process.env.MONGODB_URL,
|
mongoDbUrl: process.env.MONGODB_URL,
|
||||||
mongoDbName: 'cloudly',
|
mongoDbName: 'cloudly',
|
||||||
mongoDbUser: process.env.MONGODB_USER,
|
mongoDbUser: process.env.MONGODB_USER,
|
||||||
mongoDbPass: process.env.MONGODB_PASS,
|
mongoDbPass: process.env.MONGODB_PASS,
|
||||||
}
|
},
|
||||||
|
s3Descriptor: {
|
||||||
|
endpoint: process.env.S3_ENDPOINT,
|
||||||
|
accessKey: process.env.S3_ACCESSKEY,
|
||||||
|
accessSecret: process.env.S3_SECRETKEY,
|
||||||
|
bucketName: process.env.S3_BUCKET,
|
||||||
|
port: process.env.S3_PORT,
|
||||||
|
useSsl: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start the platform
|
|
||||||
await cloudly.start();
|
await cloudly.start();
|
||||||
console.log('🎉 Cloudly is running!');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🏗️ Architecture
|
Set `SERVEZONE_INSTALL_DEMO_DATA=true` only when you intentionally want the demo data installer to run. The code labels that path destructive.
|
||||||
|
|
||||||
Cloudly follows a modular architecture with clear separation of concerns:
|
## API Model
|
||||||
|
|
||||||
```
|
Cloudly exposes a single composed TypedRouter. Managers add their own typed handlers to the main router, and `CloudlyServer` exposes that router through the HTTP/WebSocket server.
|
||||||
┌─────────────────────────────────────────────┐
|
|
||||||
│ Web Dashboard (UI) │
|
|
||||||
├─────────────────────────────────────────────┤
|
|
||||||
│ API Layer (TypedRouter) │
|
|
||||||
├─────────────────────────────────────────────┤
|
|
||||||
│ Core Managers │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
||||||
│ │ Cluster │ │ Image │ │ Secret │ ... │
|
|
||||||
│ └─────────┘ └─────────┘ └─────────┘ │
|
|
||||||
├─────────────────────────────────────────────┤
|
|
||||||
│ Cloud Connectors │
|
|
||||||
│ ┌──────────┐ ┌─────────┐ ┌──────────----┐ │
|
|
||||||
│ │Cloudflare│ │ Hetzner │ │ DigitalOcean │ │
|
|
||||||
│ └──────────┘ └─────────┘ └──────────----┘ │
|
|
||||||
└─────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## 💻 Core Components
|
Typical consumers use `@serve.zone/api`:
|
||||||
|
|
||||||
### 🔧 Managers
|
```ts
|
||||||
|
import { CloudlyApiClient } from '@serve.zone/api';
|
||||||
|
|
||||||
- **AuthManager** - Identity and access management
|
const client = new CloudlyApiClient({
|
||||||
- **ClusterManager** - Docker Swarm cluster orchestration
|
registerAs: 'admin-tool',
|
||||||
- **ImageManager** - Container image lifecycle management
|
cloudlyUrl: 'https://cloudly.example.com',
|
||||||
- **SecretManager** - Secure credential storage and distribution
|
|
||||||
- **ServerManager** - Cloud server provisioning and management
|
|
||||||
- **TaskManager** - Background job scheduling and execution
|
|
||||||
|
|
||||||
### 🔌 Connectors
|
|
||||||
|
|
||||||
- **CloudflareConnector** - DNS, CDN, and edge services
|
|
||||||
- **LetsencryptConnector** - Automatic SSL certificate provisioning
|
|
||||||
- **MongodbConnector** - Database persistence layer
|
|
||||||
- **HetznerConnector** - German cloud infrastructure
|
|
||||||
- **DigitalOceanConnector** - Developer-friendly cloud resources
|
|
||||||
|
|
||||||
## 📚 Usage Examples
|
|
||||||
|
|
||||||
### Managing Clusters
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Create a new cluster
|
|
||||||
const cluster = await cloudly.clusterManager.createCluster({
|
|
||||||
name: 'production-cluster',
|
|
||||||
region: 'eu-central',
|
|
||||||
nodeCount: 3
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Deploy a service
|
await client.start();
|
||||||
await cluster.deployService({
|
const identity = await client.loginWithUsernameAndPassword('admin', 'change-me');
|
||||||
name: 'api-service',
|
const clusters = await client.cluster.getClusters();
|
||||||
image: 'myapp:latest',
|
|
||||||
replicas: 3,
|
|
||||||
ports: [{ published: 80, target: 3000 }]
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Secret Management
|
Machine clients such as Coreflow authenticate with `getIdentityByToken`, request a stateful identity, and tag their WebSocket connection. That lets Cloudly push configuration to already-connected Coreflow instances instead of opening inbound connections to cluster nodes.
|
||||||
|
|
||||||
```typescript
|
## Cluster Flow
|
||||||
// Create a secret group
|
|
||||||
const secretGroup = await cloudly.secretManager.createSecretGroup({
|
|
||||||
name: 'api-credentials',
|
|
||||||
secrets: [
|
|
||||||
{ key: 'API_KEY', value: process.env.API_KEY },
|
|
||||||
{ key: 'DB_PASSWORD', value: process.env.DB_PASSWORD }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a bundle for deployment
|
The implemented cluster flow is intentionally simple:
|
||||||
const bundle = await cloudly.secretManager.createSecretBundle({
|
|
||||||
name: 'production-secrets',
|
1. An admin creates a Cloudly cluster record.
|
||||||
secretGroups: [secretGroup]
|
2. Cloudly creates a machine user with a long-lived cluster token.
|
||||||
});
|
3. Coreflow starts on a Docker Swarm manager node with `CLOUDLY_URL` and `JUMPCODE`.
|
||||||
|
4. Coreflow authenticates to Cloudly and requests the cluster configuration payload.
|
||||||
|
5. Cloudly returns cluster data, workload services, platform bindings, provider configs, and optional external gateway configuration.
|
||||||
|
6. Coreflow reconciles Docker networks, base services, workload services, secrets, volumes, platform bindings, backups, and routing.
|
||||||
|
|
||||||
|
When service, platform, or gateway settings change, Cloudly pushes updated config to connected Coreflow clients where supported.
|
||||||
|
|
||||||
|
## Registry and Deploy-On-Push
|
||||||
|
|
||||||
|
Cloudly serves an OCI registry under `/v2` through `CloudlyRegistryManager`. The registry uses configured S3 storage and issues OCI tokens from Cloudly authentication state.
|
||||||
|
|
||||||
|
For Cloudly-managed services, `getServiceRegistryTarget()` creates stable registry targets like:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<cloudly-host>/workloads/<service-name>-<service-id>:<tag>
|
||||||
```
|
```
|
||||||
|
|
||||||
### DNS Management
|
Registry push hooks record tag/digest metadata on the linked image and service. Unless `deployOnPush` is explicitly `false`, a successful push updates the service image version and asks connected Coreflow clients to reconcile.
|
||||||
|
|
||||||
```typescript
|
## BaseOS and CoreBuild
|
||||||
// Create DNS records via Cloudflare
|
|
||||||
const record = await cloudly.cloudflareConnector.createDNSRecord(
|
|
||||||
'example.com',
|
|
||||||
'api.example.com',
|
|
||||||
'A',
|
|
||||||
'192.168.1.1'
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Web Dashboard
|
Cloudly can manage BaseOS nodes and image builds:
|
||||||
|
|
||||||
```typescript
|
- BaseOS devices register through `POST /baseos/v1/nodes/register` and heartbeat through `POST /baseos/v1/nodes/heartbeat`.
|
||||||
import { html } from '@design.estate/dees-element';
|
- A configured `baseosJoinToken` accepts generic device enrollment.
|
||||||
|
- BaseOS image builds create one-time provisioning tokens that are embedded in generated images.
|
||||||
|
- Cloudly selects a CoreBuild worker based on `/corebuild/v1/capabilities` and sends the build to `/corebuild/v1/jobs/baseos-image`.
|
||||||
|
- Completed artifacts are stored in the configured S3 bucket and served through short-lived `/baseos/v1/images/:buildId/download` URLs.
|
||||||
|
|
||||||
// Create a custom dashboard view
|
CoreBuild worker configuration can use `corebuildWorkersJson` for multiple workers or the legacy `corebuildWorkerUrl` and `corebuildWorkerToken` settings for one worker.
|
||||||
const dashboard = html`
|
|
||||||
<cloudly-dashboard>
|
|
||||||
<cloudly-view-clusters></cloudly-view-clusters>
|
|
||||||
<cloudly-view-dns></cloudly-view-dns>
|
|
||||||
<cloudly-view-images></cloudly-view-images>
|
|
||||||
</cloudly-dashboard>
|
|
||||||
`;
|
|
||||||
|
|
||||||
document.body.appendChild(dashboard);
|
## Backups and Corestore
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ CLI Usage
|
Cloudly owns backup records and user-facing backup/restore requests. Coreflow executes the cluster-local work, and Corestore snapshots volumes, database resources, object storage resources, and archive objects.
|
||||||
|
|
||||||
The CLI provides quick access to all Cloudly features:
|
The backup path includes:
|
||||||
|
|
||||||
```bash
|
- `createServiceBackup` and `restoreServiceBackup` typed requests for admins.
|
||||||
# Login to your Cloudly instance
|
- `executeServiceBackup` and `executeServiceRestore` requests from Cloudly to Coreflow.
|
||||||
servezone login --url https://cloudly.example.com
|
- Corestore volume/resource snapshot and restore endpoints behind Coreflow.
|
||||||
|
- Optional archive replication through `prepareBackupReplication`, `uploadBackupArchiveObject`, `completeBackupReplication`, `getBackupArchiveManifest`, and `downloadBackupArchiveObject`.
|
||||||
|
- Optional scheduled `backup-all-services` task when `CLOUDLY_BACKUP_CRON` is set.
|
||||||
|
|
||||||
# List clusters
|
## External Gateway Integration
|
||||||
servezone clusters list
|
|
||||||
|
|
||||||
# Deploy a service
|
Cloudly can integrate with a dcrouter gateway when the gateway URL and API token are present in settings. The current integration syncs externally available domains into Cloudly and passes an external gateway route configuration to Coreflow. Coreflow can then ask dcrouter for certificates and synchronize public routes while still routing to cluster-local Coretraffic.
|
||||||
servezone deploy --cluster prod --image myapp:latest
|
|
||||||
|
|
||||||
# Manage secrets
|
## Development
|
||||||
servezone secrets create --name api-key --value "secret123"
|
|
||||||
|
|
||||||
# View logs
|
Common commands:
|
||||||
servezone logs --service api-service --follow
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📦 Package Exports
|
```sh
|
||||||
|
|
||||||
This monorepo publishes multiple packages:
|
|
||||||
|
|
||||||
- **@serve.zone/cloudly** - Main orchestration platform
|
|
||||||
- **@serve.zone/api** - TypeScript/JavaScript API client
|
|
||||||
- **@serve.zone/cli** - Command-line interface
|
|
||||||
- **@serve.zone/interfaces** - Shared TypeScript interfaces
|
|
||||||
|
|
||||||
## 🔒 Security Features
|
|
||||||
|
|
||||||
- **End-to-end encryption** for secrets
|
|
||||||
- **Role-based access control** (RBAC)
|
|
||||||
- **Automatic SSL/TLS** certificate management
|
|
||||||
- **Secure token-based authentication**
|
|
||||||
- **Audit logging** for compliance
|
|
||||||
|
|
||||||
## 🚢 Production Ready
|
|
||||||
|
|
||||||
Cloudly is battle-tested in production environments managing:
|
|
||||||
- High-traffic web applications
|
|
||||||
- Microservice architectures
|
|
||||||
- CI/CD pipelines
|
|
||||||
- Data processing workloads
|
|
||||||
- Real-time communication systems
|
|
||||||
|
|
||||||
## 🤝 Development
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clone the repository
|
|
||||||
git clone https://gitlab.com/servezone/private/cloudly.git
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
pnpm install
|
pnpm install
|
||||||
|
|
||||||
# Run tests
|
|
||||||
pnpm test
|
|
||||||
|
|
||||||
# Build the project
|
|
||||||
pnpm build
|
pnpm build
|
||||||
|
pnpm test
|
||||||
# Start development mode
|
pnpm run build:docker
|
||||||
pnpm watch
|
pnpm run release:docker
|
||||||
|
pnpm run docs
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📖 Documentation
|
Important paths:
|
||||||
|
|
||||||
For detailed documentation, API references, and guides, visit our [documentation site](https://cloudly.serve.zone).
|
| Path | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| `ts/index.ts` | CLI/runtime entry point exporting `runCli`, `Cloudly`, and `ICloudlyConfig`. |
|
||||||
|
| `ts/classes.cloudly.ts` | Main service coordinator and startup order. |
|
||||||
|
| `ts/classes.server.ts` | API/dashboard server, registry bridge, and BaseOS HTTP routes. |
|
||||||
|
| `ts/manager.*` | Domain managers for auth, clusters, services, images, registry, platform, backups, BaseOS, and more. |
|
||||||
|
| `ts/connector.*` | External system connectors for MongoDB, Cloudflare, and Let's Encrypt. |
|
||||||
|
| `ts_web/` | Browser dashboard web components. |
|
||||||
|
| `ts_cliclient/` | Published `@serve.zone/cli` submodule. |
|
||||||
|
|
||||||
|
## Accuracy Notes
|
||||||
|
|
||||||
|
The package metadata and settings schema include fields for several cloud providers. The code paths currently exercised in this repository are Cloudflare for ACME DNS-01, Hetzner for selected node/bare-metal provisioning paths, S3-compatible storage, MongoDB/SmartData, CoreBuild, Coreflow, Corestore, and optional dcrouter integration. Verify provider-specific behavior in the relevant manager before relying on it operationally.
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license) file.
|
||||||
|
|
||||||
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
### Trademarks
|
### Trademarks
|
||||||
|
|
||||||
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
|
||||||
|
|
||||||
|
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
|
||||||
|
|
||||||
### Company Information
|
### Company Information
|
||||||
|
|
||||||
Task Venture Capital GmbH
|
Task Venture Capital GmbH
|
||||||
Registered at District court Bremen HRB 35230 HB, Germany
|
Registered at District Court Bremen HRB 35230 HB, Germany
|
||||||
|
|
||||||
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
||||||
|
|
||||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||||
+64
-317
@@ -1,358 +1,105 @@
|
|||||||
# @serve.zone/cli 🚀
|
# @serve.zone/cli
|
||||||
|
|
||||||
**Command-line interface for Cloudly.** Manage your multi-cloud infrastructure from the terminal with powerful, intuitive commands.
|
`@serve.zone/cli` is the published Cloudly CLI submodule. It provides the `servezone` binary and currently acts as a thin environment-driven client for connecting to a Cloudly control plane and listing clusters through `@serve.zone/api`.
|
||||||
|
|
||||||
## 🎯 What is @serve.zone/cli?
|
## Issue Reporting and Security
|
||||||
|
|
||||||
The Cloudly CLI brings the full power of the Cloudly platform to your terminal. Whether you're automating deployments, managing secrets, or monitoring services, the CLI provides a streamlined interface for all your cloud operations.
|
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
||||||
|
|
||||||
## ✨ Features
|
## Current Scope
|
||||||
|
|
||||||
- **⚡ Fast & Efficient** - Optimized for speed and minimal resource usage
|
This submodule is intentionally small in the current codebase:
|
||||||
- **🔐 Secure Authentication** - Token-based authentication with secure storage
|
|
||||||
- **📝 Intuitive Commands** - Clear, consistent command structure
|
|
||||||
- **🎨 Formatted Output** - Beautiful, readable output with color coding
|
|
||||||
- **🔄 Scriptable** - Perfect for CI/CD pipelines and automation
|
|
||||||
- **📊 Comprehensive** - Access to all Cloudly features from the terminal
|
|
||||||
|
|
||||||
## 🚀 Installation
|
- Reads `CLOUDLY_URL` through `@push.rocks/qenv`.
|
||||||
|
- Authenticates with either `CLOUDLY_TOKEN` or `CLOUDLY_USERNAME` plus `CLOUDLY_PASSWORD`.
|
||||||
|
- Starts a `CloudlyApiClient` registered as `cli`.
|
||||||
|
- Creates a `CliClient` wrapper around the API client.
|
||||||
|
- Calls `CliClient.getClusters()` and prints the result.
|
||||||
|
|
||||||
### Global Installation (Recommended)
|
It is not currently a full command tree for services, secrets, deployments, logs, profiles, or shell completion. Those flows should be implemented against `@serve.zone/api` before documenting them as CLI commands.
|
||||||
|
|
||||||
```bash
|
## Installation
|
||||||
|
|
||||||
|
The package is published from `cloudly/ts_cliclient` via `tspublish.json` under the name `@serve.zone/cli` with the `servezone` binary.
|
||||||
|
|
||||||
|
```sh
|
||||||
pnpm add -g @serve.zone/cli
|
pnpm add -g @serve.zone/cli
|
||||||
```
|
```
|
||||||
|
|
||||||
### Local Installation
|
For local development inside the Cloudly repository, build the parent package:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
pnpm add @serve.zone/cli
|
pnpm install
|
||||||
|
pnpm build
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🎬 Quick Start
|
## Usage
|
||||||
|
|
||||||
```bash
|
Authenticate with a machine token:
|
||||||
# Configure your Cloudly instance
|
|
||||||
servezone config --url https://cloudly.example.com
|
|
||||||
|
|
||||||
# Login with your service token
|
```sh
|
||||||
servezone login --token your-service-token
|
CLOUDLY_URL=https://cloudly.example.com \
|
||||||
|
CLOUDLY_TOKEN=cluster-or-api-token \
|
||||||
# List your clusters
|
servezone
|
||||||
servezone clusters list
|
|
||||||
|
|
||||||
# Deploy a service
|
|
||||||
servezone deploy --cluster production --image myapp:latest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🔑 Authentication
|
Authenticate with username and password:
|
||||||
|
|
||||||
### Initial Setup
|
```sh
|
||||||
|
CLOUDLY_URL=https://cloudly.example.com \
|
||||||
```bash
|
CLOUDLY_USERNAME=admin \
|
||||||
# Set your Cloudly instance URL
|
CLOUDLY_PASSWORD=change-me \
|
||||||
servezone config --url https://cloudly.example.com
|
servezone
|
||||||
|
|
||||||
# Authenticate with a service token
|
|
||||||
servezone login --token YOUR_SERVICE_TOKEN
|
|
||||||
|
|
||||||
# Or use environment variables
|
|
||||||
export CLOUDLY_URL=https://cloudly.example.com
|
|
||||||
export CLOUDLY_TOKEN=YOUR_SERVICE_TOKEN
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Managing Profiles
|
When `CLOUDLY_TOKEN` is present, the CLI requests a stateful identity and asks Cloudly to tag the WebSocket connection. When username/password are present instead, it uses Cloudly's admin login flow. If no credentials are provided, the CLI prints a warning before attempting the default cluster-list operation.
|
||||||
|
|
||||||
```bash
|
## Programmatic Use
|
||||||
# Create a profile for different environments
|
|
||||||
servezone profile create production --url https://prod.cloudly.com
|
|
||||||
servezone profile create staging --url https://stage.cloudly.com
|
|
||||||
|
|
||||||
# Switch between profiles
|
The submodule exports the `runCli()` entry point and uses `CliClient` internally:
|
||||||
servezone profile use production
|
|
||||||
|
|
||||||
# List all profiles
|
```ts
|
||||||
servezone profile list
|
import { CloudlyApiClient } from '@serve.zone/api';
|
||||||
|
import { CliClient } from './classes.cliclient.js';
|
||||||
|
|
||||||
|
const apiClient = new CloudlyApiClient({
|
||||||
|
registerAs: 'cli',
|
||||||
|
cloudlyUrl: 'https://cloudly.example.com',
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiClient.start();
|
||||||
|
await apiClient.loginWithUsernameAndPassword('admin', 'change-me');
|
||||||
|
|
||||||
|
const cli = new CliClient(apiClient);
|
||||||
|
await cli.getClusters();
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📚 Core Commands
|
## Files
|
||||||
|
|
||||||
### 🌐 Cluster Management
|
| Path | Purpose |
|
||||||
|
| --- | --- |
|
||||||
```bash
|
| `index.ts` | Runtime entry point for the published CLI. |
|
||||||
# List all clusters
|
| `classes.cliclient.ts` | Minimal client wrapper; currently exposes `getClusters()`. |
|
||||||
servezone clusters list
|
| `plugins.ts` | Centralized imports for the submodule. |
|
||||||
|
| `tspublish.json` | Published package name, dependencies, registry targets, and `servezone` bin metadata. |
|
||||||
# Get cluster details
|
|
||||||
servezone clusters info production-cluster
|
|
||||||
|
|
||||||
# Create a new cluster
|
|
||||||
servezone clusters create \
|
|
||||||
--name production-cluster \
|
|
||||||
--region eu-central \
|
|
||||||
--nodes 3
|
|
||||||
|
|
||||||
# Scale a cluster
|
|
||||||
servezone clusters scale production-cluster --nodes 5
|
|
||||||
|
|
||||||
# Delete a cluster
|
|
||||||
servezone clusters delete staging-cluster
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🐳 Service Deployment
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Deploy a service
|
|
||||||
servezone deploy \
|
|
||||||
--cluster production \
|
|
||||||
--name api-service \
|
|
||||||
--image myapp:2.0.0 \
|
|
||||||
--replicas 3 \
|
|
||||||
--port 80:3000
|
|
||||||
|
|
||||||
# Update a service
|
|
||||||
servezone service update api-service \
|
|
||||||
--image myapp:2.1.0 \
|
|
||||||
--replicas 5
|
|
||||||
|
|
||||||
# Scale a service
|
|
||||||
servezone service scale api-service --replicas 10
|
|
||||||
|
|
||||||
# Remove a service
|
|
||||||
servezone service remove api-service
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔐 Secret Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create a secret
|
|
||||||
servezone secrets create \
|
|
||||||
--name database-url \
|
|
||||||
--value "postgres://user:pass@host/db"
|
|
||||||
|
|
||||||
# Create a secret group
|
|
||||||
servezone secrets create-group \
|
|
||||||
--name api-secrets \
|
|
||||||
--secret DATABASE_URL=postgres://... \
|
|
||||||
--secret REDIS_URL=redis://...
|
|
||||||
|
|
||||||
# List secrets
|
|
||||||
servezone secrets list
|
|
||||||
|
|
||||||
# Get secret value
|
|
||||||
servezone secrets get database-url
|
|
||||||
|
|
||||||
# Delete a secret
|
|
||||||
servezone secrets delete old-secret
|
|
||||||
```
|
|
||||||
|
|
||||||
### 📦 Image Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List images
|
|
||||||
servezone images list
|
|
||||||
|
|
||||||
# Push a new image
|
|
||||||
servezone images push \
|
|
||||||
--name myapp \
|
|
||||||
--version 2.0.0 \
|
|
||||||
--file ./myapp.tar
|
|
||||||
|
|
||||||
# Tag an image
|
|
||||||
servezone images tag myapp:2.0.0 myapp:latest
|
|
||||||
|
|
||||||
# Delete an image
|
|
||||||
servezone images delete myapp:1.0.0
|
|
||||||
```
|
|
||||||
|
|
||||||
### 📊 Monitoring & Logs
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# View service logs
|
|
||||||
servezone logs api-service
|
|
||||||
|
|
||||||
# Follow logs in real-time
|
|
||||||
servezone logs api-service --follow
|
|
||||||
|
|
||||||
# Filter logs
|
|
||||||
servezone logs api-service --since 1h --grep ERROR
|
|
||||||
|
|
||||||
# Get service status
|
|
||||||
servezone service status api-service
|
|
||||||
|
|
||||||
# Monitor cluster health
|
|
||||||
servezone clusters health production-cluster
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔧 DNS Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List DNS records
|
|
||||||
servezone dns list --domain example.com
|
|
||||||
|
|
||||||
# Create a DNS record
|
|
||||||
servezone dns create \
|
|
||||||
--domain example.com \
|
|
||||||
--name api \
|
|
||||||
--type A \
|
|
||||||
--value 192.168.1.1
|
|
||||||
|
|
||||||
# Update a DNS record
|
|
||||||
servezone dns update api.example.com --value 192.168.1.2
|
|
||||||
|
|
||||||
# Delete a DNS record
|
|
||||||
servezone dns delete old.example.com
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 Advanced Usage
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Set environment variables for a service
|
|
||||||
servezone deploy \
|
|
||||||
--name api-service \
|
|
||||||
--env NODE_ENV=production \
|
|
||||||
--env PORT=3000 \
|
|
||||||
--env DATABASE_URL=@secret:database-url
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuration Files
|
|
||||||
|
|
||||||
Create a `cloudly.yaml` file:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
cluster: production
|
|
||||||
service:
|
|
||||||
name: api-service
|
|
||||||
image: myapp:latest
|
|
||||||
replicas: 3
|
|
||||||
ports:
|
|
||||||
- 80:3000
|
|
||||||
environment:
|
|
||||||
NODE_ENV: production
|
|
||||||
DATABASE_URL: "@secret:database-url"
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy using the config file:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
servezone deploy --config cloudly.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
### Batch Operations
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Deploy multiple services
|
|
||||||
servezone deploy --config services/*.yaml
|
|
||||||
|
|
||||||
# Update all services in a namespace
|
|
||||||
servezone service update --namespace api --image-tag v2.0.0
|
|
||||||
|
|
||||||
# Delete all staging resources
|
|
||||||
servezone cleanup --environment staging
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔄 CI/CD Integration
|
|
||||||
|
|
||||||
### GitHub Actions
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Deploy to Cloudly
|
|
||||||
run: |
|
|
||||||
servezone config --url ${{ secrets.CLOUDLY_URL }}
|
|
||||||
servezone login --token ${{ secrets.CLOUDLY_TOKEN }}
|
|
||||||
servezone deploy \
|
|
||||||
--cluster production \
|
|
||||||
--name api-service \
|
|
||||||
--image myapp:${{ github.sha }}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GitLab CI
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
deploy:
|
|
||||||
script:
|
|
||||||
- servezone config --url $CLOUDLY_URL
|
|
||||||
- servezone login --token $CLOUDLY_TOKEN
|
|
||||||
- servezone deploy --config cloudly.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎨 Output Formats
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# JSON output for scripting
|
|
||||||
servezone clusters list --output json
|
|
||||||
|
|
||||||
# YAML output
|
|
||||||
servezone service info api-service --output yaml
|
|
||||||
|
|
||||||
# Table output (default)
|
|
||||||
servezone images list --output table
|
|
||||||
|
|
||||||
# Quiet mode (IDs only)
|
|
||||||
servezone clusters list --quiet
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ Troubleshooting
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Enable debug output
|
|
||||||
servezone --debug clusters list
|
|
||||||
|
|
||||||
# Check CLI version
|
|
||||||
servezone version
|
|
||||||
|
|
||||||
# Test connection
|
|
||||||
servezone ping
|
|
||||||
|
|
||||||
# View configuration
|
|
||||||
servezone config show
|
|
||||||
|
|
||||||
# Clear cache and credentials
|
|
||||||
servezone logout --clear-cache
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📝 Command Reference
|
|
||||||
|
|
||||||
```bash
|
|
||||||
servezone --help # Show all commands
|
|
||||||
servezone <command> --help # Show command-specific help
|
|
||||||
servezone clusters --help # Show cluster commands
|
|
||||||
servezone service --help # Show service commands
|
|
||||||
servezone secrets --help # Show secret commands
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔌 Shell Completion
|
|
||||||
|
|
||||||
Enable tab completion for your shell:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Bash
|
|
||||||
servezone completion bash > /etc/bash_completion.d/servezone
|
|
||||||
|
|
||||||
# Zsh
|
|
||||||
servezone completion zsh > ~/.zsh/completions/_servezone
|
|
||||||
|
|
||||||
# Fish
|
|
||||||
servezone completion fish > ~/.config/fish/completions/servezone.fish
|
|
||||||
```
|
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](../license) file.
|
||||||
|
|
||||||
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
### Trademarks
|
### Trademarks
|
||||||
|
|
||||||
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
|
||||||
|
|
||||||
|
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
|
||||||
|
|
||||||
### Company Information
|
### Company Information
|
||||||
|
|
||||||
Task Venture Capital GmbH
|
Task Venture Capital GmbH
|
||||||
Registered at District court Bremen HRB 35230 HB, Germany
|
Registered at District Court Bremen HRB 35230 HB, Germany
|
||||||
|
|
||||||
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
||||||
|
|
||||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||||
Reference in New Issue
Block a user