mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-05-18 14:53:05 +08:00
feat(skills): add uncloud skill
This commit is contained in:
committed by
Affaan Mustafa
parent
9b1d891870
commit
8b6aed0b80
317
skills/uncloud/SKILL.md
Normal file
317
skills/uncloud/SKILL.md
Normal file
@@ -0,0 +1,317 @@
|
||||
---
|
||||
name: uncloud
|
||||
description: Use when managing an Uncloud cluster — deploying services, configuring Caddy ingress, adding static proxy routes for non-cluster devices, publishing ports, scaling, inspecting logs, or managing machines and volumes with the `uc` CLI.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Uncloud Cluster Management
|
||||
|
||||
Reference for the `uc` CLI — a decentralised self-hosting platform using Docker containers, WireGuard mesh networking, and Caddy reverse proxy.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
- **No central control plane** — all machines are equal peers connected by WireGuard
|
||||
- **Caddy** runs as a global service on every machine; auto-obtains TLS from Let's Encrypt
|
||||
- **Overlay network** — services communicate via `10.210.0.0/16` by default; DNS provided inside the mesh
|
||||
- **Caddyfile is autogenerated** — never edit it directly; use `x-caddy` / `--caddyfile` instead
|
||||
|
||||
---
|
||||
|
||||
## CLI Quick Reference
|
||||
|
||||
### Machines
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `uc machine init user@host` | Bootstrap first machine / new cluster |
|
||||
| `uc machine add user@host` | Join machine to existing cluster |
|
||||
| `uc machine ls` | List machines |
|
||||
| `uc machine update NAME --public-ip IP` | Update public IP for ingress |
|
||||
| `uc machine rm NAME` | Remove machine |
|
||||
|
||||
Key `init` flags: `--name`, `--network 10.210.0.0/16`, `--no-caddy`, `--no-dns`, `--public-ip auto\|IP\|none`
|
||||
|
||||
### Services
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `uc service ls` / `uc ls` | List services |
|
||||
| `uc service run IMAGE` | Run a single container service |
|
||||
| `uc deploy` | Deploy from `compose.yaml` |
|
||||
| `uc scale SERVICE N` | Set replica count |
|
||||
| `uc service logs SERVICE` | View logs |
|
||||
| `uc service exec SERVICE` | Shell into container |
|
||||
| `uc service inspect SERVICE` | Detailed info |
|
||||
| `uc service rm SERVICE` | Remove service (keeps named volumes) |
|
||||
| `uc ps` | All containers across cluster |
|
||||
|
||||
### Images
|
||||
|
||||
```bash
|
||||
uc image push myapp:latest # Push local image to all machines
|
||||
uc image push myapp:latest -m machine1,machine2 # Push to specific machines
|
||||
uc images # List images in cluster
|
||||
```
|
||||
|
||||
### Volumes
|
||||
|
||||
```bash
|
||||
uc volume ls # All volumes
|
||||
uc volume ls -m machine1 # On specific machine
|
||||
uc volume create NAME -m MACHINE
|
||||
uc volume rm NAME
|
||||
```
|
||||
|
||||
### Caddy
|
||||
|
||||
```bash
|
||||
uc caddy config # Show current generated Caddyfile (read-only)
|
||||
uc caddy deploy # Deploy/upgrade Caddy across cluster
|
||||
```
|
||||
|
||||
### DNS & Context
|
||||
|
||||
```bash
|
||||
uc dns show # Show reserved *.uncld.dev domain
|
||||
uc dns reserve # Reserve a new domain
|
||||
uc ctx ls # List cluster contexts
|
||||
uc ctx use prod # Switch context
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Port Publishing
|
||||
|
||||
### HTTP/HTTPS (via Caddy reverse proxy)
|
||||
|
||||
```
|
||||
-p [hostname:]container_port[/protocol]
|
||||
```
|
||||
|
||||
| Example | Meaning |
|
||||
|---------|---------|
|
||||
| `-p 8080/https` | HTTPS with auto `service-name.cluster-domain` hostname |
|
||||
| `-p app.example.com:8080/https` | HTTPS with custom hostname |
|
||||
| `-p 8080/http` | HTTP only, no TLS |
|
||||
|
||||
### TCP/UDP (host-bound, bypasses Caddy)
|
||||
|
||||
```
|
||||
-p [host_ip:]host_port:container_port[/protocol]@host
|
||||
```
|
||||
|
||||
| Example | Meaning |
|
||||
|---------|---------|
|
||||
| `-p 5432:5432@host` | TCP 5432 on all interfaces |
|
||||
| `-p 127.0.0.1:5432:5432@host` | TCP 5432 loopback only |
|
||||
| `-p 53:5353/udp@host` | UDP |
|
||||
|
||||
---
|
||||
|
||||
## Compose File Extensions
|
||||
|
||||
Uncloud adds these extensions on top of Docker Compose:
|
||||
|
||||
### `x-ports` — publish ports with domains
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
image: app:latest
|
||||
x-ports:
|
||||
- example.com:8000/https
|
||||
- www.example.com:8000/https
|
||||
- api.example.com:9000/https
|
||||
```
|
||||
|
||||
### `x-caddy` — custom Caddy config for service
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
image: app:latest
|
||||
x-caddy: |
|
||||
example.com {
|
||||
redir https://www.example.com{uri} permanent
|
||||
}
|
||||
www.example.com {
|
||||
reverse_proxy {{upstreams 8000}} {
|
||||
import common_proxy
|
||||
}
|
||||
basic_auth /admin/* {
|
||||
admin $2a$14$...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Template functions available inside `x-caddy`:
|
||||
- `{{upstreams [service] [port]}}` — healthy container IPs
|
||||
- `{{.Name}}` — service name
|
||||
- `{{.Upstreams}}` — map of all services → IPs
|
||||
|
||||
### `x-machines` — placement constraints
|
||||
|
||||
```yaml
|
||||
services:
|
||||
db:
|
||||
image: postgres:18
|
||||
x-machines: db-machine # Single machine name
|
||||
app:
|
||||
image: app:latest
|
||||
x-machines:
|
||||
- machine-1
|
||||
- machine-2
|
||||
```
|
||||
|
||||
### Full multi-service example
|
||||
|
||||
```yaml
|
||||
services:
|
||||
api:
|
||||
build: ./api
|
||||
x-ports:
|
||||
- api.example.com:3000/https
|
||||
environment:
|
||||
DATABASE_URL: postgres://db:5432/mydb
|
||||
|
||||
web:
|
||||
build: ./web
|
||||
x-ports:
|
||||
- example.com:8000/https
|
||||
- www.example.com:8000/https
|
||||
environment:
|
||||
API_URL: http://api:3000
|
||||
|
||||
db:
|
||||
image: postgres:18
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
x-machines: db-machine
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Routing to External (Non-Cluster) Devices
|
||||
|
||||
To expose an external device (e.g. BMC, NAS, router UI) via Caddy without running a real container:
|
||||
|
||||
**1. Create a Caddyfile snippet** (e.g. `~/device.caddyfile`):
|
||||
|
||||
```caddyfile
|
||||
https://device.example.com {
|
||||
reverse_proxy https://192.168.1.x {
|
||||
transport http {
|
||||
tls_insecure_skip_verify # needed for self-signed BMC certs
|
||||
}
|
||||
}
|
||||
log
|
||||
}
|
||||
```
|
||||
|
||||
For plaintext upstream: `reverse_proxy http://192.168.1.x:port`
|
||||
|
||||
**2. Register as a named service with no-op container:**
|
||||
|
||||
```bash
|
||||
uc service run \
|
||||
--name device-bmc \
|
||||
--caddyfile ~/device.caddyfile \
|
||||
registry.k8s.io/pause:3.9
|
||||
```
|
||||
|
||||
`pause` is a minimal no-op container — it does nothing, but gives Uncloud a service entry to attach the Caddyfile to.
|
||||
|
||||
**3. Verify:**
|
||||
|
||||
```bash
|
||||
uc caddy config # device.example.com block should appear
|
||||
```
|
||||
|
||||
> `--caddyfile` cannot be combined with non-`@host` published ports.
|
||||
|
||||
---
|
||||
|
||||
## Service DNS (Internal)
|
||||
|
||||
Services inside the cluster resolve each other by name:
|
||||
|
||||
| DNS name | Resolves to |
|
||||
|----------|------------|
|
||||
| `service-name` | Any healthy container |
|
||||
| `service-name.internal` | Same |
|
||||
| `rr.service-name.internal` | Round-robin |
|
||||
| `nearest.service-name.internal` | Machine-local first |
|
||||
|
||||
---
|
||||
|
||||
## Scaling & Global Services
|
||||
|
||||
```bash
|
||||
uc scale web 5 # 5 replicas (spread across machines)
|
||||
uc scale web 1 # Scale down
|
||||
```
|
||||
|
||||
```yaml
|
||||
services:
|
||||
caddy:
|
||||
deploy:
|
||||
mode: global # One container on every machine
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Image Tag Templates (in compose.yaml)
|
||||
|
||||
```yaml
|
||||
image: myapp:{{gitdate "20060102"}}.{{gitsha 7}}
|
||||
image: myapp:{{gitsha 7}}.${GITHUB_RUN_ID:-local}
|
||||
```
|
||||
|
||||
| Function | Output |
|
||||
|----------|--------|
|
||||
| `{{gitsha N}}` | First N chars of commit SHA |
|
||||
| `{{gitdate "format"}}` | Git commit date in Go format |
|
||||
| `{{date "format"}}` | Current date |
|
||||
|
||||
---
|
||||
|
||||
## Common Workflows
|
||||
|
||||
**Deploy from source:**
|
||||
```bash
|
||||
uc deploy # Build + push + deploy
|
||||
uc build --push && uc deploy --no-build # Separate steps
|
||||
```
|
||||
|
||||
**Inspect a service:**
|
||||
```bash
|
||||
uc inspect web
|
||||
uc logs -f web
|
||||
uc logs --since 1h web
|
||||
uc exec web # Opens shell
|
||||
uc exec web /bin/sh -c "env" # Run specific command
|
||||
```
|
||||
|
||||
**Zero-downtime deploys** happen automatically; Uncloud waits for health checks before terminating old containers.
|
||||
|
||||
**Force recreate:**
|
||||
```bash
|
||||
uc deploy --recreate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
| Mistake | Fix |
|
||||
|---------|-----|
|
||||
| Editing the Caddyfile directly | Use `x-caddy` in compose or `--caddyfile` on `uc service run` |
|
||||
| Proxying an HTTPS upstream with self-signed cert | Add `transport http { tls_insecure_skip_verify }` |
|
||||
| `uc caddy config` shows no user-defined blocks | Caddy admin socket unreachable — check `uc inspect caddy` and `uc logs caddy` |
|
||||
| Service can't reach external LAN IP from container | Verify Caddy container's host can route to target network |
|
||||
| Volumes lost after `uc service rm` | Named volumes persist; only anonymous volumes are auto-removed |
|
||||
Reference in New Issue
Block a user