Terminal, SSH & Logs
Früher oder später willst du einen Befehl selbst eintippen: eine Migration starten, ein Paket installieren, in eine Datei schauen. Dafür musst du dich nicht auf dem Server selbst anmelden. Envoryx gibt dir eine Shell in den Containern des Projekts, im Browser oder per SSH.
Browser-Terminal
Abschnitt betitelt „Browser-Terminal“Der Bereich Terminal öffnet eine Shell (xterm.js) in jedem Container des Projekts. In den Anwendungscontainern - PHP, Python, Go, Ruby, Java, .NET, Node.js und den Workern - bist du der Projektbesitzer (PUID/PGID), startest im Projektverzeichnis /var/www/html, und die Umgebungsvariablen des Projekts sind alle da. Genau der richtige Ort für composer, npm, pip, go, bundle, rails, mvn, dotnet und Co.


Lieber im eigenen Terminal? Dieselbe Shell gibt es auch per SSH. Dateien schiebst du über denselben Login hin und her, mit einem SFTP-Client, scp oder rsync, denn jedes Runtime-Image hat rsync:
ssh -p 2222 shop@<envoryx-host> # der Anwendungscontainerssh -p 2222 shop.node@<envoryx-host> # ein bestimmter Runtime-Containerrsync -av -e 'ssh -p 2222' ./uploads/ shop@<envoryx-host>:/var/www/html/public/uploads/Als Passwort nimmst du ein API-Token aus Einstellungen → API-Tokens & MCP, oder du hinterlegst deinen öffentlichen Schlüssel unter Einstellungen → SSH-Schlüssel. Mehr dazu, auch zur Einrichtung der IDEs, steht auf der Seite IDE-Anbindung.
SFTP und scp starten im Projektverzeichnis, also da, wo auch ein ssh-Login landet: scp dump.sql shop@<envoryx-host>: legt die Datei direkt neben deine composer.json. Die einzige Ausnahme sind JetBrains-IDEs. Sie legen ihre Helfer ins Startverzeichnis, deshalb starten sie weiter im Home /home/envoryx, und die Helfer bleiben aus deinem Projekt raus.
Eine statische Seite hat keinen Container, in dem Befehle laufen könnten. Ihr Login gibt dir trotzdem SFTP und damit scp für die Dateien; eine Shell oder rsync endet mit einer Meldung, die erklärt, warum es keine gibt.
Ausgesperrt?
Abschnitt betitelt „Ausgesperrt?“Envoryx zählt fehlgeschlagene Logins, damit niemand endlos Tokens raten kann. Es zählen aber nur echte Rateversuche, also ein falsches oder unbekanntes API-Token. Die Schlüssel, die dein Agent vor dem Passwort anbietet, zählen nicht, und auch nicht das leere Passwort, das OpenSSH schickt, wenn es nicht nachfragen kann. Zehn Fehlversuche von einer Adresse für denselben SSH-Benutzer, also für ein Projekt, sperren diese Adresse für fünf Minuten aus diesem Projekt aus. Eine Kollegin hinter demselben NAT, die an einem anderen Projekt arbeitet, merkt davon nichts. Wer von einer Adresse aus viele Projektnamen durchprobiert, wird trotzdem gestoppt: 30 Fehlversuche über alle Projekte sperren die ganze Adresse. Fehlversuche verfallen zehn Minuten nach dem ersten, ein paar Tippfehler über den Tag summieren sich also nie, und ein erfolgreicher Login setzt den Zähler seines Projekts zurück.
Solange die Sperre läuft, wird jeder Login abgewiesen, auch ein richtiger, sonst würde ein Angreifer merken, wann er getroffen hat. ssh zeigt dann Envoryx: too many failed logins from your address - try again in 5 min. statt eines nackten Permission denied, und du weißt, dass du warten musst und nicht nach einem falschen Schlüssel suchen.
Einen Befehl aus einem Skript ausführen
Abschnitt betitelt „Einen Befehl aus einem Skript ausführen“Für Deploy-Skripte und CI-Jobs gibt es envoryx project exec. Es führt einen Befehl in einem Container aus und reicht seinen Exit-Code an deine Shell zurück - schlägt die Migration fehl, schlägt also auch dein Skript fehl:
envoryx project exec shop -- php artisan migrate --forceenvoryx project exec shop --service node -- npm run buildenvoryx project exec shop -- sh -c "cat > /tmp/x" < datei # stdin wird durchgereicht (bis 512 KiB)stdout und stderr bleiben getrennt, und der Befehl läuft als Projektbesitzer im Projektverzeichnis. Für eine interaktive Shell oder große Datenmengen ist SSH das bessere Werkzeug. Der Rest steht bei der Kommandozeile.
Bist du sowieso auf dem Host und greifst zu docker exec, gib den Benutzer mit. Ohne -u bist du im PHP-Container root, und was du dort anlegst, etwa ein var/cache beim Cache-Leeren, gehört dann root. Der Projektbenutzer kann es später nicht überschreiben, und die Seite wirft Rechtefehler. Nimm die PUID/PGID deiner Installation (1000, wenn du nichts gesetzt hast):
docker exec -it -u 1000:1000 -w /var/www/html envoryx-shop-php shWenn etwas nicht läuft, schaust du meist zuerst in den Bereich Logs. Er hat für jeden Container zwei Ansichten. Live folgt der Ausgabe, während sie entsteht; anhalten, suchen und nach Level filtern geht dort auch. Verlauf ist für den Blick zurück: Zeitraum wählen, nach Text suchen, nach Level filtern, und du bekommst ein Diagramm aus Zeilen, Warnungen und Fehlern über die Zeit (ein Klick auf einen Balken zoomt hinein). Darunter stehen die häufigsten Fehler und Warnungen, so gruppiert, dass dieselbe Meldung mit anderen Zahlen oder IDs nur einmal zählt. Herunterladen speichert jede passende Zeile.


Container melden kein Log-Level, also liest Envoryx es aus dem Text. Fatal error, [error], ERROR:, Exception, Traceback, ein level-Feld in JSON oder logfmt oder ein 5xx-Status im Access-Log gelten als Fehler; Warning, [warn] und Deprecated als Warnung.
Log-Verlauf
Abschnitt betitelt „Log-Verlauf“Docker behält die Ausgabe eines Containers nur so lange, wie es den Container gibt. Wird er neu erstellt, ist die alte Ausgabe weg. Darum kopiert Envoryx die Ausgabe jedes Projektcontainers laufend nach /config/logs/ - so übersteht der Verlauf Neustarts und neu erstellte Container.
Abgeschlossene Tage werden komprimiert. Standardmäßig behält Envoryx 7 Tage und höchstens 1 GB für alle Projekte zusammen; beides stellst du unter Einstellungen → Aufbewahrung → Log-Verlauf um, dort siehst du auch, wie viel Platz die Logs gerade belegen. Löschst du ein Projekt, verschwindet auch sein Verlauf, und Gespeicherte Logs löschen leert alles auf einmal. In den Instanz-Backups ist der Log-Verlauf nicht enthalten.
Aus einem Skript sieht das so aus:
envoryx project logs shop --service php --tail 200 --followenvoryx project logs shop --since 6h --level error --grep "SQLSTATE" -o fehler.log