skills/deploy-server/SKILL.md

```
name: deploy-server
description: Use this skill to provision or update a Welley server on a supported cloud (currently DigitalOcean) when the user asks to deploy a new instance or run a server update. Covers single-instance deployments and SSH-based updates, including interactive collection of missing credentials, SSH keys, domain, region, and sizing.
```

# Nasazení serveru

## Přehled

Tento skill vytvoří na DigitalOcean jednu instanci Welley a umí spouštět aktualizace přes SSH. Agenta vede k tomu, aby si doptal chybějící údaje, z určeného zdroje načetl dostupné parametry instancí, vytvořil virtuální stroj, nastavil hostitele, nasadil Welley příkazem `wlycli deployment create` a výsledek ověřil.

Názvy příkazů musí odpovídat CLI:

-   `wlycli deployment create`
-   `wlycli deployment update`
-   `wlycli deployment delete`

## Výchozí hodnoty (DigitalOcean)

-   Region: `nyc3`
-   Image: `latest LTS available via API` (zjistěte přes `images?type=distribution`)
-   Název dropletu: náhodně vygenerovaný ve tvaru `wlsly-<adjective>-<surname>` (např. `wlsly-bright-hopper`). Použijte generátor názvů z `references/digitalocean.md`. Pokud vytváříte spravovanou databázi, dejte jí stejný název.
-   Cílový plán: Basic / Regular (Shared CPU)
-   Cílová velikost: 2 vCPU / 4 GB RAM / 80 GB SSD / 4 TB přenosu (asi 24 USD za měsíc)

## Pravidlo pro změnu výchozích hodnot

Pokud uživatel určí jinou hodnotu než výchozí (region, image, název dropletu, projekt, velikost), agent musí:

1.  Zopakovat změnu doslova zpět uživateli.
2.  Před pokračováním požádat o potvrzení.

## Šablona interaktivního zadávání

Ptejte se jen na to, co chybí. Použijte přesně tyto otázky, aby nevznikaly nejasnosti. Ptejte se postupně v kolech. V 1. kole nejvýše 2 otázky najednou. Ve 2. kole můžete nabídnout společnou možnost „přijmout všechny výchozí hodnoty“. Pokud prostředí podporuje výběr z možností, nabídněte u každé otázky 2 až 3 možnosti (A/B/C). Volné odpovědi používejte jen v nezbytných případech.

Otázky 1. kola (identita a přístup):

1.  „Máte API token DigitalOcean, který mám použít, nebo mám počkat, až ho zadáte?“
2.  „Jakou doménu má tento server používat (např. `super-puper.example.com`)? Spravujete její DNS?“
3.  „Máte už veřejný klíč SSH, který mám použít, nebo mám nějaký vytvořit a nahrát?“
4.  „Chcete tento droplet přiřadit do existujícího projektu DigitalOcean? Pokud ano, zadejte název nebo ID projektu.“
5.  „Požadavek na DNS: musíte vytvořit záznamy A/AAAA pro `<domain>` a `storage.<domain>` (pokud nepoužíváte CDN). Zvládnete to, než se spustí certbot?“
6.  „Požadavek na DNS pro e-mail: doména v `--smtp-from` potřebuje záznamy SPF, DMARC a DKIM, jinak mohou být pozvánky a potvrzovací e-maily pro nové příjemce bez upozornění zahozeny. Jsou záznamy nastavené, nebo mám vypsat záznamy, které váš poskytovatel SMTP potřebuje?“
7.  Pokud se uživatel zeptá, kde získat token DO, pošlete mu tento odkaz:

```
https://cloud.digitalocean.com/account/api/tokens
```

Otázky 2. kola (velikost, umístění a možnosti nasazení):

1.  „Chcete výchozí region `nyc3`, nebo jiný?“
2.  „Chcete výchozí velikost (2 vCPU / 2 GB), nebo jiný cíl pro CPU a RAM?“
3.  „Mám použít nejnovější Ubuntu LTS dostupné v API, nebo konkrétní verzi Ubuntu?“
4.  „Jakého uživatele SSH máme po úvodním nastavení používat (výchozí: `wlsly`)? Můžete nechat výchozí.“
5.  „Chcete spravovanou databázi Postgres, nebo vestavěný kontejner s Postgresem?“
6.  Pokud je zvolen spravovaný Postgres: „Jaký region a jakou velikost databáze mám použít? Mohu zvolit `nyc3` a 1 vCPU / 2 GB.“
7.  Pokud je zvolen spravovaný Postgres: „Mám databázi vytvořit za měsíční cenu, kterou uvádí poskytovatel?“
8.  „Zadejte prosím povinné nastavení SMTP (host, uživatel, heslo, odesílatel). OTEL je volitelný, zadejte ho jen v případě potřeby.“
9.  „K vytvoření je potřeba e-mail správce. Zadejte ho teď (přepínač: `--email` / `-e`). Pokud ho nezadáte, požádám vás o něj dvakrát, abych ho ověřil.“

Ve 2. kole nabídněte možnost „přijmout všechny výchozí hodnoty“, aby sběr údajů šel rychleji.

Pokud některá odpověď chybí, položte cílenou doplňující otázku (jednu nebo dvě).

## Postup (DigitalOcean, jedna instance)

1.  **Získejte potřebné údaje (zeptejte se, pokud chybí).**

-   API token DigitalOcean
-   Název nebo ID projektu (volitelné; pokud chybí nebo se nenajde, použije se výchozí projekt)
-   Region
-   Cílová velikost instance (např. 4 vCPU / 16 GB RAM)
-   Název domény
-   Veřejný klíč SSH (nebo potvrzení, že se má vytvořit a zaregistrovat)
-   E-mail správce pro první přihlášení a obnovu hesla (povinný při vytvoření; `--email` / `-e`). Pokud chybí, zeptejte se dvakrát a ověřte, že se obě zadání shodují.
-   Volitelně: vlastní certifikáty TLS, nebo certbot
-   Potvrzení přístupu k DNS (musí být možné vytvořit záznamy A/AAAA pro `<domain>` a případně i pro `storage.<domain>`)

1.  **Načtěte typy instancí a vyberte velikost.**

-   K výpisu a filtrování podle CPU a RAM použijte úryvek pro velikosti z `references/digitalocean.md`.
-   Pokud vyhovuje více možností, požádejte uživatele o potvrzení.

2b. **Zjistěte slug image Ubuntu.**

-   Zavolejte `GET /v2/images?type=distribution&per_page=200` a vyfiltrujte Ubuntu.
-   Pokud uživatel chtěl konkrétní verzi, ověřte, že její slug existuje, a nechte si ji potvrdit.
-   Jinak vyberte ze seznamu slug nejnovějšího LTS a před vytvořením ho nechte uživatelem potvrdit.

1.  **Vytvořte droplet.**

-   Použijte přímo API DigitalOcean (doctl je volitelný).
-   Image: upřednostněte ten, který určil uživatel, jinak vyberte nejnovější LTS ze seznamu z API.
-   Připojte otisk klíče SSH, nebo klíč vytvořte a nahrajte.
-   Zapněte monitoring.
-   Pokud byl zadán název nebo ID projektu, ale projekt se nenašel, vytvořte droplet bez projektu (ve výchozím projektu).
-   Poznámka: spravovanou databázi lze vytvářet souběžně s dropletem.

## Souběžné provádění

Agent by měl překrývat nezávislé úkoly, aby se zkrátila celková doba čekání:

-   Během sběru údajů od uživatele (2. kolo) začněte vytvářet droplet, pokud už jsou potvrzené token, region, velikost, image a klíč SSH.
-   Zatímco se droplet vytváří, začněte vytvářet spravovaný Postgres (pokud o něj uživatel požádal).
-   Zatímco droplet startuje, pokračujte ve sběru zbývajících údajů (SMTP, OTEL, e-mail správce).
-   Pokud pro některý krok chybí kritický údaj, tento krok pozastavte a pokračujte dalšími úkoly, které lze dělat souběžně.
-   Pokud se DNS spravuje v DigitalOcean, vytvořte nebo upravte záznamy A/AAAA hned, jak bude známá IP adresa dropletu (nečekejte na samotný krok nasazení).

1.  **DNS a doména.**

-   Zeptejte se, zda se má DNS vytvořit nebo upravit v DigitalOcean, nebo zda zůstane externí.
-   Pokud používáte DNS DigitalOcean, vytvořte záznamy A/AAAA na IP adresu dropletu.

1.  **Nastavte hostitele přes SSH.**

-   Vytvořte uživatele bez práv roota (např. `wlsly`), dejte mu sudo a zkopírujte mu autorizované klíče SSH.
-   **Odhlaste se z roota a před pokračováním se znovu přihlaste jako uživatel bez práv roota.**
-   Nainstalujte Docker a docker compose.
-   Stáhněte binárku Welley CLI z AppStore a nastavte ji jako spustitelnou:
    -   Základní URL: `https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=<os>/<arch>`
    -   Správnou hodnotu `platform` zvolte podle OS a architektury:
        -   Linux x86\_64: `linux/amd64`
        -   Linux arm64: `linux/arm64`
        -   macOS x86\_64: `darwin/amd64`
        -   macOS arm64: `darwin/arm64`
        -   Windows x86\_64: `windows/amd64`
    -   Příklad (Linux x86\_64):
        
        ```
        curl -fL 'https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=linux/amd64' -o wlycli
        chmod +x wlycli
        ```
        
    -   Očekávané hlavičky odpovědi zahrnují:
        -   `x-artifact-display-name: Welley CLI`
        -   `x-artifact-full-name: social.wellesley.wlycli`
        -   `x-artifact-kind: cli`
        -   `x-artifact-platform: <os>/<arch>`, například `linux/amd64`
        -   `x-artifact-sha256: <sha256>`
        -   `x-artifact-version: <version>`
        -   `x-channel: develop`
    -   Před instalací raději zkontrolujte hlavičky požadavkem HEAD a ověřte, že název artefaktu, druh, platforma a kanál odpovídají požadované binárce.
-   Ověřte binárku CLI: spusťte `wlycli -v` a `wlycli deployment --help` a potvrďte, že informace o sestavení odpovídají očekávání.

1.  **Nasaďte Welley.**

-   Spusťte `wlycli deployment create` s požadovanými možnostmi.
-   Použijte výchozí nastavení pro jednu instanci (bez externího Postgresu, pokud o něj uživatel nepožádá).
-   Pokud uživatel chce spravovaný Postgres, nejdřív ho vytvořte (databáze DigitalOcean) a vrácený host, port, databázi, uživatele a heslo použijte v přepínačích `--postgres-*`.
-   Pokud API nebo UI heslo uživatele databáze nevrátí, před spuštěním `wlycli` resetujte přihlášení uživatele databáze a získejte nové přihlašovací údaje.
-   Neinteraktivní spuštění musí obsahovat `--email` / `-e`, jinak příkaz selže.
-   `--base-dir` ukazuje na nadřazený adresář, podadresář projektu vytvoří CLI samo.
-   CLI odmítne běžet, pokud adresář projektu nebo kontejnery už existují. Před dalším pokusem je nutné je odstranit.

1.  **Certifikáty (povinné).**

-   Výchozí postup: použijte Certbot ve standalone režimu (neinteraktivně).
-   **Uživatel musí před spuštěním certbotu nasměrovat záznamy DNS A/AAAA domény (a případně `storage.<domain>`) na IP adresu dropletu.**
-   CLI podporuje `--public-ip` (přepíše zjištěnou IP adresu) a `--skip-dns-preflight`, pokud je nutné kontrolu obejít.
-   **Nikdy nepředpokládejte, že je DNS nastavené. Zeptejte se a počkejte na výslovné potvrzení.**
-   **Nikdy nepoužívejte `--skip-dns-preflight`, pokud o to uživatel výslovně nepožádá.**
-   Pokud není nastavené CDN, musí certbot v žádosti o certifikát zahrnout i `storage.<domain>`.
-   Self-signed certifikáty použijte jen tehdy, když o ně uživatel výslovně požádá, a předejte `--self-signed-certs` (certifikáty se vygenerují v Go).
-   Dejte uživateli pokyny k nastavení DNS a počkejte na potvrzení:
-   „Vytvořte záznamy A/AAAA tak, aby se `<domain>` překládala na IP adresu dropletu.“
-   „Pokud používáte `storage.<domain>`, vytvořte záznam A/AAAA i pro něj.“
-   „Až se DNS rozšíří, napište mi a budu pokračovat. Šíření nevidím, dokud mě nepožádáte, abych překlad ověřil.“
-   Agent může šíření DNS ověřit i sám pomocí `ping -c 1 <domain>` a porovnat IP adresu s dropletem. Pokud se shoduje, může pokračovat.

7b. **DNS pro e-mail (SPF / DMARC / DKIM).**

-   Gmail a Outlook často zahodí poštu z domény bez SPF a DMARC, pokud příjemce dostává e-mail z této domény poprvé, i když poskytovatel SMTP hlásí, že byla doručena.
-   `deployment create` vypíše `Warning:`, pokud doména v `--smtp-from` nemá záznam SPF, nebo nemá záznam DMARC na `_dmarc.<domain>` či v nadřazené doméně. Nasazení to neblokuje. Varování nikdy neignorujte: ukažte ho uživateli a dejte mu záznamy, které má přidat:
    -   `<mail-domain>` TXT `v=spf1 include:<provider> ~all` (přesnou hodnotu include dodá poskytovatel SMTP; sloučte ji s existujícím záznamem SPF, nikdy nepřidávejte druhý)
    -   `_dmarc.<mail-domain>` TXT `v=DMARC1; p=none; rua=mailto:dmarc@<mail-domain>`
    -   DKIM: záznamy `<selector>._domainkey.<mail-domain>`, které poskytovatel SMTP vygeneruje po ověření domény
-   Zkontrolujte je příkazy `dig +short TXT <mail-domain>` a `dig +short TXT _dmarc.<mail-domain>`.
-   CLI DKIM zkontrolovat neumí (selektor se liší podle poskytovatele). Vždy požádejte uživatele o potvrzení, že je DKIM u poskytovatele SMTP ověřený, i když `create` žádné varování nevypsal. U Amazon SES a podobných poskytovatelů se SPF kontroluje pro vlastní obálkovou doménu poskytovatele, takže DMARC může projít jen díky DKIM. V SES musí v části _Verified identities_ u položky `<mail-domain>` být DKIM ve stavu _Successful_.

1.  **Ověřte a podejte zprávu.**

-   Zkontrolujte `docker ps` a koncové body stavu služeb.
-   Předejte uživateli konečné údaje o připojení a další kroky.

## Aktualizace přes SSH

Když uživatel požádá o „aktualizaci serveru“:

1.  Zeptejte se na cílového hostitele nebo IP adresu a na uživatele a klíč SSH.
2.  Spusťte `wlycli deployment update --domain <domain> [--force-restart]`.
3.  Ověřte stav kontejnerů a Nginxu.

## Zdroje

-   Úryvky a příklady pro API DigitalOcean: `references/digitalocean.md`.

## Tajné údaje a přepínače

Pro tajné údaje používejte tyto názvy přepínačů:

-   Host SMTP: `--smtp-host`
-   Uživatel SMTP: `--smtp-user`
-   Heslo SMTP: `--smtp-password`
-   Odesílatel SMTP: `--smtp-from`
-   Koncový bod OTEL: `--otel-endpoint`
-   Hlavičky OTEL: `--otel-headers`

## Minimální příkaz pro vytvoření

Povinné přepínače:

-   `--domain`
-   `--email`
-   `--smtp-host`
-   `--smtp-user`
-   `--smtp-password`
-   `--smtp-from`

Minimální příklad:

```
wlycli deployment create \
  --domain example.com \
  --email admin@example.com \
  --smtp-host smtp.example.com \
  --smtp-user user \
  --smtp-password pass \
  --smtp-from noreply@example.com
```

## Výchozí hodnoty spravovaného Postgresu (DigitalOcean a CLI)

Když používáte spravovaný Postgres od DigitalOcean, nespoléhejte na výchozí hodnoty CLI. Všechny přepínače `--postgres-*` nastavte výslovně:

-   Typické výchozí hodnoty DO:
    -   Port: `25060`
    -   Databáze: `defaultdb`
    -   Uživatel: `doadmin`
-   Výchozí hodnoty CLI (pokud přepínače vynecháte):
    -   Port: `5432`
    -   Databáze: `wlsly`
    -   Uživatel: `wlsly`

## Poznámky k používání CLI

-   Kontrola verze: `wlycli -v` nebo `wlycli --version` (přepínač). Podpříkaz `version` neexistuje.
-   `--base-dir` použijte, jen pokud chcete jiné než výchozí umístění (výchozí je `~/.welley`). CLI adresář vytvoří, pokud na to má oprávnění.
-   Neinteraktivní spuštění přes SSH by mělo obsahovat `--email` a všechny povinné přepínače, aby se příkaz na nic nedoptával.
-   Pokud uživatel nahrál binárku CLI na server (např. `~/wcli`), použijte ji přímo. Nepřesouvejte ji, pokud o to nikdo nepožádá.
-   **Úryvky kopírujte doslova** z `references/digitalocean.md` pro všechna volání API DO. Parsování v Pythonu nepřepisujte, neupravujte ani nevymýšlejte po svém. I malé změny (např. escapování nebo uvozovky) mohou v různých shellech přestat fungovat.
-   **Vzdálené skripty přes SSH:** Vždy používejte `ssh host 'bash -s' << 'EOF'` (heredoc v uvozovkách). Nikdy nepoužívejte `ssh host "..."` s dvojitými uvozovkami: zsh rozbalí `$(...)` a `[...]` lokálně, ještě než se příkaz odešle na vzdáleného hostitele.

## Obnova po selhání

Pokud `deployment create` selže a potřebujete to zkusit znovu:

-   K úklidu použijte `wlycli deployment delete --domain <domain> --yes-please-delete-all-the-data`.
-   Příkaz delete se pokusí soubory vlastněné rootem uklidit přes kontejner. Pokud to přesto selže, odstraňte adresář projektu v `--base-dir` se zvýšenými oprávněními a spusťte příkaz znovu.

## Předběžný test portu 80 (volitelný)

Pokud certbot selže, před dalším pokusem otestujte dostupnost portu 80:

```
docker run --rm -d -p 80:80 --name test-http nginx:alpine
curl -s http://<domain>:80
docker rm -f test-http
```

## Další dokumenty

-   [**Welley CLI** docs/index.md](https://welley.com/cs/administrators/docs/cli/)
-   [**Rychlý start: minimální nasazení Welley** docs/quick-start.md](https://welley.com/cs/administrators/docs/quick-start/)
-   [**openai.yaml** skills/deploy-server/agents/openai.yaml](https://welley.com/cs/administrators/docs/deploy-server-openai-yaml/)
-   [**Referenční informace k DigitalOcean** skills/deploy-server/references/digitalocean.md](https://welley.com/cs/administrators/docs/deploy-server-digitalocean/)
