# Deploy dalla riga di comando con la CLI di Vimonto Deploy

> Installa la CLI di Vimonto Deploy, accedi con un token API e fai il deploy dei siti, segui i task, avvia ricette e backup dal terminale o da una pipeline CI.

La CLI di Vimonto Deploy è un piccolo strumento a riga di comando chiamato `deploy`. Con lei fai il deploy di un sito, ne segui l'output e il codice di uscita, elenchi i tuoi server e siti e avvii ricette e backup, dal tuo terminale o da una pipeline CI come GitHub Actions o GitLab CI.

La CLI è un client leggero dell'[API di Vimonto Deploy](https://ops.vimonto.com/docs/it/more/api): ogni comando è una o più richieste all'API, firmate con un token API personale. Può fare esattamente ciò che il token e il tuo ruolo nell'organizzazione permettono, niente di più.

## Di cosa hai bisogno?

- **PHP 8.2 o successivo con l'estensione curl.** La CLI è un unico file PHP senza dipendenze, quindi non serve un'installazione con Composer. Verificalo con `php -v` e `php -m | grep curl`.
- **Un token API**, creato in **Impostazioni account** → **Token API** (vedi [il tuo account](https://ops.vimonto.com/docs/it/more/account)). Il token viene mostrato una sola volta, quando lo crei.
- macOS, Linux o WSL. Su Windows la CLI funziona anche con `php deploy …`, ma nasconde il token mentre lo digiti solo su macOS e Linux.

## Installare la CLI

La CLI è il singolo file `deploy`. Scaricalo dal tuo indirizzo di Vimonto Deploy su `/cli/deploy` (il link è anche in **Impostazioni account** → **Token API**, con il comando da copiare), rendilo eseguibile e mettilo in una cartella del tuo `PATH`:

```bash
curl -fsSL https://deploy.example.com/cli/deploy -o deploy
chmod +x deploy
sudo mv deploy /usr/local/bin/deploy
deploy --version
```

`deploy --version` (o `deploy version`) mostra la versione, ad esempio `deploy 1.1.0`. Senza spostare il file puoi anche eseguirlo direttamente con `./deploy` o `php deploy`.

In una pipeline CI, fai il commit del file nel tuo repository (ad esempio come `bin/deploy`), oppure scaricalo nel job con lo stesso comando `curl`, ed eseguilo con `php bin/deploy`. La CLI non ha altri file e non richiede installazione. Per aggiornarla, scaricala di nuovo.

## Creare un token API

1. Apri **Impostazioni account** → **Token API** e clicca su **Nuovo token**.
2. Dagli un **Nome** che dica dove viene usato, come `GitHub Actions` o `Il mio portatile`.
3. Scegli gli **Ambiti**: **Lettura**, **Deploy** e/o **Scrittura** (vedi la tabella qui sotto).
4. Scegli quando **Scade**: tra 30, 90 o 365 giorni, oppure **Mai**.
5. Clicca su **Crea token** e copia il token da **Il tuo nuovo token**. Viene mostrato una sola volta; viene salvato solo il suo hash.

![La pagina Token API nelle impostazioni account](https://ops.vimonto.com/docs-media/it/account-api-tokens.webp?v=161e760d "Token API")

### Di quali ambiti ha bisogno un comando?

Gli elenchi richiedono **Lettura** (o **Scrittura**). Un token con solo **Deploy** può comunque fare il deploy di un sito e seguirlo: la CLI cerca il sito per dominio o id, cosa che questo ambito permette. Gli altri lavori richiedono **Scrittura**.

| Comandi | Ambiti necessari al token |
|---|---|
| `login`, `orgs`, `use` | Qualsiasi ambito |
| `servers`, `sites`, `databases`, `recipes`, `backups` | **Lettura** o **Scrittura** |
| `deployments`, `task` | **Lettura**, **Deploy** o **Scrittura** |
| `deploy` | **Deploy** o **Scrittura** |
| `database:create`, `recipe:run`, `backup:run` | **Scrittura** |

Oltre agli ambiti vale il tuo ruolo nell'organizzazione: un token non può mai fare più di te. Un osservatore non può fare il deploy, nemmeno con un token con **Scrittura**, e i server a cui non hai accesso non vengono elencati. Per una pipeline CI che fa solo il deploy, crea un token con il solo **Deploy**.

## Accedere con deploy login

Esegui `deploy login` e rispondi alle due domande: l'indirizzo di Vimonto Deploy (l'URL che apri nel browser) e il token API. Il token non viene mostrato mentre lo digiti o lo incolli.

```text
$ deploy login
URL of your Deploy app, such as https://deploy.example.com: https://deploy.example.com
API token (Account → API tokens):
✓ Logged in as Jane Doe (jane@example.com), scopes: read, deploy.
Organization: acme (change with "deploy use <org>")
```

Puoi anche passarli entrambi subito: `deploy login --url=https://deploy.example.com --token=…`. Tieni presente che un token scritto sulla riga di comando finisce nella cronologia della shell.

La CLI controlla il token, poi salva l'URL, il token e l'organizzazione (quella che indichi con `--org <slug>`, altrimenti quella salvata prima, altrimenti la prima delle tue; `DEPLOY_ORG` non viene mai salvata) in `~/.config/deploy/config.json` (o `$XDG_CONFIG_HOME/deploy/config.json` se quella variabile è impostata). La cartella viene creata con modalità `0700` e il file con `0600`, così solo tu puoi leggerlo. Per uscire elimina quel file, e revoca il token in **Token API** quando non ti serve più.

### Scegliere l'organizzazione

La maggior parte dei comandi lavora in un'organizzazione. Dopo `deploy login` è l'organizzazione che usavi prima, altrimenti la prima delle tue. Elencale con `deploy orgs` (quella in uso ha un `*`) e cambia con `deploy use`:

```text
$ deploy orgs
SLUG         NAME       ROLE
* acme       Acme       owner
  acme-labs  Acme Labs  developer

$ deploy use acme-labs
✓ Using acme-labs.
```

Aggiungi `--org=<slug>` a un comando per usare un'altra organizzazione solo per quel comando.

## Usare la CLI in CI con le variabili d'ambiente

In una pipeline non esegui `deploy login`. Imposta invece queste variabili d'ambiente; hanno la precedenza sul file di configurazione:

| Variabile | Valore |
|---|---|
| `DEPLOY_TOKEN` | Il token API. Salvalo come secret nella tua CI. |
| `DEPLOY_URL` | L'indirizzo di Vimonto Deploy, ad esempio `https://deploy.example.com`. |
| `DEPLOY_ORG` | Lo slug dell'organizzazione, come nei tuoi URL e in `deploy orgs`. |

I colori vengono omessi quando l'output non è un terminale e quando `NO_COLOR` è impostata.

### GitHub Actions

Aggiungi `DEPLOY_TOKEN` in **Settings** → **Secrets and variables** → **Actions** del tuo repository. Questo workflow fa il deploy dopo che i test sono passati, e fallisce se il deploy fallisce:

```yaml
# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    # needs: tests   # esegui prima il tuo job di test
    steps:
      - uses: actions/checkout@v4

      - name: Deploy shop.example.com
        run: php bin/deploy deploy shop.example.com --watch
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
          DEPLOY_URL: https://deploy.example.com
          DEPLOY_ORG: acme
```

I runner Ubuntu ospitati da GitHub includono PHP e l'estensione curl, quindi non c'è niente da configurare.

### GitLab CI

Aggiungi `DEPLOY_TOKEN` come variabile mascherata in **Settings** → **CI/CD** → **Variables** del tuo progetto:

```yaml
# .gitlab-ci.yml
deploy:
  stage: deploy
  image: php:8.3-cli
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  variables:
    DEPLOY_URL: https://deploy.example.com
    DEPLOY_ORG: acme
  script:
    - php bin/deploy deploy shop.example.com --watch
```

Con `--watch` il job aspetta il deploy e ne riceve il risultato come codice di uscita, così un deploy fallito rende rossa la pipeline. Senza `--watch` il job termina appena il deploy è partito.

> [!TIP]
> Vuoi solo avviare un deploy dalla CI, senza PHP né token? Ogni sito ha anche un URL di deploy segreto che chiami con `curl`. Vedi [deployment](https://ops.vimonto.com/docs/it/sites/deployments).

## Fare il deploy di un sito

`deploy deploy` fa il deploy del branch del sito, come **Fai il deploy** nell'app. Indica il sito con il suo dominio o il suo id:

```text
$ deploy deploy shop.example.com --watch
✓ Deploying shop.example.com (main) on web-1.
==> Fetch code
Cloning git@github.com:acme/shop.git (main)
HEAD is now at 3f9c2ab
==> Run deploy script
Installing dependencies from lock file
   INFO  Running migrations.
==> Go live
Linked current → releases/20261007101500
==> Clean up old releases
Kept the last 5 releases.
✓ Deploying to shop.example.com succeeded.
```

La CLI trova il sito per dominio o id con una sola richiesta. Se due server hanno un sito con lo stesso dominio, aggiungi `--server <nome>` per cercare su un solo server. Un deploy avviato dalla CLI compare nell'elenco dei deploy del sito come tutti gli altri; come funzionano i deploy lo trovi in [deployment](https://ops.vimonto.com/docs/it/sites/deployments).

Senza `--watch`, il comando avvia il deploy e mostra il comando per seguirlo:

```text
$ deploy deploy shop.example.com
✓ Deploying shop.example.com (main) on web-1.
Follow it with: deploy task 4821 --watch
```

Se un deploy del sito è già in corso, la CLI lo dice e mostra l'id di quel task, così puoi seguirlo.

### Seguire un task con --watch

Deploy, nuovi database, ricette e backup vengono eseguiti come task in background. `deploy task <id>` mostra lo stato di un task e il suo output finora; con `--watch` controlla il task ogni due secondi, mostra il nuovo output appena arriva e termina con il risultato:

```text
$ deploy task 4821 --watch
```

`--watch` funziona con `deploy`, `task`, `database:create`, `recipe:run` e `backup:run`.

## Tutti i comandi

Esegui `deploy help` per la versione breve.

| Comando | Cosa fa |
|---|---|
| `deploy login [--url=… --token=…]` | Controlla un token e lo salva con l'URL. |
| `deploy orgs` | Elenca le tue organizzazioni; `*` indica quella in uso. |
| `deploy use <org>` | Da ora lavora in un'altra organizzazione. |
| `deploy servers` | Elenca i server: id, nome, tipo, stato, indirizzo IP e versione PHP. |
| `deploy sites [server]` | Elenca i siti di un server o di tutti i server: id, dominio, server, framework, stato, branch e ultimo deploy. |
| `deploy deploy <site> [--watch]` | Fa il deploy di un sito (dominio o id). |
| `deploy deployments <site>` | Gli ultimi 25 deploy: stato, come è stato avviato, commit e quando. |
| `deploy task <id> [--watch]` | Lo stato e l'output di un task. |
| `deploy databases <server>` | Elenca i database di un server. |
| `deploy database:create <server> <name> [--watch]` | Crea un database su un server. |
| `deploy recipes` | Elenca le ricette dell'organizzazione. |
| `deploy recipe:run <recipe> <server>… [--watch] [--notify]` | Esegue una ricetta su uno o più server. |
| `deploy backups <server>` | Elenca i backup di un server con la pianificazione e l'ultima esecuzione. |
| `deploy backup:run <server> <backup> [--watch]` | Esegue subito un backup. |
| `deploy version` | Mostra la versione della CLI; `deploy --version` fa lo stesso. |
| `deploy help` | Mostra l'elenco dei comandi. |

I server si indicano con il nome o l'id, i siti con il dominio o l'id, ricette e backup con il nome o l'id. Maiuscole e minuscole non contano. Metti tra virgolette un nome con spazi.

### Opzioni

| Opzione | Significato |
|---|---|
| `--watch` | Aspetta il task e termina con il suo risultato. |
| `--org=<slug>` | Usa questa organizzazione solo per questo comando. |
| `--server=<name>` | Cerca il sito solo su questo server (`deploy`, `deployments`). |
| `--url=<url>` | Usa questo indirizzo di Vimonto Deploy solo per questo comando. |
| `--notify` | `recipe:run`: ti invia un report via email quando ogni server ha finito. |
| `--version` | Mostra la versione della CLI, con qualsiasi comando. |
| `--help`, `-h` | Mostra l'elenco dei comandi. |

Le opzioni prendono il valore dopo uno spazio o un `=`: `--org acme` e `--org=acme` sono la stessa cosa.

### Elencare server e siti

```text
$ deploy servers
ID  NAME   TYPE      STATUS  IP            PHP
12  web-1  app       active  203.0.113.10  8.4
14  db-1   database  active  203.0.113.11

$ deploy sites web-1
ID  DOMAIN            SERVER  FRAMEWORK  STATUS     BRANCH  DEPLOYED
31  shop.example.com  web-1   laravel    installed  main    2 h ago
```

### Database, ricette e backup

```bash
deploy databases web-1
deploy database:create web-1 shop_reports --watch

deploy recipes
deploy recipe:run "Clear caches" web-1 web-2 --watch --notify

deploy backups db-1
deploy backup:run db-1 "Nightly" --watch
```

Il nome di un database può contenere lettere, cifre e underscore, fino a 63 caratteri, e il server deve essere pronto e avere un database installato. `recipe:run` avvia un task per server; con `--watch` li segue uno dopo l'altro e fallisce se uno di essi è fallito. Maggiori dettagli in [ricette](https://ops.vimonto.com/docs/it/more/recipes).

## Codici di uscita ed errori

| Codice di uscita | Quando |
|---|---|
| `0` | Il comando ha funzionato. Con `--watch`: il task è riuscito. |
| `1` | Qualsiasi errore, oppure con `--watch` un task fallito o annullato. |

Anche `deploy task <id>` senza `--watch` termina con `1` quando il task è fallito o è stato annullato, e con `0` finché è ancora in coda o in esecuzione.

Gli errori vengono scritti sullo standard error, dopo una `✗`:

| Messaggio | Cosa fare |
|---|---|
| `Not logged in. Run "deploy login", or set DEPLOY_TOKEN.` | Accedi, oppure imposta `DEPLOY_TOKEN` e `DEPLOY_URL` in CI. |
| `No organization chosen. Run "deploy use <org>".` | Scegline una con `deploy use`, `--org=` o `DEPLOY_ORG`. |
| `The token was not accepted. It may be revoked or expired: run "deploy login" again.` | Crea un nuovo token e accedi di nuovo. |
| `This token or your role does not allow that.` | Al token manca un ambito (vedi la tabella sopra), oppure il tuo ruolo non permette l'azione. |
| `Not found. Check the name, and that you have access to it.` | L'organizzazione, il server o il sito non esiste, oppure non hai accesso. |
| `No site "…".` / `No server "…".` | Controlla il dominio o il nome, e che stai usando l'organizzazione giusta. |
| `Too many requests. Wait a minute and try again.` | Un token può fare 120 richieste al minuto. |

I messaggi di Vimonto Deploy stesso, come un sito che non ha ancora un repository o un deploy già in corso, vengono mostrati così come sono.

## Domande frequenti

### La CLI ha bisogno dell'accesso SSH ai miei server?

No. La CLI parla solo con l'API di Vimonto Deploy, via HTTPS. Poi è Vimonto Deploy a fare il lavoro sul server, come quando clicchi un pulsante nell'app.

### Dove viene salvato il mio token?

Sul tuo computer, in `~/.config/deploy/config.json` con permessi `0600`. In CI il token arriva dalla variabile `DEPLOY_TOKEN` e non viene scritto nulla su disco.

### Perché il mio token CI riceve "This token or your role does not allow that"?

`deploy`, `deployments` e `task` funzionano con un token con il solo **Deploy**. Gli altri comandi, come `servers` o `sites`, richiedono **Lettura** o **Scrittura** (vedi la tabella sopra). Controlla anche che il tuo ruolo nell'organizzazione possa fare il deploy e di usare la versione 1.1.0 o successiva della CLI (`deploy --version`): le versioni precedenti cercavano il sito tramite l'elenco dei server, che richiede **Lettura**.

### Posso usare la CLI per più organizzazioni?

Sì. Un token funziona in ogni organizzazione di cui sei membro. Cambia con `deploy use <org>`, oppure aggiungi `--org=<slug>` a un singolo comando.

### Esiste un'API per ciò che la CLI non fa?

La CLI copre le operazioni più comuni. L'[API](https://ops.vimonto.com/docs/it/more/api) ha gli stessi endpoint che usa la CLI, quindi puoi chiamarla anche direttamente dai tuoi script.
