uncloud
affaan-m/ECC
Gérer un cluster Uncloud : déployer des services, configurer l'Ingress de Caddy, ajouter des routes de proxy statiques pour les appareils ne faisant pas partie du cluster, publier des ports, faire évoluer la capacité, analyser les journaux et gérer les machines et les volumes à l'aide de l'interface de ligne de commande `uc`.
...Développer toutUncloud Gestion des clusters
Guide de référence pour l' uc CLI — une plateforme décentralisée en auto-hébergement utilisant des conteneurs Docker, le maillage réseau WireGuard et le proxy inverse Caddy.
Quand l'activer
Utilisez cette compétence lorsque vous travaillez avec des clusters «Uncloud», en particulier dans les cas suivants :
- l’initialisation ou l’intégration de machines à l’aide de
uc machine - le déploiement de services à partir de fichiers Compose avec
uc deploy - la publication de ports HTTP, HTTPS, TCP ou UDP via l’Uncloud
- la configuration d’Ingress Caddy avec
x-caddy,x-ports, ou--caddyfile - Routage des périphériques LAN externes via le proxy du cluster
- Inspection des journaux, de l’état des services, des volumes, du DNS ou de l’emplacement des machines
Fonctionnement
Uncloud exécute des services Docker sur des machines homologues reliées par un maillage WireGuard. Chaque machine est un membre à part entière du cluster ; les services communiquent sur le réseau superposé et Caddy s'exécute globalement pour traiter le trafic HTTP/HTTPS public. Les fichiers Compose peuvent utiliser des extensions Uncloud pour l'Ingress, le placement et la configuration générée de Caddy, tandis que la uc CLI gère la distribution des images, la planification, la mise à l'échelle, les journaux et l'état du cluster.
Exemples
uc machine init user@host --name machine-1
uc service run --name web -p app.example.com:8080/https nginx:latest
uc deploy
Concepts fondamentaux
- Pas de plan de contrôle central — toutes les machines sont des pairs égaux reliés par WireGuard
- Caddy s’exécute en tant que service global sur chaque machine ; il obtient automatiquement un certificat TLS auprès de Let’s Encrypt
- Réseau overlay — les services communiquent via
10.210.0.0/16par défaut ; le DNS est fourni au sein du maillage - Le fichier Caddyfile est généré automatiquement — ne le modifiez jamais directement ; utilisez
x-caddy/--caddyfileà la place
Guide de référence rapide de l’interface en ligne de commande
Machines
| Commande | Objectif |
|---|---|
uc machine init user@host |
Initialisation de la première machine / d'un nouveau cluster |
uc machine add user@host |
Ajouter une machine à un cluster existant |
uc machine ls |
Lister les machines |
uc machine update NAME --public-ip IP |
Mettre à jour l'adresse IP publique pour le trafic entrant |
uc machine rm NAME |
Supprimer une machine |
Clé init indicateurs : --name, --network 10.210.0.0/16, --no-caddy, --no-dns, --public-ip auto\|IP\|none
Services
| Commande | Objectif |
|---|---|
uc service ls / uc ls |
Lister les services |
uc service run IMAGE |
Exécuter un seul service de conteneur |
uc deploy |
Déployer à partir de compose.yaml |
uc deploy --no-build |
Déployer des images déjà poussées sans les reconstruire |
uc deploy --recreate |
Forcer la recréation du service |
uc scale SERVICE N |
Définir le nombre de répliques |
uc service logs SERVICE |
Afficher les journaux |
uc service exec SERVICE |
Accéder au shell du conteneur |
uc service inspect SERVICE |
Informations détaillées |
uc service rm SERVICE |
Supprimer le service (conserve les volumes nommés) |
uc ps |
Tous les conteneurs du cluster |
Images
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
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 et contexte
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
Publication de ports
HTTP/HTTPS (via le proxy inverse Caddy)
-p [hostname:]container_port[/protocol]
| Exemple | Signification |
|---|---|
-p 8080/https |
HTTPS avec service-name.cluster-domain nom d’hôte |
-p app.example.com:8080/https |
HTTPS avec nom d’hôte personnalisé |
-p 8080/http |
HTTP uniquement, sans TLS |
TCP/UDP (lié à l'hôte, contourne Caddy)
-p [host_ip:]host_port:container_port[/protocol]@host
| Exemple | Signification |
|---|---|
-p 5432:5432@host |
TCP 5432 sur toutes les interfaces |
-p 127.0.0.1:5432:5432@host |
TCP 5432 en boucle locale uniquement |
-p 53:5353/udp@host |
UDP |
Extensions de fichiers Compose
Uncloud ajoute ces extensions en plus de Docker Compose :
x-ports — publication des ports avec des domaines
services:
app:
image: app:latest
x-ports:
- example.com:8000/https
- www.example.com:8000/https
- api.example.com:9000/https
x-caddy — configuration Caddy personnalisée pour le service
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$...
}
}
Fonctions de modèle disponibles à l'intérieur x-caddy:
{{upstreams [service] [port]}}— adresses IP des conteneurs opérationnels{{.Name}}— nom du service{{.Upstreams}}— carte de tous les services → adresses IP
x-machines — contraintes de placement
services:
db:
image: postgres:18
x-machines: db-machine # Single machine name
app:
image: app:latest
x-machines:
- machine-1
- machine-2
Exemple complet multiservice
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:
Routage vers des périphériques externes (hors cluster)
Pour exposer un périphérique externe (par exemple, BMC, NAS, interface utilisateur d’un routeur) via Caddy sans exécuter de véritable conteneur :
1. Créez un extrait de fichier Caddyfile (par exemple : ~/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
}
Pour un en amont en texte clair : reverse_proxy http://192.168.1.x:port
2. Enregistrez-le en tant que service nommé avec un conteneur « no-op » :
uc service run \
--name device-bmc \
--caddyfile ~/device.caddyfile \
registry.k8s.io/pause:3.9
pause est un conteneur minimal sans opération — il ne fait rien, mais fournit à Uncloud une entrée de service à laquelle associer le Caddyfile.
3. Vérifiez :
uc caddy config # device.example.com block should appear
--caddyfilene peut pas être combiné avec des ports non@host.
Astuce DNS : un enregistrement générique (*.yourdomain.com → cluster-public-ip) garantit que tout nouveau sous-domaine fonctionne immédiatement — aucune modification DNS n’est nécessaire pour chaque service.
DNS des services (interne)
Les services au sein du cluster se résolvent mutuellement par leur nom :
| Nom DNS | Résout vers |
|---|---|
service-name |
Tout conteneur opérationnel |
service-name.internal |
Le même |
rr.service-name.internal |
Round-robin |
nearest.service-name.internal |
Priorité aux machines locales |
Mise à l’échelle et services globaux
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
Modèles de balises d’image (dans compose.yaml)
image: myapp:{{gitdate "20060102"}}.{{gitsha 7}}
image: myapp:{{gitsha 7}}.${GITHUB_RUN_ID:-local}
| Fonction | Sortie |
|---|---|
{{gitsha N}} |
Les N premiers caractères du SHA de la validation |
{{gitdate "format"}} |
Date du commit Git au format Go |
{{date "format"}} |
Date du jour |
Workflows courants
Déploiement à partir du code source :
uc deploy # Build + push + deploy
uc build --push && uc deploy --no-build # Separate steps
Inspection d’un service :
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
Les déploiements sans interruption de service s'effectuent automatiquement ; « Uncloud » attend les résultats des contrôles d'intégrité avant de fermer les anciens conteneurs.
Forcer la recréation :
uc deploy --recreate
Erreurs courantes
| Erreur | Solution |
|---|---|
| Modification directe du fichier Caddyfile | Utilisez x-caddy dans la fenêtre de rédaction ou --caddyfile sur uc service run |
| Proxy d'un serveur en amont HTTPS avec un certificat auto-signé | Ajouter transport http { tls_insecure_skip_verify } |
uc caddy config n'affiche aucun bloc défini par l'utilisateur |
Socket d'administration de Caddy inaccessible — vérifier uc inspect caddy et uc logs caddy |
| Le service ne parvient pas à atteindre l'adresse IP LAN externe depuis le conteneur | Vérifiez que l'hôte du conteneur Caddy peut acheminer le trafic vers le réseau cible |
Volumes perdus après uc service rm |
Les volumes nommés persistent ; seuls les volumes anonymes sont supprimés automatiquement |
---
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 |
Tous les fichiers
1 fichiersInstaller uncloud
Téléchargez et décompressez les fichiers de compétences dans votre répertoire .claude/skills/.
Télécharger le ZIPClonez le dépôt et copiez les fichiers de compétence dans votre projet.
git clone https://github.com/affaan-m/ECC/tree/main/skills/uncloud # Copy SKILL.md to your .claude/skills/ directory
Copier





Maison
