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.
Deploy del server
Panoramica
Questa skill crea uno stack Welley a istanza singola su DigitalOcean e può eseguire aggiornamenti via SSH. Guida l'agente a raccogliere gli input mancanti, recuperare le specifiche delle istanze disponibili da una fonte definita, creare la VM, configurare l'host, fare il deploy con wlycli deployment create e validare il risultato.
I nomi dei comandi devono corrispondere a quelli della CLI:
wlycli deployment createwlycli deployment updatewlycli deployment delete
Valori predefiniti (DigitalOcean)
- Regione:
nyc3 - Immagine:
latest LTS available via API(risolvila conimages?type=distribution) - Nome del droplet: generato a caso come
wlsly-<adjective>-<surname>(es.wlsly-bright-hopper). Usa lo snippet del generatore di nomi inreferences/digitalocean.md. Se viene creato un database gestito, usa lo stesso nome anche per quello. - Piano di riferimento: Basic / Regular (Shared CPU)
- Dimensione di riferimento: 2 vCPU / 4 GB RAM / 80 GB SSD / 4 TB di trasferimento (~$24/mese)
Regola per modificare i valori predefiniti
Se l'utente specifica uno qualsiasi dei valori predefiniti (regione, immagine, nome del droplet, progetto, dimensione), l'agente deve:
- Ripetere all'utente la modifica parola per parola.
- Chiedere conferma prima di procedere.
Modello per raccogliere gli input
Chiedi solo ciò che manca. Usa esattamente queste domande, per ridurre le ambiguità. Procedi a round successivi. Round 1: massimo 2 domande per turno. Il round 2 può proporre un'unica opzione “accetta tutti i valori predefiniti”. Se l'ambiente supporta le scelte, proponi 2 o 3 opzioni per domanda (A/B/C). Evita le risposte libere se non sono necessarie.
Domande del round 1 (credenziali e accesso):
- “Hai un token API di DigitalOcean da usare, o devo aspettare che tu me ne fornisca uno?”
- “Quale dominio deve usare questo server (es.
super-puper.example.com)? Gestisci tu il suo DNS?” - “Hai già una chiave pubblica SSH da usare, o devo crearne e caricarne una io?”
- “Vuoi assegnare questo droplet a un progetto DigitalOcean esistente? Se sì, indicami il nome o l'ID del progetto.”
- “Requisito DNS: devi creare record A/AAAA per
<domain>estorage.<domain>(se non c'è una CDN). Puoi farlo prima che parta certbot?” - “Requisito DNS per le email: il dominio di
--smtp-fromha bisogno di record SPF, DMARC e DKIM, altrimenti le email di invito e di conferma ai nuovi destinatari potrebbero essere scartate senza alcun avviso. Sono già a posto, o vuoi che ti elenchi i record che servono al tuo provider SMTP?” - Se l'utente chiede dove ottenere un token DO, fornisci questo link:
https://cloud.digitalocean.com/account/api/tokens
Domande del round 2 (dimensione, posizione e opzioni di deploy):
- “Vuoi la regione predefinita
nyc3o un'altra regione?” - “Vuoi la dimensione predefinita (2 vCPU / 2 GB) o un altro obiettivo di CPU/RAM?”
- “Uso l'ultima Ubuntu LTS disponibile nell'API o una versione specifica di Ubuntu?”
- “Quale utente SSH dobbiamo usare dopo il bootstrap (predefinito:
wlsly)? Puoi tenere quello predefinito.” - “Vuoi un database Postgres gestito, o preferisci usare il container Postgres incluso?”
- Se è stato scelto il Postgres gestito: “Quale regione e quale dimensione devo usare per il database? Posso usare
nyc3e 1 vCPU / 2 GB come valori predefiniti.” - Se è stato scelto il Postgres gestito: “Vuoi che proceda con la creazione al prezzo mensile indicato dal provider?”
- “Indicami le impostazioni SMTP obbligatorie (host, utente, password, mittente). OTEL è facoltativo: indicalo solo se serve.”
- “L'email dell'amministratore è obbligatoria per la creazione. Indicala ora (flag:
--email/-e). Se non me la dai, te la chiederò due volte per conferma.”
Offri un'opzione “accetta tutti i valori predefiniti” nel round 2 per velocizzare la raccolta degli input.
Se manca qualche risposta, fai una domanda di approfondimento mirata (una o due domande).
Flusso di lavoro (DigitalOcean, istanza singola)
- Raccogli gli input necessari (chiedi se mancano).
- Token API di DigitalOcean
- Nome o ID del progetto (facoltativo; se manca o non viene trovato, usa il progetto predefinito)
- Regione
- Dimensione dell'istanza (es. 4 vCPU / 16 GB RAM)
- Nome di dominio
- Chiave pubblica SSH (o conferma per crearne e registrarne una)
- Email dell'amministratore per il primo accesso e il recupero della password (obbligatoria per create;
--email/-e). Se manca, chiedila due volte e verifica che coincidano. - Facoltativo: certificati TLS personalizzati invece di certbot
- Conferma dell'accesso al DNS (deve essere possibile creare record A/AAAA per
<domain>e, se usato, perstorage.<domain>)
- Recupera i tipi di istanza e scegli una dimensione.
- Usa lo snippet delle dimensioni in
references/digitalocean.mdper elencare le istanze e filtrarle per CPU/RAM. - Se ci sono più corrispondenze, chiedi conferma all'utente.
2b. Individua lo slug dell'immagine Ubuntu.
- Chiama
GET /v2/images?type=distribution&per_page=200e filtra per Ubuntu. - Se l'utente ha chiesto una versione specifica, verifica che il suo slug esista e chiedi conferma.
- Altrimenti scegli dall'elenco lo slug dell'ultima LTS e chiedi conferma all'utente prima della creazione.
- Crea il droplet.
- Usa direttamente l'API di DigitalOcean (doctl è facoltativo).
- Immagine: preferisci quella indicata dall'utente, altrimenti scegli l'ultima LTS dall'elenco dell'API.
- Collega l'impronta della chiave SSH oppure crea e carica una chiave.
- Attiva il monitoraggio.
- Se sono stati forniti il nome o l'ID del progetto ma il progetto non è stato trovato, crea il droplet senza progetto (progetto predefinito).
- Nota: la creazione del database gestito può avvenire in parallelo a quella del droplet.
Indicazioni sulla parallelizzazione
L'agente deve sovrapporre i task indipendenti per ridurre i tempi complessivi:
- Mentre raccogli gli input dell'utente (round 2), avvia la creazione del droplet se token, regione, dimensione, immagine e chiave SSH sono già confermati.
- Mentre il droplet è in fase di provisioning, avvia la creazione del Postgres gestito (se richiesto).
- Mentre il droplet si avvia, continua a raccogliere gli input rimanenti (SMTP, OTEL, email dell'amministratore).
- Se per un passaggio manca un input critico, metti in pausa quel passaggio e prosegui con gli altri task che si possono fare in parallelo.
- Se il DNS è gestito su DigitalOcean, crea o aggiorna i record A/AAAA appena l'IP del droplet è disponibile (non aspettare il passaggio di deploy completo).
- DNS / dominio.
- Chiedi se creare o aggiornare il DNS su DigitalOcean oppure lasciare il DNS esterno.
- Se usi il DNS di DigitalOcean, crea record A/AAAA che puntano all'IP del droplet.
- Configura l'host via SSH.
- Crea un utente non root (es.
wlsly), concedigli sudo e copia le chiavi SSH autorizzate. - Esci da root e rientra come utente non root prima di continuare.
- Installa Docker + docker compose.
- Scarica da AppStore il binario della CLI di Welley e rendilo eseguibile:
- URL di base:
https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=<os>/<arch> - Scegli il valore corretto di
platformin base a sistema operativo e architettura:- 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:
- Esempio (Linux x86_64):
curl -fL 'https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?develop=stable&platform=linux/amd64' -o wlycli chmod +x wlycli - Le intestazioni di risposta attese includono:
x-artifact-display-name: Welley CLIx-artifact-full-name: social.wellesley.wlyclix-artifact-kind: clix-artifact-platform: <os>/<arch>, ad esempiolinux/amd64x-artifact-sha256: <sha256>x-artifact-version: <version>x-channel: develop
- Prima di installare, è meglio controllare le intestazioni con una richiesta HEAD e verificare che nome dell'artefatto, tipo, piattaforma e canale corrispondano al binario richiesto.
- URL di base:
- Verifica il binario della CLI: esegui
wlycli -vewlycli deployment --helpper confermare le informazioni di build attese.
- Fai il deploy di Welley.
- Esegui
wlycli deployment createcon le opzioni necessarie. - Usa i valori predefiniti per l'istanza singola (nessun Postgres esterno, a meno che l'utente lo chieda).
- Se è richiesto un Postgres gestito, crealo prima (database DigitalOcean) e poi usa host/porta/db/utente/password restituiti nei flag
--postgres-*. - Se la password dell'utente del database non viene restituita dall'API o dall'interfaccia, reimposta l'autenticazione dell'utente del database per ottenere credenziali nuove prima di eseguire
wlycli. - Le esecuzioni non interattive devono passare
--email/-e, altrimenti il comando fallisce. --base-dirindica la directory padre; la CLI crea da sola la sottodirectory del progetto.- La CLI si rifiuta di partire se la directory del progetto o i container esistono già: prima di riprovare serve una pulizia.
- Certificati (obbligatori).
- Impostazione predefinita: usa Certbot in modalità standalone (non interattiva).
- L'utente deve far puntare all'IP del droplet i record DNS A/AAAA del dominio (e di
storage.<domain>, se usato) prima che parta certbot. - La CLI supporta
--public-ip(sostituisce l'IP rilevato) e--skip-dns-preflightse devi saltare il controllo. - Non dare mai per scontato che il DNS sia configurato. Chiedi e aspetta una conferma esplicita.
- Non usare mai
--skip-dns-preflight, a meno che l'utente lo chieda esplicitamente. - Se la CDN non è configurata, certbot deve includere
storage.<domain>nella richiesta del certificato. - Usa certificati autofirmati solo se l'utente lo chiede esplicitamente, e passa
--self-signed-certs(genera certificati autofirmati in Go). - Dai all'utente le istruzioni per configurare il DNS e aspetta la conferma:
- “Crea record A/AAAA in modo che
<domain>punti all'IP del droplet.” - “Se usi
storage.<domain>, crea un record A/AAAA anche per quello.” - “Quando il DNS si è propagato, scrivimelo e io continuo. Non posso vedere la propagazione, a meno che tu non mi chieda di verificare la risoluzione.”
- L'agente può verificare da solo la propagazione del DNS con
ping -c 1 <domain>, confrontando l'IP con quello del droplet. Se coincide, procede.
7b. DNS per le email (SPF / DMARC / DKIM).
- Le email inviate da un dominio senza SPF e DMARC vengono spesso scartate da Gmail e Outlook quando il destinatario le riceve per la prima volta, anche se il provider SMTP le segnala come consegnate.
deployment createstampa unWarning:quando il dominio di--smtp-fromnon ha un record SPF, oppure non ha un record DMARC in_dmarc.<domain>o in un dominio padre. Non blocca il deploy. Non ignorare mai l'avviso: mostralo all'utente e dagli i record da aggiungere:<mail-domain>TXTv=spf1 include:<provider> ~all(l'include esatto dipende dal provider SMTP; unisci il valore a un record SPF già esistente e non aggiungerne mai un secondo)_dmarc.<mail-domain>TXTv=DMARC1; p=none; rua=mailto:dmarc@<mail-domain>- DKIM: i record
<selector>._domainkey.<mail-domain>che il provider SMTP genera quando il dominio viene verificato
- Controlla con
dig +short TXT <mail-domain>edig +short TXT _dmarc.<mail-domain>. - La CLI non può controllare DKIM (il selector dipende dal provider). Chiedi sempre all'utente di confermare che DKIM sia verificato presso il provider SMTP, anche quando
createnon ha stampato nessun avviso. Con Amazon SES e provider simili, SPF viene controllato sul dominio envelope del provider stesso, quindi solo DKIM può far passare DMARC. In SES, apri Verified identities e poi<mail-domain>: la voce DKIM deve risultare Successful.
- Verifica e riepiloga.
- Controlla
docker pse gli endpoint di stato dei servizi. - Fornisci i dettagli finali di connessione e i passi successivi.
Aggiornamento via SSH
Quando l'utente chiede “aggiorna il server”:
- Chiedi host/IP di destinazione e utente/chiave SSH.
- Esegui
wlycli deployment update --domain <domain> [--force-restart]. - Verifica lo stato dei container e di Nginx.
Risorse
- Snippet ed esempi dell'API di DigitalOcean:
references/digitalocean.md.
Flag per i segreti
Usa questi nomi di flag per i segreti:
- Host SMTP:
--smtp-host - Utente SMTP:
--smtp-user - Password SMTP:
--smtp-password - Mittente SMTP:
--smtp-from - Endpoint OTEL:
--otel-endpoint - Header OTEL:
--otel-headers
Comando create minimo
Flag obbligatori:
--domain--email--smtp-host--smtp-user--smtp-password--smtp-from
Esempio minimo:
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
Valori predefiniti del Postgres gestito (DigitalOcean e CLI)
Quando usi il Postgres gestito di DigitalOcean, non fare affidamento sui valori predefiniti della CLI. Imposta esplicitamente tutti i flag --postgres-*:
- Valori predefiniti tipici di DO:
- Porta:
25060 - Database:
defaultdb - Utente:
doadmin
- Porta:
- Valori predefiniti della CLI (se ometti i flag):
- Porta:
5432 - Database:
wlsly - Utente:
wlsly
- Porta:
Note sull'uso della CLI
- Controllo della versione:
wlycli -voppurewlycli --version(flag). Non esiste un sottocomandoversion. - Usa
--base-dirsolo se vuoi una posizione diversa da quella predefinita (il valore predefinito è~/.welley). La CLI crea la directory se ha i permessi. - Le esecuzioni SSH non interattive devono includere
--emaile tutti i flag necessari, per evitare le richieste. - Se l'utente fornisce un binario della CLI sul server (es.
~/wcli), usalo direttamente. Non spostarlo, a meno che ti venga chiesto. - Copia gli snippet alla lettera da
references/digitalocean.mdper tutte le chiamate all'API di DO. Non riscrivere, adattare o improvvisare il parsing Python: anche piccole modifiche (es. escaping o virgolette) possono smettere di funzionare su shell diverse. - Script remoti via SSH: usa sempre
ssh host 'bash -s' << 'EOF'(heredoc tra apici). Non usare maissh host "..."con le virgolette doppie: zsh espande$(...)e[...]in locale prima di inviarli all'host remoto.
Recupero dopo un errore
Se deployment create fallisce e devi riprovare:
- Usa
wlycli deployment delete --domain <domain> --yes-please-delete-all-the-dataper fare pulizia. - Delete prova a pulire tramite container i file che appartengono a root. Se fallisce ancora, rimuovi la directory del progetto sotto
--base-dircon permessi elevati e riesegui il comando.
Test preliminare della porta 80 (facoltativo)
Se certbot fallisce, prima di riprovare verifica che la porta 80 sia raggiungibile:
docker run --rm -d -p 80:80 --name test-http nginx:alpine
curl -s http://<domain>:80
docker rm -f test-http