옵션

Uncloud 클러스터 관리 — `uc` CLI를 사용하여 서비스를 배포하고, Caddy 인그레스를 구성하며, 클러스터에 속하지 않은 장치에 대한 정적 프록시 경로를 추가하고, 포트를 공개하고, 확장하고, 로그를 확인하고, 머신 및 볼륨을 관리할 수 있습니다.

...모든 것을 확장하십시오
0
업데이트 된 시간 2026년 9월 30일

Uncloud 클러스터 관리

CLI 참조 — uc CLI — Docker 컨테이너, WireGuard 메쉬 네트워킹 및 Caddy 리버스 프록시를 사용하는 분산형 자체 호스팅 플랫폼.

활성화 시점

Uncloud 클러스터를 다룰 때, 특히 다음과 같은 경우에 이 스킬을 사용하십시오:

  • 다음과 같이 머신을 초기화하거나 클러스터에 가입할 때 uc machine
  • 다음과 같이 Compose 파일을 통해 서비스를 배포할 때 uc deploy
  • Uncloud를 통해 HTTP, HTTPS, TCP 또는 UDP 포트를 공개할 때
  • 다음과 같이 Caddy 인그레스를 구성할 때 x-caddy, x-ports, 또는 --caddyfile
  • 클러스터 프록시를 통해 외부 LAN 장치 라우팅
  • 로그, 서비스 상태, 볼륨, DNS 또는 머신 배치 확인

작동 원리

Uncloud 는 WireGuard 메시로 연결된 피어 머신 전반에 걸쳐 Docker 서비스를 실행합니다. 각 머신은 동등한 클러스터 구성원이며, 서비스는 오버레이 네트워크를 통해 통신하고, Caddy는 공용 HTTP/HTTPS 트래픽을 종단 처리하기 위해 전역적으로 실행됩니다. Compose 파일은 인그레스, 배치 및 생성된 Caddy 구성을 위해 Uncloud 확장자를 사용할 수 있으며, 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 컨테이너에 셸 접속
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, 라우터 UI)를 노출하려면:

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. 아무 작업도 수행하지 않는(no-op) 컨테이너로 명명된 서비스를 등록합니다:

uc service run \
  --name device-bmc \
  --caddyfile ~/device.caddyfile \
  registry.k8s.io/pause:3.9

pause 는 최소한의 무작동(no-op) 컨테이너입니다. 이 컨테이너는 아무런 작업도 수행하지 않지만, 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"}} Go 형식의 Git 커밋 날짜
{{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을 직접 편집하는 경우 'Compose'에서 x-caddy 'compose'에서 사용하거나 --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 이름이 지정된 볼륨은 유지되며, 익명 볼륨만 자동으로 제거됩니다
GitHub에서 보기
---
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

복사 복사
빠른 설정: 스킬 폴더를 .claude/skills/로 복사하세요. Claude가 해당 스킬을 자동으로 감지하여 사용할 것입니다.
저장소 affaan-m/ECC

관련 스킬

klingai-upgrade-migration
업데이트 된 시간 2026년 7월 3일
Verification & Quality Assurance
업데이트 된 시간 2026년 6월 29일
base44-cli
업데이트 된 시간 2026년 6월 29일
Railway CLI Management
업데이트 된 시간 2026년 7월 2일
OR