uncloud
affaan-m/ECC
Gestiona un clúster de Uncloud: implementa servicios, configura Caddy Ingress, añade rutas de proxy estáticas para dispositivos que no forman parte del clúster, publica puertos, escala, revisa los registros y gestiona máquinas y volúmenes con la CLI `uc`.
...Expandir todoUncloud Gestión de clústeres
Referencia para la uc CLI: una plataforma descentralizada de autoalojamiento que utiliza contenedores Docker, redes en malla WireGuard y el proxy inverso Caddy.
Cuándo activarla
Utiliza esta habilidad cuando trabajes con clústeres de Uncloud, especialmente cuando:
- Inicializar o incorporar máquinas mediante
uc machine - Implementar servicios desde archivos Compose con
uc deploy - Publicar puertos HTTP, HTTPS, TCP o UDP a través de Uncloud
- Configurar Caddy Ingress con
x-caddy,x-ports, o--caddyfile - Enrutar dispositivos LAN externos a través del proxy del clúster
- Revisión de registros, estado de los servicios, volúmenes, DNS o ubicación de los servidores
Cómo funciona
Uncloud ejecuta servicios de Docker en máquinas homólogas conectadas mediante una malla WireGuard. Cada máquina es un miembro del clúster con los mismos derechos; los servicios se comunican en la red superpuesta y Caddy se ejecuta a nivel global para gestionar el tráfico público HTTP/HTTPS. Los archivos Compose pueden utilizar extensiones de Uncloud para el Ingress, la ubicación y la configuración generada de Caddy, mientras que la uc CLI se encarga de la distribución de imágenes, la programación, el escalado, los registros y el estado del clúster.
Ejemplos
uc machine init user@host --name machine-1
uc service run --name web -p app.example.com:8080/https nginx:latest
uc deploy
Conceptos básicos
- Sin plano de control central: todas las máquinas son pares en pie de igualdad conectadas mediante WireGuard
- Caddy se ejecuta como un servicio global en cada máquina; obtiene automáticamente el certificado TLS de Let's Encrypt
- Red superpuesta: los servicios se comunican a través de
10.210.0.0/16por defecto; el DNS se proporciona dentro de la malla - El archivo Caddyfile se genera automáticamente; nunca lo edites directamente; utiliza
x-caddy/--caddyfileen su lugar
Referencia rápida de la CLI
Máquinas
| Comando | Finalidad |
|---|---|
uc machine init user@host |
Inicializar la primera máquina / nuevo clúster |
uc machine add user@host |
Incorporar una máquina a un clúster existente |
uc machine ls |
Listar máquinas |
uc machine update NAME --public-ip IP |
Actualizar la IP pública de entrada |
uc machine rm NAME |
Eliminar máquina |
Clave init indicadores: --name, --network 10.210.0.0/16, --no-caddy, --no-dns, --public-ip auto\|IP\|none
Servicios
| Comando | Finalidad |
|---|---|
uc service ls / uc ls |
Mostrar una lista de servicios |
uc service run IMAGE |
Ejecutar un único servicio de contenedor |
uc deploy |
Implementar desde compose.yaml |
uc deploy --no-build |
Implementar imágenes ya enviadas sin necesidad de recompilarlas |
uc deploy --recreate |
Forzar la recreación del servicio |
uc scale SERVICE N |
Establecer el número de réplicas |
uc service logs SERVICE |
Ver registros |
uc service exec SERVICE |
Acceder al contenedor mediante el shell |
uc service inspect SERVICE |
Información detallada |
uc service rm SERVICE |
Eliminar servicio (conserva los volúmenes con nombre) |
uc ps |
Todos los contenedores del clúster |
Imágenes
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
Volúmenes
uc volume ls # All volumes
uc volume ls -m machine1 # On specific machine
uc volume create NAME -m MACHINE
uc volume rm NAME
Caddy
uc caddy config # Show current generated Caddyfile (read-only)
uc caddy deploy # Deploy/upgrade Caddy across cluster
DNS y contexto
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
Publicación de puertos
HTTP/HTTPS (a través del proxy inverso de Caddy)
-p [hostname:]container_port[/protocol]
| Ejemplo | Significado |
|---|---|
-p 8080/https |
HTTPS con service-name.cluster-domain nombre de host |
-p app.example.com:8080/https |
HTTPS con nombre de host personalizado |
-p 8080/http |
Solo HTTP, sin TLS |
TCP/UDP (vinculado al host, sin pasar por Caddy)
-p [host_ip:]host_port:container_port[/protocol]@host
| Ejemplo | Significado |
|---|---|
-p 5432:5432@host |
TCP 5432 en todas las interfaces |
-p 127.0.0.1:5432:5432@host |
TCP 5432 solo en bucle cerrado |
-p 53:5353/udp@host |
UDP |
Extensiones de archivos de Docker Compose
Uncloud añade estas extensiones además de las de Docker Compose:
x-ports — puertos de publicación con dominios
services:
app:
image: app:latest
x-ports:
- example.com:8000/https
- www.example.com:8000/https
- api.example.com:9000/https
x-caddy — configuración personalizada de Caddy para el servicio
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$...
}
}
Funciones de plantilla disponibles en x-caddy:
{{upstreams [service] [port]}}— direcciones IP de contenedores en buen estado{{.Name}}— nombre del servicio{{.Upstreams}}— mapa de todos los servicios → direcciones IP
x-machines — restricciones de ubicación
services:
db:
image: postgres:18
x-machines: db-machine # Single machine name
app:
image: app:latest
x-machines:
- machine-1
- machine-2
Ejemplo completo multiservicio
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:
Enrutamiento a dispositivos externos (ajenos al clúster)
Para exponer un dispositivo externo (por ejemplo, BMC, NAS, interfaz de usuario de un router) a través de Caddy sin ejecutar un contenedor real:
1. Crea un fragmento de Caddyfile (p. ej., ~/device.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
}
Para un servidor upstream de texto sin formato: reverse_proxy http://192.168.1.x:port
2. Regístralo como un servicio con nombre y un contenedor «no-op»:
uc service run \
--name device-bmc \
--caddyfile ~/device.caddyfile \
registry.k8s.io/pause:3.9
pause es un contenedor «no-op» mínimo: no hace nada, pero proporciona a Uncloud una entrada de servicio a la que adjuntar el Caddyfile.
3. Verifica:
uc caddy config # device.example.com block should appear
--caddyfileno se puede combinar con puertos no@hostpuerto no publicado.
Consejo sobre el DNS: un registro comodín (*.yourdomain.com → cluster-public-ip) implica que cualquier nuevo subdominio funciona de inmediato, sin necesidad de realizar cambios en el DNS por cada servicio.
DNS del servicio (interno)
Los servicios del clúster se identifican entre sí por su nombre:
| Nombre DNS | Se resuelve como |
|---|---|
service-name |
Cualquier contenedor operativo |
service-name.internal |
El mismo |
rr.service-name.internal |
Rotación |
nearest.service-name.internal |
Primero el local de la máquina |
Escalabilidad y servicios globales
uc scale web 5 # 5 replicas (spread across machines)
uc scale web 1 # Scale down
services:
caddy:
deploy:
mode: global # One container on every machine
Plantillas de etiquetas de imagen (en compose.yaml)
image: myapp:{{gitdate "20060102"}}.{{gitsha 7}}
image: myapp:{{gitsha 7}}.${GITHUB_RUN_ID:-local}
| Función | Salida |
|---|---|
{{gitsha N}} |
Primeros N caracteres del SHA de la confirmación |
{{gitdate "format"}} |
Fecha del commit de Git en formato Go |
{{date "format"}} |
Fecha actual |
Flujos de trabajo habituales
Implementación desde el código fuente:
uc deploy # Build + push + deploy
uc build --push && uc deploy --no-build # Separate steps
Inspeccionar un servicio:
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
Las implementaciones sin tiempo de inactividad se realizan automáticamente; Uncloud espera a que se completen las comprobaciones de estado antes de cerrar los contenedores antiguos.
Forzar la recreación:
uc deploy --recreate
Errores comunes
| Error | Solución |
|---|---|
| Editar el archivo Caddyfile directamente | Utiliza x-caddy en «Compose» o --caddyfile en uc service run |
| Proxy de un servidor HTTPS con certificado autofirmado | Añadir transport http { tls_insecure_skip_verify } |
uc caddy config no muestra ningún bloque definido por el usuario |
No se puede acceder al socket de administración de Caddy: comprueba uc inspect caddy y uc logs caddy |
| El servicio no puede acceder a la IP de la LAN externa desde el contenedor | Comprueba que el host del contenedor de Caddy pueda enrutar hacia la red de destino |
Se han perdido volúmenes tras uc service rm |
Los volúmenes con nombre persisten; solo los volúmenes anónimos se eliminan automáticamente |
---
name: uncloud
description: Manage an Uncloud cluster — deploy services, configure Caddy ingress, add static proxy routes for non-cluster devices, publish ports, scale, inspect logs, and manage machines and volumes with the `uc` CLI.
---
# Uncloud Cluster Management
Reference for the `uc` CLI — a decentralised self-hosting platform using Docker containers, WireGuard mesh networking, and Caddy reverse proxy.
## When to Activate
Use this skill when working with Uncloud clusters, especially when:
- Bootstrapping or joining machines with `uc machine`
- Deploying services from Compose files with `uc deploy`
- Publishing HTTP, HTTPS, TCP, or UDP ports through Uncloud
- Configuring Caddy ingress with `x-caddy`, `x-ports`, or `--caddyfile`
- Routing external LAN devices through the cluster proxy
- Inspecting logs, service state, volumes, DNS, or machine placement
## How It Works
Uncloud runs Docker services across peer machines connected by a WireGuard mesh. Each machine is an equal cluster member; services communicate on the overlay network and Caddy runs globally to terminate public HTTP/HTTPS traffic. Compose files can use Uncloud extensions for ingress, placement, and generated Caddy configuration, while the `uc` CLI handles image distribution, scheduling, scaling, logs, and cluster state.
## Examples
```bash
uc machine init user@host --name machine-1
uc service run --name web -p app.example.com:8080/https nginx:latest
uc deploy
```
## 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 deploy --no-build` | Deploy already-pushed images without rebuilding |
| `uc deploy --recreate` | Force service recreation |
| `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.
**DNS tip:** A wildcard record (`*.yourdomain.com → cluster-public-ip`) means any new subdomain works immediately — no DNS change needed per service.
---
## 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 |
Todos los archivos
1 archivosInstalar uncloud
Descarga y descomprime los archivos de habilidades en tu directorio .claude/skills/.
Descargar ZIPClona el repositorio y copia los archivos de la habilidad a tu proyecto.
git clone https://github.com/affaan-m/ECC/tree/main/skills/uncloud # Copy SKILL.md to your .claude/skills/ directory
Copiar





Hogar
