# Deployen vanaf de command line met de Vimonto Deploy CLI

> Installeer de Vimonto Deploy CLI, log in met een API-token en deploy sites, volg taken en draai recepten en back-ups vanuit je terminal of een CI-pipeline.

De Vimonto Deploy CLI is een kleine command-line tool met de naam `deploy`. Daarmee deploy je een site, volg je de output en de exitcode, bekijk je je servers en sites en draai je recepten en back-ups, vanuit je eigen terminal of vanuit een CI-pipeline zoals GitHub Actions of GitLab CI.

De CLI is een dunne client van de [Vimonto Deploy API](https://ops.vimonto.com/docs/nl/more/api): elk commando is één of meer API-verzoeken, ondertekend met een persoonlijk API-token. Hij kan precies wat het token en je rol in de organisatie toestaan, niets meer.

## Wat heb je nodig?

- **PHP 8.2 of nieuwer met de curl-extensie.** De CLI is één PHP-bestand zonder afhankelijkheden, dus er is geen Composer-installatie. Controleer het met `php -v` en `php -m | grep curl`.
- **Een API-token**, gemaakt onder **Accountinstellingen** → **API-tokens** (zie [je account](https://ops.vimonto.com/docs/nl/more/account)). Het token wordt één keer getoond, wanneer je het maakt.
- macOS, Linux of WSL. De CLI draait op Windows ook met `php deploy …`, maar verbergt het token tijdens het typen alleen op macOS en Linux.

## De CLI installeren

De CLI is het ene bestand `deploy`. Download het van je Vimonto Deploy-adres op `/cli/deploy` (de link staat ook onder **Accountinstellingen** → **API-tokens**, met het commando om te kopiëren), maak het uitvoerbaar en zet het in een map op je `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` (of `deploy version`) toont de versie, zoals `deploy 1.1.0`. Zonder het bestand te verplaatsen kun je het ook direct draaien als `./deploy` of `php deploy`.

Commit het bestand in een CI-pipeline in je repository (bijvoorbeeld als `bin/deploy`), of download het in de job met hetzelfde `curl`-commando, en draai het met `php bin/deploy`. De CLI heeft geen andere bestanden en hoeft niet geïnstalleerd te worden. Bijwerken doe je door hem opnieuw te downloaden.

## Een API-token maken

1. Open **Accountinstellingen** → **API-tokens** en klik op **Nieuw token**.
2. Geef het een **Naam** die zegt waar het gebruikt wordt, zoals `GitHub Actions` of `Mijn laptop`.
3. Kies de **Scopes**: **Lezen**, **Deploy** en/of **Schrijven** (zie de tabel hieronder).
4. Kies wanneer het **Verloopt**: over 30, 90 of 365 dagen, of **Nooit**.
5. Klik op **Token maken** en kopieer het token uit **Je nieuwe token**. Het wordt maar één keer getoond; alleen de hash wordt opgeslagen.

![De pagina API-tokens in de accountinstellingen](https://ops.vimonto.com/docs-media/nl/account-api-tokens.webp?v=161e760d "API-tokens")

### Welke scopes heeft een commando nodig?

Lijsten tonen vraagt **Lezen** (of **Schrijven**). Een token met alleen **Deploy** kan toch een site deployen en volgen: de CLI zoekt de site op met zijn domein of id, en dat mag met die scope. Ander werk vraagt **Schrijven**.

| Commando's | Scopes die het token nodig heeft |
|---|---|
| `login`, `orgs`, `use` | Elke scope |
| `servers`, `sites`, `databases`, `recipes`, `backups` | **Lezen** of **Schrijven** |
| `deployments`, `task` | **Lezen**, **Deploy** of **Schrijven** |
| `deploy` | **Deploy** of **Schrijven** |
| `database:create`, `recipe:run`, `backup:run` | **Schrijven** |

Bovenop de scopes geldt je rol in de organisatie: een token kan nooit meer dan jij. Een kijker kan niet deployen, ook niet met een token met **Schrijven**, en servers waar je geen toegang toe hebt worden niet getoond. Maak voor een CI-pipeline die alleen deployt een token met alleen **Deploy**.

## Inloggen met deploy login

Draai `deploy login` en beantwoord de twee vragen: het adres van Vimonto Deploy (de URL die je in je browser opent) en het API-token. Het token wordt niet getoond terwijl je het typt of plakt.

```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>")
```

Je kunt ook allebei meteen meegeven: `deploy login --url=https://deploy.example.com --token=…`. Houd er rekening mee dat een token op de command line in je shellgeschiedenis terechtkomt.

De CLI controleert het token en slaat daarna de URL, het token en de organisatie (die je met `--org <slug>` noemt, anders die van eerder, anders je eerste; `DEPLOY_ORG` wordt nooit opgeslagen) op in `~/.config/deploy/config.json` (of `$XDG_CONFIG_HOME/deploy/config.json` als die variabele is ingesteld). De map wordt gemaakt met modus `0700` en het bestand met `0600`, zodat alleen jij het kunt lezen. Verwijder dat bestand om uit te loggen, en trek het token in onder **API-tokens** als je het niet meer nodig hebt.

### De organisatie kiezen

De meeste commando's werken in één organisatie. Na `deploy login` is dat de organisatie die je eerder gebruikte, en anders je eerste. Bekijk de jouwe met `deploy orgs` (die in gebruik heeft een `*`) en wissel met `deploy use`:

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

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

Zet `--org=<slug>` achter een commando om voor alleen dat commando een andere organisatie te gebruiken.

## De CLI in CI gebruiken met omgevingsvariabelen

In een pipeline draai je geen `deploy login`. Stel in plaats daarvan deze omgevingsvariabelen in; ze gaan voor het configuratiebestand:

| Variabele | Waarde |
|---|---|
| `DEPLOY_TOKEN` | Het API-token. Bewaar het als secret in je CI. |
| `DEPLOY_URL` | Het adres van Vimonto Deploy, zoals `https://deploy.example.com`. |
| `DEPLOY_ORG` | De slug van de organisatie, zoals in je URL's en in `deploy orgs`. |

Kleuren worden weggelaten als de output geen terminal is, en als `NO_COLOR` is ingesteld.

### GitHub Actions

Voeg `DEPLOY_TOKEN` toe onder **Settings** → **Secrets and variables** → **Actions** van je repository. Deze workflow deployt nadat de tests geslaagd zijn, en faalt als de deploy faalt:

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

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    # needs: tests   # draai eerst je testjob
    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
```

De Ubuntu-runners van GitHub hebben PHP en de curl-extensie al, dus je hoeft niets in te stellen.

### GitLab CI

Voeg `DEPLOY_TOKEN` toe als gemaskeerde variabele onder **Settings** → **CI/CD** → **Variables** van je project:

```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
```

Met `--watch` wacht de job op de deploy en krijgt hij het resultaat als exitcode, zodat een mislukte deploy de pipeline rood maakt. Zonder `--watch` eindigt de job zodra de deploy gestart is.

> [!TIP]
> Wil je vanuit CI alleen een deploy starten, zonder PHP of token? Elke site heeft ook een geheime deploy-URL die je met `curl` aanroept. Zie [deployments](https://ops.vimonto.com/docs/nl/sites/deployments).

## Een site deployen

`deploy deploy` deployt de branch van de site, net als **Deployen** in de app. Noem de site bij zijn domein of zijn 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.
```

De CLI vindt de site met één request op zijn domein of id. Hebben twee servers een site met hetzelfde domein, voeg dan `--server <naam>` toe om op één server te zoeken. Een deploy die vanuit de CLI is gestart, staat net als elke andere in de deploylijst van de site; hoe deploys werken lees je in [deployments](https://ops.vimonto.com/docs/nl/sites/deployments).

Zonder `--watch` start het commando de deploy en toont het het commando om hem te volgen:

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

Loopt er al een deploy van de site, dan meldt de CLI dat en geeft hij het id van die taak, zodat je die kunt volgen.

### Een taak volgen met --watch

Deploys, nieuwe databases, recepten en back-ups draaien als taken op de achtergrond. `deploy task <id>` toont de status van een taak en de output tot nu toe; met `--watch` controleert hij de taak elke twee seconden, toont hij nieuwe output zodra die er is en eindigt hij met het resultaat:

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

`--watch` werkt bij `deploy`, `task`, `database:create`, `recipe:run` en `backup:run`.

## Alle commando's

Draai `deploy help` voor de korte versie.

| Commando | Wat het doet |
|---|---|
| `deploy login [--url=… --token=…]` | Een token controleren en met de URL opslaan. |
| `deploy orgs` | Je organisaties tonen; `*` markeert die in gebruik. |
| `deploy use <org>` | Vanaf nu in een andere organisatie werken. |
| `deploy servers` | Servers tonen: id, naam, type, status, IP-adres en PHP-versie. |
| `deploy sites [server]` | De sites van één server of van alle servers tonen: id, domein, server, framework, status, branch en laatste deploy. |
| `deploy deploy <site> [--watch]` | Een site deployen (domein of id). |
| `deploy deployments <site>` | De 25 laatste deploys: status, hoe hij gestart is, commit en wanneer. |
| `deploy task <id> [--watch]` | De status en output van een taak. |
| `deploy databases <server>` | De databases van een server tonen. |
| `deploy database:create <server> <name> [--watch]` | Een database op een server maken. |
| `deploy recipes` | De recepten van de organisatie tonen. |
| `deploy recipe:run <recipe> <server>… [--watch] [--notify]` | Een recept op één of meer servers draaien. |
| `deploy backups <server>` | De back-ups van een server tonen met hun schema en laatste run. |
| `deploy backup:run <server> <backup> [--watch]` | Nu een back-up maken. |
| `deploy version` | De versie van de CLI tonen; `deploy --version` doet hetzelfde. |
| `deploy help` | De lijst met commando's tonen. |

Servers noem je bij hun naam of id, sites bij hun domein of id, recepten en back-ups bij hun naam of id. Hoofdletters maken niet uit. Zet een naam met spaties tussen aanhalingstekens.

### Opties

| Optie | Betekenis |
|---|---|
| `--watch` | Op de taak wachten en eindigen met het resultaat. |
| `--org=<slug>` | Deze organisatie alleen voor dit commando gebruiken. |
| `--server=<name>` | De site alleen op deze server zoeken (`deploy`, `deployments`). |
| `--url=<url>` | Dit adres van Vimonto Deploy alleen voor dit commando gebruiken. |
| `--notify` | `recipe:run`: je een rapport mailen als elke server klaar is. |
| `--version` | De versie van de CLI tonen, bij elk commando. |
| `--help`, `-h` | De lijst met commando's tonen. |

Opties krijgen hun waarde na een spatie of een `=`: `--org acme` en `--org=acme` zijn hetzelfde.

### Servers en sites tonen

```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
```

### Databases, recepten en back-ups

```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
```

Een databasenaam mag letters, cijfers en underscores bevatten, tot 63 tekens, en de server moet klaar zijn en een database geïnstalleerd hebben. `recipe:run` start één taak per server; met `--watch` volgt hij ze na elkaar en faalt hij als een ervan mislukt is. Meer over recepten lees je in [recepten](https://ops.vimonto.com/docs/nl/more/recipes).

## Exitcodes en foutmeldingen

| Exitcode | Wanneer |
|---|---|
| `0` | Het commando is gelukt. Met `--watch`: de taak is geslaagd. |
| `1` | Elke fout, of met `--watch` een taak die mislukt of geannuleerd is. |

`deploy task <id>` zonder `--watch` eindigt ook met `1` als de taak mislukt of geannuleerd is, en met `0` zolang hij nog in de wachtrij staat of loopt.

Fouten komen op standard error, na een `✗`:

| Melding | Wat je doet |
|---|---|
| `Not logged in. Run "deploy login", or set DEPLOY_TOKEN.` | Log in, of stel in CI `DEPLOY_TOKEN` en `DEPLOY_URL` in. |
| `No organization chosen. Run "deploy use <org>".` | Kies er een met `deploy use`, `--org=` of `DEPLOY_ORG`. |
| `The token was not accepted. It may be revoked or expired: run "deploy login" again.` | Maak een nieuw token en log opnieuw in. |
| `This token or your role does not allow that.` | Het token mist een scope (zie de tabel hierboven), of je rol staat de actie niet toe. |
| `Not found. Check the name, and that you have access to it.` | De organisatie, server of site bestaat niet, of je hebt er geen toegang toe. |
| `No site "…".` / `No server "…".` | Controleer het domein of de naam, en of je de juiste organisatie gebruikt. |
| `Too many requests. Wait a minute and try again.` | Een token mag 120 verzoeken per minuut doen. |

Meldingen van Vimonto Deploy zelf, zoals een site die nog geen repository heeft of een deploy die al loopt, worden getoond zoals ze zijn.

## Veelgestelde vragen

### Heeft de CLI SSH-toegang tot mijn servers nodig?

Nee. De CLI praat alleen via HTTPS met de API van Vimonto Deploy. Vimonto Deploy doet daarna het werk op de server, net als wanneer je in de app op een knop klikt.

### Waar wordt mijn token bewaard?

Op je eigen computer, in `~/.config/deploy/config.json` met rechten `0600`. In CI komt het token uit de variabele `DEPLOY_TOKEN` en wordt er niets naar schijf geschreven.

### Waarom krijgt mijn CI-token "This token or your role does not allow that"?

`deploy`, `deployments` en `task` werken met een token met alleen **Deploy**. Andere commando's, zoals `servers` of `sites`, vragen **Lezen** of **Schrijven** (zie de tabel hierboven). Controleer ook of je rol in de organisatie mag deployen, en of je versie 1.1.0 of nieuwer van de CLI gebruikt (`deploy --version`): oudere versies zochten de site op via de serverlijst, en daarvoor is **Lezen** nodig.

### Kan ik de CLI voor meer dan één organisatie gebruiken?

Ja. Eén token werkt in elke organisatie waar je lid van bent. Wissel met `deploy use <org>`, of zet `--org=<slug>` achter één commando.

### Is er een API voor wat de CLI niet kan?

De CLI dekt de meest gebruikte taken. De [API](https://ops.vimonto.com/docs/nl/more/api) heeft dezelfde endpoints die de CLI gebruikt, dus je kunt hem ook direct aanroepen vanuit je eigen scripts.
