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.
Wdrażanie serwera
Przegląd
Ten skill tworzy pojedynczą instancję Welley na DigitalOcean i potrafi uruchamiać aktualizacje przez SSH. Prowadzi agenta przez zebranie brakujących danych, pobranie dostępnych parametrów instancji ze wskazanego źródła, utworzenie maszyny wirtualnej, skonfigurowanie hosta, wdrożenie poleceniem wlycli deployment create i sprawdzenie wyniku.
Nazwy poleceń muszą zgadzać się z CLI:
wlycli deployment createwlycli deployment updatewlycli deployment delete
Ustawienia domyślne (DigitalOcean)
- Region:
nyc3 - Obraz:
latest LTS available via API(ustal przezimages?type=distribution) - Nazwa dropleta: losowo generowana jako
wlsly-<adjective>-<surname>(np.wlsly-bright-hopper). Użyj fragmentu generatora nazw zreferences/digitalocean.md. Jeśli tworzysz zarządzaną bazę danych, nadaj jej tę samą nazwę. - Docelowy plan: Basic / Regular (Shared CPU)
- Docelowy rozmiar: 2 vCPU / 4 GB RAM / 80 GB SSD / 4 TB transferu (ok. 24 USD miesięcznie)
Zmiana ustawień domyślnych
Jeśli użytkownik poda dowolną z wartości domyślnych (region, obraz, nazwę dropleta, projekt, rozmiar), agent musi:
- Powtórzyć tę zmianę dosłownie.
- Poprosić o potwierdzenie przed dalszymi krokami.
Szablon pytań do użytkownika
Pytaj tylko o to, czego brakuje. Używaj dokładnie tych pytań, żeby uniknąć nieporozumień. Pytaj w kilku rundach. Runda 1: najwyżej 2 pytania naraz. W rundzie 2 możesz zaproponować zbiorczą opcję „przyjmij wszystkie ustawienia domyślne”. Jeśli środowisko obsługuje wybór opcji, podaj 2 lub 3 opcje do każdego pytania (A/B/C). Unikaj pytań otwartych, chyba że to konieczne.
Pytania w rundzie 1 (podstawowe dane i dostęp):
- „Czy masz token API DigitalOcean, którego mam użyć, czy mam poczekać, aż go podasz?”
- „Jakiej domeny ma używać ten serwer (np.
super-puper.example.com)? Czy masz kontrolę nad jej DNS?” - „Czy masz już klucz publiczny SSH, którego mam użyć, czy mam go utworzyć i wgrać?”
- „Czy chcesz przypisać tego dropleta do istniejącego projektu DigitalOcean? Jeśli tak, podaj nazwę lub ID projektu.”
- „Wymaganie DNS: musisz utworzyć rekordy A/AAAA dla
<domain>istorage.<domain>(jeśli nie ma CDN). Czy możesz to zrobić, zanim uruchomię certbota?” - „Wymaganie DNS dla poczty: domena z
--smtp-frompotrzebuje rekordów SPF, DMARC i DKIM, bo inaczej zaproszenia i e-maile z potwierdzeniem do nowych odbiorców mogą po cichu przepadać. Czy rekordy są już ustawione, czy mam wypisać te, których potrzebuje twój dostawca SMTP?” - Jeśli użytkownik zapyta, gdzie zdobyć token DO, podaj ten link:
https://cloud.digitalocean.com/account/api/tokens
Pytania w rundzie 2 (rozmiar, lokalizacja i opcje wdrożenia):
- „Czy chcesz domyślny region
nyc3, czy inny?” - „Czy chcesz domyślny rozmiar (2 vCPU / 2 GB), czy inne parametry CPU/RAM?”
- „Mam użyć najnowszego Ubuntu LTS dostępnego w API, czy konkretnej wersji Ubuntu?”
- „Jakiego użytkownika SSH mamy używać po wstępnej konfiguracji (domyślnie:
wlsly)? Możesz zostawić domyślnego.” - „Chcesz zarządzaną bazę Postgres, czy dołączony kontener z Postgresem?”
- Jeśli wybrano zarządzany Postgres: „Jakiego regionu i rozmiaru bazy mam użyć? Mogę domyślnie wybrać
nyc3i 1 vCPU / 2 GB.” - Jeśli wybrano zarządzany Postgres: „Czy mam przejść do tworzenia bazy po cenie miesięcznej podanej przez dostawcę?”
- „Podaj wymagane ustawienia SMTP (host, użytkownik, hasło, nadawca). OTEL jest opcjonalny, podaj go tylko wtedy, gdy jest potrzebny.”
- „Adres e-mail administratora jest wymagany do utworzenia instancji. Podaj go teraz (flaga:
--email/-e). Jeśli go nie podasz, poproszę o niego dwa razy, żeby się upewnić.”
W rundzie 2 zaproponuj opcję „przyjmij wszystkie ustawienia domyślne”, żeby szybciej zebrać dane.
Jeśli brakuje którejś odpowiedzi, zadaj krótkie pytanie uzupełniające (jedno lub dwa).
Przebieg pracy (DigitalOcean, pojedyncza instancja)
- Zbierz wymagane dane (zapytaj, jeśli czegoś brakuje).
- Token API DigitalOcean
- Nazwa lub ID projektu (opcjonalnie; jeśli brak albo nie znaleziono, użyj projektu domyślnego)
- Region
- Docelowy rozmiar instancji (np. 4 vCPU / 16 GB RAM)
- Nazwa domeny
- Klucz publiczny SSH (lub zgoda na utworzenie i zarejestrowanie go)
- E-mail administratora do pierwszego logowania i odzyskiwania hasła (wymagany do utworzenia instancji;
--email/-e). Jeśli go brakuje, poproś o niego dwa razy i sprawdź, czy oba wpisy są takie same. - Opcjonalnie: własne certyfikaty TLS zamiast certbota
- Potwierdzenie dostępu do DNS (musisz móc utworzyć rekordy A/AAAA dla
<domain>i, jeśli jest używana, dlastorage.<domain>)
- Pobierz typy instancji i wybierz rozmiar.
- Użyj fragmentu sizes z
references/digitalocean.md, żeby wypisać rozmiary i przefiltrować je po CPU/RAM. - Jeśli pasuje kilka, potwierdź wybór z użytkownikiem.
2b. Ustal slug obrazu Ubuntu.
- Wywołaj
GET /v2/images?type=distribution&per_page=200i przefiltruj listę pod kątem Ubuntu. - Jeśli użytkownik poprosił o konkretną wersję, sprawdź, czy jej slug istnieje, i potwierdź.
- W przeciwnym razie wybierz z listy slug najnowszego LTS i przed utworzeniem dropleta potwierdź go z użytkownikiem.
- Utwórz dropleta.
- Używaj bezpośrednio API DigitalOcean (doctl jest opcjonalny).
- Obraz: wybierz ten, który wskazał użytkownik; w przeciwnym razie najnowszy LTS z listy z API.
- Dołącz odcisk (fingerprint) klucza SSH albo utwórz i wgraj nowy klucz.
- Włącz monitoring.
- Jeśli podano nazwę lub ID projektu, ale go nie znaleziono, utwórz dropleta bez projektu (w projekcie domyślnym).
- Uwaga: zarządzaną bazę danych można tworzyć równolegle z dropletem.
Wskazówki dotyczące równoległego działania
Agent powinien nakładać na siebie niezależne zadania, żeby skrócić czas oczekiwania:
- Podczas zbierania danych od użytkownika (runda 2) zacznij tworzyć dropleta, jeśli token, region, rozmiar, obraz i klucz SSH są już potwierdzone.
- Gdy droplet jest tworzony, zacznij tworzyć zarządzanego Postgresa (jeśli o niego poproszono).
- Gdy droplet się uruchamia, zbieraj dalej pozostałe dane (SMTP, OTEL, e-mail administratora).
- Jeśli do któregoś kroku brakuje krytycznych danych, wstrzymaj ten krok i zajmij się innymi zadaniami, które można robić równolegle.
- Jeśli DNS jest w DigitalOcean, utwórz lub zaktualizuj rekordy A/AAAA od razu, gdy tylko będzie znane IP dropleta (nie czekaj na krok pełnego wdrożenia).
- DNS i domena.
- Zapytaj, czy tworzyć lub aktualizować DNS w DigitalOcean, czy zostawić zewnętrzny DNS.
- Jeśli używasz DNS w DigitalOcean, utwórz rekordy A/AAAA wskazujące na IP dropleta.
- Skonfiguruj hosta przez SSH.
- Utwórz użytkownika innego niż root (np.
wlsly), nadaj mu sudo i skopiuj autoryzowane klucze SSH (authorized keys). - Wyloguj się z roota i zaloguj ponownie jako ten użytkownik, zanim pójdziesz dalej.
- Zainstaluj Dockera i docker compose.
- Pobierz plik binarny Welley CLI z AppStore i nadaj mu uprawnienia do uruchamiania:
- Bazowy URL:
https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=<os>/<arch> - Wybierz właściwą wartość
platformwedług systemu i architektury:- Linux x86_64:
linux/amd64 - Linux arm64:
linux/arm64 - macOS x86_64:
darwin/amd64 - macOS arm64:
darwin/arm64 - Windows x86_64:
windows/amd64
- Linux x86_64:
- Przykład (Linux x86_64):
curl -fL 'https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=linux/amd64' -o wlycli chmod +x wlycli - Oczekiwane nagłówki odpowiedzi obejmują:
x-artifact-display-name: Welley CLIx-artifact-full-name: social.wellesley.wlyclix-artifact-kind: clix-artifact-platform: <os>/<arch>, np.linux/amd64x-artifact-sha256: <sha256>x-artifact-version: <version>x-channel: develop
- Przed instalacją najlepiej sprawdź nagłówki zapytaniem HEAD i upewnij się, że nazwa artefaktu, rodzaj, platforma i kanał zgadzają się z żądanym plikiem binarnym.
- Bazowy URL:
- Zweryfikuj plik binarny CLI: uruchom
wlycli -viwlycli deployment --help, żeby potwierdzić oczekiwane informacje o buildzie.
- Wdróż Welley.
- Uruchom
wlycli deployment createz wymaganymi opcjami. - Użyj ustawień domyślnych dla pojedynczej instancji (bez zewnętrznego Postgresa, chyba że użytkownik o to poprosi).
- Jeśli potrzebny jest zarządzany Postgres, utwórz go najpierw (baza DigitalOcean), a potem użyj zwróconych wartości host/port/db/user/password we flagach
--postgres-*. - Jeśli API lub panel nie zwraca hasła użytkownika bazy, zresetuj uwierzytelnianie tego użytkownika, żeby dostać nowe dane dostępowe, zanim uruchomisz
wlycli. - Uruchomienia nieinteraktywne muszą przekazać
--email/-e, bo inaczej polecenie się nie powiedzie. --base-dirwskazuje katalog nadrzędny; CLI samo tworzy podkatalog projektu.- CLI odmawia działania, jeśli katalog projektu lub kontenery już istnieją; przed ponowną próbą trzeba to wyczyścić.
- Certyfikaty (obowiązkowe).
- Domyślnie: Certbot w trybie standalone (nieinteraktywnie).
- Użytkownik musi skierować rekordy DNS A/AAAA domeny (i
storage.<domain>, jeśli jest używana) na IP dropleta, zanim uruchomi się certbot. - CLI obsługuje
--public-ip(nadpisuje wykryte IP) oraz--skip-dns-preflight, jeśli koniecznie trzeba pominąć to sprawdzenie. - Nigdy nie zakładaj, że DNS jest skonfigurowany. Zapytaj i poczekaj na wyraźne potwierdzenie.
- Nigdy nie używaj
--skip-dns-preflight, chyba że użytkownik wyraźnie o to poprosi. - Jeśli CDN nie jest skonfigurowany, certbot musi uwzględnić
storage.<domain>w żądaniu certyfikatu. - Certyfikatów samopodpisanych używaj tylko wtedy, gdy użytkownik wyraźnie o to poprosi, i przekaż
--self-signed-certs(generuje certyfikaty samopodpisane w Go). - Podaj użytkownikowi instrukcję konfiguracji DNS i poczekaj na potwierdzenie:
- „Utwórz rekordy A/AAAA, tak żeby
<domain>wskazywała na IP dropleta.” - „Jeśli używasz
storage.<domain>, utwórz rekord A/AAAA także dla niej.” - „Gdy DNS się rozpropaguje, daj mi znać, a ja będę kontynuować. Nie widzę propagacji, chyba że poprosisz mnie o sprawdzenie rozwiązywania nazwy.”
- Agent może sam sprawdzić propagację DNS poleceniem
ping -c 1 <domain>i porównać IP z adresem dropleta. Jeśli się zgadza, kontynuuj.
7b. DNS poczty (SPF / DMARC / DKIM).
- Poczta z domeny bez SPF i DMARC jest często odrzucana przez Gmaila i Outlooka, gdy trafia do odbiorców po raz pierwszy, nawet jeśli dostawca SMTP raportuje ją jako dostarczoną.
deployment createwypisujeWarning:, gdy domena z--smtp-fromnie ma rekordu SPF albo nie ma rekordu DMARC w_dmarc.<domain>ani w domenie nadrzędnej. Nie blokuje to wdrożenia. Nigdy nie ignoruj tego ostrzeżenia: pokaż je użytkownikowi i podaj rekordy do dodania:<mail-domain>TXTv=spf1 include:<provider> ~all(dokładny include podaje dostawca SMTP; połącz go z istniejącym rekordem SPF, nigdy nie dodawaj drugiego)_dmarc.<mail-domain>TXTv=DMARC1; p=none; rua=mailto:dmarc@<mail-domain>- DKIM: rekordy
<selector>._domainkey.<mail-domain>, które dostawca SMTP generuje po zweryfikowaniu domeny
- Sprawdź poleceniami
dig +short TXT <mail-domain>idig +short TXT _dmarc.<mail-domain>. - CLI nie potrafi sprawdzić DKIM (selektor zależy od dostawcy). Zawsze poproś użytkownika o potwierdzenie, że DKIM jest zweryfikowany u dostawcy SMTP, nawet jeśli
createnie wypisało ostrzeżenia. W Amazon SES i podobnych usługach SPF jest sprawdzany dla własnej domeny koperty dostawcy, więc tylko DKIM może sprawić, że DMARC przejdzie. W SES: Verified identities, potem<mail-domain>, potem DKIM musi mieć status Successful.
- Sprawdź wynik i zdaj raport.
- Sprawdź
docker psi endpointy sprawdzania stanu usług. - Podaj końcowe dane połączenia i kolejne kroki.
Aktualizacja przez SSH
Gdy użytkownik poprosi o „aktualizację serwera”:
- Zapytaj o docelowego hosta lub IP oraz o użytkownika i klucz SSH.
- Uruchom
wlycli deployment update --domain <domain> [--force-restart]. - Sprawdź stan kontenerów i Nginx.
Zasoby
- Fragmenty kodu i przykłady dla API DigitalOcean:
references/digitalocean.md.
Sekrety i flagi
Używaj tych nazw flag dla sekretów:
- Host SMTP:
--smtp-host - Użytkownik SMTP:
--smtp-user - Hasło SMTP:
--smtp-password - Nadawca SMTP:
--smtp-from - Endpoint OTEL:
--otel-endpoint - Nagłówki OTEL:
--otel-headers
Minimalne polecenie create
Wymagane flagi:
--domain--email--smtp-host--smtp-user--smtp-password--smtp-from
Minimalny przykład:
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
Ustawienia domyślne zarządzanego Postgresa (DigitalOcean i CLI)
Gdy używasz zarządzanego Postgresa z DigitalOcean, nie polegaj na domyślnych ustawieniach CLI. Ustaw jawnie wszystkie flagi --postgres-*:
- Typowe ustawienia domyślne DO:
- Port:
25060 - Baza danych:
defaultdb - Użytkownik:
doadmin
- Port:
- Ustawienia domyślne CLI (jeśli pominiesz flagi):
- Port:
5432 - Baza danych:
wlsly - Użytkownik:
wlsly
- Port:
Uwagi o użyciu CLI
- Sprawdzenie wersji:
wlycli -vlubwlycli --version(flaga). Nie ma podpoleceniaversion. - Używaj
--base-dirtylko wtedy, gdy chcesz mieć inną lokalizację niż domyślna (domyślnie~/.welley). CLI utworzy katalog, jeśli ma do tego uprawnienia. - Nieinteraktywne uruchomienia przez SSH powinny zawierać
--emaili wszystkie wymagane flagi, żeby uniknąć pytań. - Jeśli użytkownik udostępni na serwerze plik binarny CLI (np.
~/wcli), używaj go bezpośrednio. Nie przenoś go, chyba że ktoś o to poprosi. - Kopiuj fragmenty dosłownie z
references/digitalocean.mddla wszystkich wywołań API DO. Nie przepisuj, nie zmieniaj i nie improwizuj parsowania w Pythonie. Nawet drobne zmiany (np. escapowanie, cudzysłowy) mogą zepsuć działanie w różnych powłokach. - Zdalne skrypty SSH: zawsze używaj
ssh host 'bash -s' << 'EOF'(heredoc w cudzysłowie). Nigdy nie używajssh host "..."w podwójnych cudzysłowach, bo zsh rozwija$(...)i[...]lokalnie, zanim wyśle polecenie na zdalnego hosta.
Naprawa po błędzie
Jeśli deployment create się nie powiedzie i musisz spróbować jeszcze raz:
- Użyj
wlycli deployment delete --domain <domain> --yes-please-delete-all-the-data, żeby wszystko wyczyścić. - Delete spróbuje wyczyścić pliki należące do roota za pomocą kontenera. Jeśli to się nie uda, usuń katalog projektu w
--base-dirz podwyższonymi uprawnieniami i uruchom polecenie ponownie.
Wstępny test portu 80 (opcjonalnie)
Jeśli certbot się nie powiedzie, przed ponownym uruchomieniem sprawdź, czy port 80 jest osiągalny:
docker run --rm -d -p 80:80 --name test-http nginx:alpine
curl -s http://<domain>:80
docker rm -f test-http