Zum Inhalt springen
Containly

API-Tokens und CI-Redeploy

Seit Containly 2.7.3 rollen GitHub Actions, Gitea oder Forgejo Actions und andere Pipelines einen Stack mit einem curl-Aufruf neu aus, und Prometheus liest die Metriken, beides mit persönlichen API-Tokens. Free. Berechtigungen, Sicherheit, Job-Status und fertige Beispiele.

Containly 2.7.3 bringt persönliche API-Tokens und eine Redeploy-API für CI-Pipelines. Beides ist Free.

Token erstellen

  1. Öffne Profil > API-Tokens und klicke auf Neues Token.
  2. Gib einen Namen ein, zum Beispiel github-actions shop. Im Audit-Log erscheint jede Aktion des Tokens als <dein Name> (Token: <Name>).
  3. Wähle nur die Berechtigungen, die die Pipeline braucht:
    - API lesen: Listen von Hosts, Containern, Stacks, Images, Updates und Backups (nur lesen).
    - Stacks neu ausrollen: git pull bei Git-Stacks, Images ziehen und docker compose up -d für einen Stack. Solche Tokens können nur Admins erstellen. Optional beschränkst du das Token auf die Stacks, die diese Pipeline ausrollt.
    - Prometheus-Metriken: /metrics lesen (siehe Anleitung Prometheus).
  4. Wähle den Ablauf (30 Tage, 90 Tage, 1 Jahr oder ohne Ablauf) und klicke auf Token erstellen.
  5. Kopiere das Token sofort. Es wird nur einmal angezeigt; Containly speichert nur einen Fingerabdruck davon. Lege es als Secret in deiner CI ab (zum Beispiel DEPLOY_TOKEN).

Die Liste zeigt, wann und von welcher IP jedes Token zuletzt verwendet wurde. Widerrufen stoppt ein Token sofort. Admins sehen und widerrufen die Tokens aller Benutzer unter Einstellungen > Integrationen.

Sicherheit kurz erklärt

  • Ein Token gilt nur im Header Authorization: Bearer <token> und nur auf den API-Routen seiner Berechtigung, nie für die Anmeldung, Konsolen, WebSockets, Benutzer, Einstellungen oder Tokens selbst.
  • Ein Token kann nie mehr als dein Konto: Wirst du zum Betrachter, deaktiviert oder gelöscht, funktioniert dein Redeploy-Token nicht mehr.
  • Anfragen sind pro Token begrenzt (höchstens 10 Redeploys pro Minute).
  • Ein Redeploy startet die Compose-Dateien im Stack-Ordner (bei Git-Stacks die aus dem Repository). Wer in dieses Repository pushen darf, bestimmt also mit, was läuft: schütze den Branch.

Stack neu ausrollen

Per Name (Name des Stack-Ordners; gibt es den Namen auf zwei Hosts, ergänze "endpoint" mit der Host-ID):

curl -fsS -X POST \
  -H "Authorization: Bearer $DEPLOY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"shop"}' \
  https://containly.example.com/api/stacks/redeploy

Oder per Stack-ID (POST /api/stacks/<id>/redeploy, die ID steht in der Adresszeile, wenn der Stack offen ist).

Containly antwortet mit 202 und einem Job:

{"job":{"id":"job_MhIaXDMjzVWb","status":"queued","stackName":"shop", "...": "..."},"statusUrl":"/api/jobs/job_MhIaXDMjzVWb"}

Was der Job macht: bei einem Git-Stack git pull, danach docker compose pull und docker compose up -d --remove-orphans mit allen Compose-Dateien des Stacks (auch Override-Dateien). Frage GET /api/jobs/<id> ab, bis status auf ok oder error steht; output enthält das Ende der Compose-Ausgabe, error den Grund. Eine zweite Anfrage, während derselbe Stack gerade ausgerollt wird, liefert den laufenden Job zurück.

GitHub Actions

Lege das Token als Repository-Secret DEPLOY_TOKEN und die Adresse als Variable DEPLOY_URL an. Containly muss vom GitHub-Runner aus erreichbar sein (oder du nutzt einen eigenen Runner in deinem Netz).

name: deploy
on:
  push:
    branches: [main]
jobs:
  redeploy:
    runs-on: ubuntu-latest
    steps:
      - name: Stack in Containly neu ausrollen
        env:
          TOKEN: ${{ secrets.DEPLOY_TOKEN }}
          URL: ${{ vars.DEPLOY_URL }}
        run: |
          job=$(curl -fsS -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
                -d '{"name":"shop"}' "$URL/api/stacks/redeploy" | jq -r .job.id)
          for i in $(seq 1 60); do
            st=$(curl -fsS -H "Authorization: Bearer $TOKEN" "$URL/api/jobs/$job" | jq -r .job.status)
            echo "status: $st"
            [ "$st" = ok ] && exit 0
            [ "$st" = error ] && { curl -fsS -H "Authorization: Bearer $TOKEN" "$URL/api/jobs/$job" | jq -r .job.error; exit 1; }
            sleep 5
          done
          exit 1

Gitea und Forgejo Actions

Derselbe Workflow läuft in Gitea und Forgejo Actions (Datei .gitea/workflows/deploy.yaml oder .forgejo/workflows/deploy.yaml). Lege DEPLOY_TOKEN im Repository unter Einstellungen > Actions > Secrets ab und DEPLOY_URL unter Variablen. Mit einem Runner im eigenen Netz kann DEPLOY_URL die LAN-Adresse sein, zum Beispiel http://10.0.0.5:8420.

Daten lesen

Ein Token mit API lesen ruft mit demselben Header zum Beispiel GET /api/stacks, GET /api/containers, GET /api/updates oder GET /api/hosts/metrics auf. GET /api/auth/me zeigt, zu welchem Benutzer ein Token gehört.

Mögliche Antworten

StatusBedeutung
202Redeploy gestartet (oder läuft schon), siehe statusUrl
401Token fehlt, ist falsch, abgelaufen oder widerrufen, oder der Besitzer ist deaktiviert
403 token_scopeDem Token fehlt die Berechtigung für diese Route, oder Tokens sind dort nicht erlaubt
403Die Rolle des Besitzers erlaubt es nicht (zum Beispiel Betrachter) oder das Token ist auf andere Stacks beschränkt
404Kein Stack mit diesem Namen oder dieser ID
409Mehrere Stacks mit diesem Namen: ergänze "endpoint", oder ein Backup oder eine Wiederherstellung hält den Stack
429Zu viele Anfragen, warte eine Minute