- TypeScript 98.5%
- Shell 1.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo | ||
| .githooks | ||
| docs | ||
| scripts | ||
| src | ||
| tests | ||
| .gitignore | ||
| CLAUDE.md | ||
| deno.json | ||
| deno.lock | ||
| install.sh | ||
| main.ts | ||
| README.md | ||
apcmd
Betrieb von Aivopod auf dem Server:
Installation, Start und Stopp, Aktualisierung mit Rückkehr bei Fehlern, Sicherungen, Diagnose. Eine
einzelne ausführbare Datei (deno compile) für Linux x86_64 und aarch64; auf dem Server brauchen
Sie nur Docker mit Compose v2, kein Node und kein Deno.
Installation
curl -fsSL https://git.belowtoxic.cloud/api/packages/aivopod/generic/apcmd/latest/install.sh | sh
Das Skript lädt die passende Datei, prüft ihre Prüfsumme (auch gegen release-trust.json) und legt
sie unter /usr/local/bin/apcmd ab. APCMD_VERSION wählt eine Version.
Erste Installation von Aivopod
sudo apcmd install --app-host app.schule.example.org --preview-host p.aivopod-preview.example \
--tls admin@schule.example.org
sudo apcmd school create --name "BRG Beispiel"
install lädt das neueste Deploy-Bundle (oder --version, --bundle <zip>), prüft es, legt
/opt/aivopod mit .env und erzeugten Geheimnissen an, zieht die Images per Digest, startet den
Stack und prüft seine Gesundheit. Fehlende Angaben fragt es im Terminal ab (run. und assets.
werden aus dem App-Hostnamen vorgeschlagen). Ohne --backup-recipient erzeugt es ein Schlüsselpaar
für die Sicherungen; den privaten Schlüssel (backup-identity.key) sofort vom Server wegkopieren.
Jede Installation ist eine Instanz mit eigenem Namen (--name, sonst gefragt; Vorschlag
aivopod, auf einem Rechner mit einer solchen Instanz aivopod-2). Der Name ist
COMPOSE_PROJECT_NAME in .env und Präfix von Containern, Netz und Volumes; das Verzeichnis ist
/opt/<name> (oder --dir). Einen Namen, den es auf dem Rechner schon gibt, lehnt install ab.
apcmd list zeigt alle Instanzen. Welche ein Befehl nimmt: --dir, sonst --instance <name>,
sonst AIVOPOD_HOME, sonst die mit apcmd use <name> gewählte, sonst die einzige. Mit mehreren und
keiner gewählten bricht ein Befehl ab und nennt die Namen (D017).
Neben anderen Diensten: Hält auf dem Rechner schon ein Server 80 und 443 (nginx, Apache, Caddy
…), installiert install --proxy hinter-proxy unseren Caddy auf 127.0.0.1:8080 (oder den nächsten
freien Port) ohne TLS; der vorhandene Server macht TLS und leitet weiter. Unser Caddy setzt in
beiden Modi die Sicherheits-Header. Vorlagen für nginx, Apache und Caddy liegen danach in proxy/
(apcmd proxy-config erzeugt sie neu); apcmd configure --proxy eigenstaendig|hinter-proxy
wechselt den Modus einer bestehenden Instanz. Belegte Ports erkennt install und schlägt freie vor.
Anmeldung der Lehrpersonen (OIDC)
Lehrpersonen melden sich über den Anmeldedienst der Schule an (Keycloak, Entra ID, …). install
zeigt die beiden URIs, die dort für einen neuen Client einzutragen sind, und fragt dann:
- Issuer-URL des Anmeldedienstes, genau so, wie er sich selbst nennt (bei Keycloak
https://<host>/realms/<realm>).installliest sein Discovery-Dokument und lehnt eine Adresse ab, unter der sich der Dienst anders nennt. Leer lassen: später mitapcmd oidc set. - Client-ID, und das Client-Secret. Ohne Secret ist Aivopod ein öffentlicher Client (nur PKCE); das muss der Anmeldedienst erlauben.
Die Scopes sind openid profile email. Ohne Terminal gelten --oidc-issuer, --oidc-client-id,
--oidc-client-secret. apcmd oidc show zeigt die Werte (nie das Secret) und die URIs,
apcmd oidc set ändert sie, prüft den Anmeldedienst und startet die API neu; apcmd doctor prüft
die Anmeldung mit.
Schulen und Lehrpersonen
school create legt die Schule an (gibt es sie mit dem Namen schon, bleibt sie unverändert) und
fragt, ob gleich eine Lehrperson dazukommen soll. Dafür erzeugt es einen einmaligen Anmeldelink
(https://<App-Host>/claim#…), standardmäßig 72 Stunden gültig (--valid-hours, höchstens 720).
Wer ihn zuerst öffnet und sich beim Anmeldedienst anmeldet, gehört danach als Eigentümer:in zur
Schule. Niemand muss Issuer oder sub der Lehrperson kennen; der Name kommt aus --teacher-name
oder vom Anmeldedienst. Wer sich über den Link anmeldet, wird manager (Leitung) der Schule;
--role wählt eine andere Rolle, --admin macht zugleich zur Admin der ganzen Instanz. Weitere
Lehrpersonen: apcmd teacher add, oder die Leitung selbst mit aivopod teacher add.
apcmd school list zeigt Schulen, Lehrpersonen mit ihren IDs und offene Links. Hat eine Lehrperson
ein neues Konto (oder hat sich der Issuer geändert), erzeugt apcmd teacher link <id> einen Link,
mit dem sie ihr neues Konto verknüpft; Kurse und Verlauf bleiben erhalten, das alte Konto gilt
danach nicht mehr.
Den Link wie ein Passwort behandeln: persönlich oder über einen vertraulichen Kanal weitergeben.
apcmd.log enthält ihn nicht. Für Skripte bindet
school create --issuer … --sub … --teacher-name … eine bekannte Anmeldung direkt, ohne Link.
Befehle
| Befehl | Wirkung |
|---|---|
apcmd install [--name] [--version] |
Bundle laden und prüfen, .env mit Geheimnissen, Name der Instanz, Hostnamen, Images per Digest, Datenbank und Rollen, Start |
apcmd list |
Alle Instanzen auf diesem Rechner mit Verzeichnis, Version und Zustand |
apcmd use [<name>] |
Instanz für die folgenden Befehle wählen; ohne Namen die gewählte zeigen |
apcmd configure --proxy <modus> |
Webserver-Modus wechseln (eigenstaendig oder hinter-proxy), Ports prüfen, Stack neu starten |
apcmd proxy-config |
Vorlagen für den vorgeschalteten Server in proxy/ neu erzeugen (nginx, Apache, Caddy) |
apcmd up / down / restart [dienst] |
Stack steuern (down behält alle Daten) |
apcmd status |
Dienste, Version, Gesundheit, nicht veröffentlichte Uploads, freier Speicher, letzte Sicherung |
apcmd logs [dienst] [--follow] |
Logs |
apcmd update [--version] |
Sicherung, neues Bundle prüfen, MIGRATION_NOTES.md zeigen, .env ergänzen, Images ziehen, Start (Migrationen), Gesundheitsprüfung; bei Fehler zurück zur vorherigen Version |
apcmd rollback [--restore-db --identity <key>] |
Vorherige Version; die Datenbank nur mit --restore-db aus der Sicherung von vor dem Update |
apcmd backup now / list / restore <datei> --identity <key> |
Sicherungen |
apcmd snapshot create / list / restore <datei> --identity <key> [--replace] |
Abbild der laufenden Instanz für den Katastrophenfall: Verzeichnis mit .env, Datenbank-Abzug, Volumes, verschlüsselt in einer Datei; auf einem neuen Rechner wiederherstellen |
apcmd oidc show / set |
Anmeldung der Lehrpersonen: Werte und URIs zeigen; Werte prüfen, in .env schreiben, API neu starten |
apcmd school create / list |
Schule anlegen (vorhandene bleibt), auf Wunsch mit Anmeldelink; Schulen, Lehrpersonen und offene Links zeigen |
apcmd school delete --school <name|id> [--yes] |
Schule mit allen Daten löschen; zeigt zuerst, was verschwindet, und fragt nach dem Namen (ab Plattform 0.11) |
apcmd teacher add / link <id> |
Einmaliger Anmeldelink für eine neue Lehrperson; Link zum Verknüpfen einer Lehrperson mit einem neuen Konto |
apcmd teacher promote / demote <id> --admin |
Admin der ganzen Instanz machen oder wieder entziehen (Rollen in den Schulen bleiben) |
apcmd doctor |
DNS und TLS aller vier Hostnamen, Ports, Anmeldedienst (OIDC), Docker, Uhrzeit, Schreibrechte, .env |
apcmd self-update |
apcmd selbst aktualisieren |
apcmd version |
Versionen von apcmd, Bundle und Images |
Hilfe zu jedem Befehl und Unterbefehl mit allen Optionen und Beispielen: apcmd <befehl> --help, z.
B. apcmd school create --help oder apcmd backup --help.
Längere Befehle (install, update, rollback, backup restore) zeigen ihre Schritte nummeriert
([3/6] …) und darunter den Fortschritt von Docker. Fragen enden mit einem Doppelpunkt; ein
Vorschlag steht in eckigen Klammern und wird mit Enter übernommen. Ja/Nein-Fragen zeigen (j/N),
der Großbuchstabe ist die Vorgabe.
Alle Befehle: --dir (Standard /opt/aivopod oder AIVOPOD_HOME), --json (ein JSON-Objekt
{ok, command, id, message, messages, data}). Exit-Code 0, 1 bei Fehlern, 2 bei falschem Aufruf.
Prüfung von Releases
Prüfsummen werden immer geprüft: die des Bundles, release.sha256 in release-trust.json und die
Hashes aller Dateien darin. Signaturen gibt es erst mit v1; AIVOPOD_VERIFY_SIGNATURES steuert, was
bis dahin passiert:
| Wert | Wirkung |
|---|---|
off |
keine Meldung |
warn (Standard) |
„Signatur nicht geprüft (erst ab v1 verfügbar)“, Eintrag in apcmd.log |
enforce |
Abbruch mit diesem Hinweis |
Entwicklung
deno task check # fmt, lint, check, test
deno task compile # dist/apcmd
git config core.hooksPath .githooks
Siehe CLAUDE.md und docs/ci.md.