uncloud
affaan-m/ECC
管理 Uncloud 叢集 — 透過 `uc` CLI 部署服務、設定 Caddy Ingress、為非叢集裝置新增靜態代理路由、公開端口、進行擴展、檢視日誌,以及管理機器和儲存卷。
...展開全部Uncloud 叢集管理
關於 uc CLI 的參考指南 — 一個採用 Docker 容器、WireGuard 網格網路及 Caddy 反向代理的去中心化自建平台。
何時啟用
在處理 Uncloud 叢集時,請使用此功能,特別是在以下情況:
- 使用
uc machine - 透過 Compose 檔案部署服務時
uc deploy - 透過 Uncloud 發佈 HTTP、HTTPS、TCP 或 UDP 埠
- 透過
x-caddy,x-ports,或--caddyfile - 透過叢集代理伺服器路由外部 LAN 裝置
- 檢視日誌、服務狀態、儲存卷、DNS 或機器配置
運作原理
Uncloud 在透過 WireGuard 網格互連的對等機器上執行 Docker 服務。每台機器都是平等的叢集成員;服務在覆蓋網路中進行通訊,而 Caddy 則在全球範圍內運作以終止公開的 HTTP/HTTPS 流量。Compose 檔案可使用 Uncloud 擴充功能來設定入口、配置及生成的 Caddy 設定,而 uc CLI 則負責處理映像檔分發、排程、擴展、日誌及叢集狀態。
範例
uc machine init user@host --name machine-1
uc service run --name web -p app.example.com:8080/https nginx:latest
uc deploy
核心概念
- 無中央控制平面 — 所有機器皆為透過 WireGuard 連接的平等對等節點
- Caddy 在每台機器上作為全球性服務運行;自動從 Let's Encrypt 取得 TLS 憑證
- 覆蓋網路 — 服務預設透過
10.210.0.0/16進行通訊;DNS 由網格內部提供 - Caddyfile 會自動產生 — 切勿直接編輯;請使用
x-caddy/--caddyfile代替
CLI 快速參考
機器
| 指令 | 用途 |
|---|---|
uc machine init user@host |
初始化第一台機器/新叢集 |
uc machine add user@host |
將機器加入現有叢集 |
uc machine ls |
列出機器 |
uc machine update NAME --public-ip IP |
更新入站服務的公開 IP 位址 |
uc machine rm NAME |
移除機器 |
鍵 init 標誌: --name, --network 10.210.0.0/16, --no-caddy, --no-dns, --public-ip auto\|IP\|none
服務
| 指令 | 用途 |
|---|---|
uc service ls / uc ls |
列出服務 |
uc service run IMAGE |
執行單一容器服務 |
uc deploy |
從...部署 compose.yaml |
uc deploy --no-build |
部署已推送的映像檔,無需重新建置 |
uc deploy --recreate |
強制重新建立服務 |
uc scale SERVICE N |
設定複本數 |
uc service logs SERVICE |
檢視日誌 |
uc service exec SERVICE |
進入容器執行 shell 指令 |
uc service inspect SERVICE |
詳細資訊 |
uc service rm SERVICE |
移除服務(保留命名卷) |
uc ps |
叢集中的所有容器 |
映像檔
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
卷
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 與上下文
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
埠號公開
HTTP/HTTPS(透過 Caddy 反向代理)
-p [hostname:]container_port[/protocol]
| 範例 | 含義 |
|---|---|
-p 8080/https |
HTTPS 搭配自動 service-name.cluster-domain 主機名 |
-p app.example.com:8080/https |
使用自訂主機名的 HTTPS |
-p 8080/http |
僅 HTTP,無 TLS |
TCP/UDP(綁定主機,繞過 Caddy)
-p [host_ip:]host_port:container_port[/protocol]@host
| 範例 | 含義 |
|---|---|
-p 5432:5432@host |
所有介面上的 TCP 5432 |
-p 127.0.0.1:5432:5432@host |
僅限 TCP 5432 迴路連接 |
-p 53:5353/udp@host |
UDP |
Compose 檔案擴充功能
Uncloud 在 Docker Compose 之上新增以下擴充功能:
x-ports — 透過網域發佈端口
services:
app:
image: app:latest
x-ports:
- example.com:8000/https
- www.example.com:8000/https
- api.example.com:9000/https
x-caddy — 為服務自訂 Caddy 配置
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$...
}
}
模板內可用的函式 x-caddy:
{{upstreams [service] [port]}}— 正常運作的容器 IP 位址{{.Name}}— 服務名稱{{.Upstreams}}— 所有服務與 IP 的對應表
x-machines — 配置限制
services:
db:
image: postgres:18
x-machines: db-machine # Single machine name
app:
image: app:latest
x-machines:
- machine-1
- machine-2
完整的多服務範例
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:
路由至外部(非叢集)裝置
若要透過 Caddy 公開外部裝置(例如 BMC、NAS、路由器使用者介面),且無需實際執行容器:
1. 建立一個 Caddyfile 片段(例如: ~/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
}
針對純文字上游: reverse_proxy http://192.168.1.x:port
2. 註冊為帶有名稱的服務,並使用無操作容器:
uc service run \
--name device-bmc \
--caddyfile ~/device.caddyfile \
registry.k8s.io/pause:3.9
pause 是一個最簡化的無操作容器 —— 它不會執行任何操作,但會為 Uncloud 提供一個服務條目,以便將 Caddyfile 附加至該服務。
3. 驗證:
uc caddy config # device.example.com block should appear
--caddyfile無法與非@host已發佈的埠號。
DNS 提示:通配符記錄(*.yourdomain.com → cluster-public-ip) 表示任何新子網域都能立即生效 — 無需針對每個服務進行 DNS 變更。
服務 DNS(內部)
叢集內的服務會透過名稱相互解析:
| DNS 名稱 | 解析結果為 |
|---|---|
service-name |
任何運作正常的容器 |
service-name.internal |
相同 |
rr.service-name.internal |
輪詢 |
nearest.service-name.internal |
優先使用機器本機服務 |
擴展與全域服務
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
映像標籤範本(位於 compose.yaml 中)
image: myapp:{{gitdate "20060102"}}.{{gitsha 7}}
image: myapp:{{gitsha 7}}.${GITHUB_RUN_ID:-local}
| 函式 | 輸出 |
|---|---|
{{gitsha N}} |
提交 SHA 的前 N 個字元 |
{{gitdate "format"}} |
Git 提交日期(Go 格式) |
{{date "format"}} |
當前日期 |
常見工作流程
從原始碼部署:
uc deploy # Build + push + deploy
uc build --push && uc deploy --no-build # Separate steps
檢查服務:
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
零停機部署會自動進行;Uncloud 會在終止舊容器前,先等待健康檢查結果。
強制重建:
uc deploy --recreate
常見錯誤
| 錯誤 | 修正方法 |
|---|---|
| 直接編輯 Caddyfile | 請使用 x-caddy 在撰寫模式中,或 --caddyfile 於 uc service run |
| 透過自簽名憑證代理 HTTPS 上游伺服器 | 新增 transport http { tls_insecure_skip_verify } |
uc caddy config 顯示沒有使用者自定義區塊 |
無法連線至 Caddy 管理套接字 — 請檢查 uc inspect caddy 以及 uc logs caddy |
| 服務無法從容器存取外部 LAN IP | 請確認 Caddy 容器的主機能否路由至目標網路 |
在以下情況後,卷已遺失 uc service rm |
命名卷會保留;僅匿名卷會自動移除 |
---
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 |
所有檔案
1 個檔案安裝 uncloud
請下載並將技能檔案解壓縮至您的 .claude/skills/ 目錄中。
下載 ZIP複製儲存庫並將技能檔案複製到您的專案中。
git clone https://github.com/affaan-m/ECC/tree/main/skills/uncloud # Copy SKILL.md to your .claude/skills/ directory
複製





首頁
