G.STANCUTA
Veröffentlicht · 2026 · 04 · 288 Min. Lesezeit

Ploi: Das Server-Team, das ich nie einstellen musste

  • devops
  • vps
  • ploi
  • automation

Ein Dashboard, eine API und ein paar Markdown-Dateien. So erledigt Ploi alles, was ein Einzelbetreiber von einem Produktionsserver braucht, ohne dich an etwas zu binden, aus dem du nicht per SSH entkommen kannst.

Produktionsinfrastruktur als Einzelentwickler zu betreiben bedeutete früher eines von zwei Dingen: für eine verwaltete Plattform bezahlen, die 40 Prozent auf die Hosting-Rechnung aufschlägt, oder Sonntagabende damit verbringen, nginx-Konfigurationen zu lesen und certbot-Hooks zu debuggen. Ploi ist ein dritter Weg. Es liegt auf deinem eigenen VPS, kümmert sich um Provisioning, Deployments, SSL, Cron und Queues und hält sich aus dem Weg. Der Server gehört dir. Ploi kommuniziert einfach über SSH mit ihm.

Einen gehärteten VPS in weniger als zehn Minuten provisionieren

Verbinde deinen DigitalOcean-, Hetzner- oder Vultr-Account über den Ploi-API-Token und das Dashboard erstellt das Droplet für dich. Oder weise Ploi auf einen Server, den du bereits besitzt, indem du eine IP eingibst und es seinen Agenten installieren lässt. In beiden Fällen konfiguriert das Bootstrap-Skript einen Nicht-Root-sudo-Benutzer, sperrt SSH auf schlüsselbasierte Authentifizierung, richtet ufw mit sinnvollen Standardwerten ein, installiert PHP (oder Node, oder beides), nginx, MySQL oder PostgreSQL, Redis und supervisor. All das mit einem einzigen Klick.

Was du am Ende bekommst, ist kein fragiles Konstrukt. Die nginx-vhost-Dateien, supervisor-Konfigurationen und cron-Einträge liegen alle auf der Disk an vorhersehbaren Pfaden. Du kannst per SSH einloggen, alles inspizieren und direkt bearbeiten. Ploi synchronisiert sein Verständnis des Servers beim nächsten Deployment, oder du kannst es über das Dashboard anpassen. Keine Black Boxes.

Isometrisches Diagramm eines VPS, der mit geschichteten Diensten provisioniert wird
Ploi stapelt Dienste auf deinem VPS, ohne den SSH-Zugriff zu abstrahieren.

Git-Deployments ohne Ausfallzeit

Jede Website, die du in Ploi erstellst, erhält ein Deploy-Skript. Die Standardeinstellung ist sinnvoll: Pull vom git-Remote, Abhängigkeiten installieren, Migrationen ausführen, Cache leeren, php-fpm neu laden. Du kannst es nach Bedarf anpassen. Ploi verwendet standardmäßig den atomaren Symlink-Ansatz im deployer-Stil, sodass eingehende Anfragen weiterhin die alte Version treffen, bis die neue vollständig gebaut ist.

Ein Deployment wird ausgelöst durch einen Push auf deinen Branch, durch einen Webhook von GitHub Actions oder durch Aufruf der Ploi REST API. Die letzte Option ist wichtig: Sie bedeutet, dass jeder automatisierte Prozess, einschließlich eines KI-Coding-Agenten, ein Produktionsdeployment mit einem einzigen HTTP-Aufruf starten kann, ohne weiteren Zugriff auf deinen Server.

bash
#!/usr/bin/env bash
# deploy.sh  --  called by CI or by a Ploi deploy hook
set -euo pipefail

APP_DIR="/var/www/myapp/current"

cd "$APP_DIR"

echo "[deploy] pulling latest release..."
git fetch --depth=1 origin main
git reset --hard origin/main

echo "[deploy] installing dependencies..."
composer install --no-dev --optimize-autoloader --no-interaction

echo "[deploy] running migrations..."
php artisan migrate --force

echo "[deploy] warming cache..."
php artisan config:cache
php artisan route:cache
php artisan view:cache

echo "[deploy] restarting queue workers..."
php artisan queue:restart

echo "[deploy] reloading php-fpm..."
sudo systemctl reload php8.3-fpm

echo "[deploy] done."

Füge dieses Skript in den Deploy-Skript-Editor von Ploi ein. Jeder git push auf main löst es über den Webhook aus, den Ploi automatisch in GitHub registriert. Der Neustart der Queue ist sicher, weil supervisor die Worker am Laufen hält, bis die alten Jobs abgearbeitet sind und die neue Worker-Binary übernimmt.

SSL, Cron, Queue-Worker und Backups

Automatisch erneuerndes SSL ist eine Checkbox. Ploi führt certbot aus, schreibt die nginx-Stanza und erneuert vor Ablauf. Du wirst nie wieder ein Zertifikat anfassen, es sei denn, du möchtest dein eigenes mitbringen.

Cron-Jobs leben im Ploi-Dashboard als lesbare Einträge. Du trägst den Zeitplan, den Befehl und den Site-Benutzer ein, der ihn ausführen soll. Ploi schreibt die eigentliche crontab-Zeile auf den Server. Hier ist ein typischer Zeitplan für eine Laravel-App:

yaml
# Ploi cron entries (stored in dashboard, written to server crontab)
# Schedule: every minute
# Command:  cd /var/www/myapp/current && php artisan schedule:run >> /dev/null 2>&1
# User:     ploi

# Schedule: 0 3 * * *
# Command:  cd /var/www/myapp/current && php artisan backup:run --only-db
# User:     ploi

# Schedule: 0 4 * * 0
# Command:  certbot renew --quiet --deploy-hook "systemctl reload nginx"
# User:     root

Queue-Worker sind supervisor-Prozesse. Ploi schreibt eine supervisor-Konfiguration pro Worker-Gruppe, legt die Neustart-Richtlinie fest und gibt dir einen Button zum Neustart oder Pausieren. Wenn ein Worker abstürzt, startet er automatisch neu. Du kannst mehrere Worker-Gruppen mit unterschiedlichen Queues und Parallelitätsstufen definieren, was 90 Prozent der realen Produktions-Setups abdeckt.

Datenbank-Backups werden ebenfalls vom Dashboard aus geplant: Wähle eine Datenbank, einen Zeitplan und ein Ziel (S3, Backblaze oder einen benutzerdefinierten S3-kompatiblen Endpunkt). Ploi führt einen mysqldump oder pg_dump aus, komprimiert ihn, lädt ihn hoch und bereinigt alte Backups gemäß dem von dir festgelegten Aufbewahrungszeitraum. Die Dateien landen in deinem eigenen Storage-Bucket, nicht in dem von Ploi.

Ephemere SSH-Schlüssel per API

Das ist der Teil, den die meisten Menschen übersehen. Ploi stellt eine vollständige REST API für alles bereit, was das Dashboard tun kann, einschließlich Schlüsselverwaltung. Ein KI-Agent, eine CI-Pipeline oder ein Skript kann ein neues SSH-Schlüsselpaar erstellen, den öffentlichen Schlüssel an einen bestimmten Server anhängen, seine Arbeit über SSH erledigen und den Schlüssel dann löschen. Der Server hält nie eine verbleibende Credential.

Hier ist ein kompakter Ablauf. Dein Agent generiert ein RSA-Schlüsselpaar im Arbeitsspeicher, registriert den öffentlichen Schlüssel über die Ploi API, verbindet sich per SSH, führt aus, was er tun soll, und ruft dann DELETE auf der Schlüssel-Ressource auf:

ts
import { execSync } from 'child_process';
import { generateKeyPairSync } from 'crypto';

const PLOI_TOKEN = process.env.PLOI_TOKEN!;
const SERVER_ID  = process.env.PLOI_SERVER_ID!;
const SERVER_IP  = process.env.SERVER_IP!;
const BASE       = 'https://ploi.io/api';

// 1. Generate ephemeral key pair in memory
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
  modulusLength: 4096,
  publicKeyEncoding:  { type: 'pkcs1', format: 'pem' },
  privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
});

// 2. Register public key on the target server
const addRes = await fetch(`${BASE}/servers/${SERVER_ID}/ssh-keys`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${PLOI_TOKEN}`,
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify({ name: 'agent-ephemeral', key: publicKey }),
});
const { id: keyId } = (await addRes.json()).sshKey;

// 3. Write private key to a temp file, chmod 600, connect and run command
const keyFile = `/tmp/agent-${Date.now()}.pem`;
require('fs').writeFileSync(keyFile, privateKey, { mode: 0o600 });
try {
  const output = execSync(
    `ssh -i "${keyFile}" -o StrictHostKeyChecking=no ploi@${SERVER_IP} "php artisan queue:restart"`,
    { encoding: 'utf8' }
  );
  console.log('[agent] remote output:', output.trim());
} finally {
  // 4. Delete the key via API and remove the temp file
  await fetch(`${BASE}/servers/${SERVER_ID}/ssh-keys/${keyId}`, {
    method: 'DELETE',
    headers: { Authorization: `Bearer ${PLOI_TOKEN}`, Accept: 'application/json' },
  });
  require('fs').unlinkSync(keyFile);
  console.log('[agent] ephemeral key deleted, server secured.');
}

Keine persistenten Schlüssel, keine geteilten Geheimnisse in einer .authorized_keys-Datei, die sich über die Zeit ansammelt. Jeder Agentenlauf ist isoliert. Wenn der Agent nach Schritt 2 abstürzt und Schritt 4 nie erreicht, kannst du einen Bereinigungsjob schreiben, der GET /servers/:id/ssh-keys aufruft und alle Schlüssel entfernt, deren Name mit agent-ephemeral beginnt und die älter als eine Stunde sind.

Kein Lock-in, nur SSH

Das gesamte Modell von Ploi ist, dass es deinen Server über SSH verwaltet. Es führt keinen Sidecar-Prozess aus, fängt keinen Traffic ab und erfordert keine dauerhafte Installation von Ploi-spezifischer Software. Die nginx-Konfigurationen, supervisor-Units, crontabs und Deploy-Skripte sind alle Standarddateien auf einer Standard-Linux-Box.

Wenn Ploi morgen verschwinden würde, würde dein Server weiter laufen. Du würdest das Dashboard und die Deploy-Webhooks verlieren, aber die eigentliche Infrastruktur bleibt unverändert. Vergleiche das mit einem PaaS, bei dem deine Container in dem Moment verschwinden, in dem du aufhörst zu bezahlen.

Ploi besitzt deine Infrastruktur nicht. Es kommuniziert nur damit. Dieser Unterschied ist alles.

Schema eines KI-Agenten, der eine Markdown-Gedächtnisdatei liest und die Ploi API aufruft
Ein KI-Agent nutzt eine persistente AGENTS.md-Datei, um sich Server-IDs, Credential-Pfade und Deploy-Konventionen zu merken.

Ploi mit einem KI-Coding-Agenten verwenden

Wenn ein KI-Coding-Agent (Claude Code, Cursor oder jedes Tool, das projektweites Markdown liest) an einer Codebase arbeitet, die über Ploi deployed wird, muss er die Server-Topologie kennen, welche Befehle Deployments auslösen und wie er sich von häufigen Fehlern erholt. Ohne diesen Kontext beginnt jede Sitzung bei null und der Agent macht konservative Vermutungen oder stellt dir dieselben Fragen wiederholt.

Die Lösung ist eine persistente AGENTS.md-Datei, die ins Repository eingecheckt ist. Der Agent liest sie zu Beginn jeder Sitzung und nutzt sie als Langzeitgedächtnis für die Infrastruktur. Hier ist ein realistisches Beispiel:

md
# AGENTS.md — Infrastructure Memory for AI Coding Agents

## Ploi Server Setup

- Provider: Hetzner CX22, Ubuntu 24.04
- Ploi server ID: 4821  (env: PLOI_SERVER_ID)
- Public IP: 95.111.42.7  (env: SERVER_IP)
- Site ID: 9103  (for deploy webhook calls)
- PHP: 8.3, nginx, PostgreSQL 16, Redis 7, supervisor

## Deploy

Trigger a deploy by calling the Ploi API:

  POST https://ploi.io/api/sites/9103/deploy
  Authorization: Bearer $PLOI_TOKEN

Zero-downtime: symlink swap. Old release stays live until new release is fully built.
Deploy script path on server: /etc/ploi/deploy-scripts/site-9103.sh

## Queues

Workers are managed by supervisor. To restart after a code change:

  ssh ploi@95.111.42.7 "php artisan queue:restart"

Or trigger via the ephemeral SSH flow in scripts/agent-ssh.ts.
Worker logs: /var/www/myapp/current/storage/logs/worker-*.log

## Cron

PHP scheduler runs every minute:
  cd /var/www/myapp/current && php artisan schedule:run

DB backup runs daily at 03:00 UTC, sent to Backblaze bucket `myapp-backups`.

## SSL

Managed by certbot via Ploi. Cert path: /etc/letsencrypt/live/myapp.com/
Renews automatically. Do not touch unless domain changes.

## Common Gotchas

- After editing .env on the server, run `php artisan config:cache` or changes are ignored.
- Queue workers cache config on boot. Always run `queue:restart` after a deploy.
- The ploi user owns /var/www. Do not sudo-write files there or nginx will 403.
- Ploi writes supervisor configs to /etc/supervisor/conf.d/ploi-*.conf. Do not rename them.

## Cleanup Protocol

After any agent session that used ephemeral SSH keys:
  GET https://ploi.io/api/servers/4821/ssh-keys
  DELETE any key with name prefix "agent-ephemeral" older than 60 minutes.

Mit dieser Datei an Ort und Stelle weiß der Agent, wo er suchen soll, was er ausführen soll und was er vermeiden soll. Er muss die Server-ID nicht aus Umgebungsvariablen neu entdecken oder den Deploy-Befehl erraten. Die AGENTS.md zeichnet auch das Bereinigungsprotokoll für ephemere Schlüssel auf, sodass selbst wenn eine Agenten-Sitzung unterbrochen wurde, die nächste Sitzung weiß, was zu bereinigen ist.

Behandle AGENTS.md als lebendiges Dokument. Wenn du einen neuen Queue-Worker hinzufügst, aktualisiere den supervisor-Abschnitt. Wenn du das Deploy-Skript änderst, aktualisiere den Pfad. Der Aufwand ist gering und der Ertrag ist ein Agent, der sich verhält, als würde er deine Infra seit Monaten betreiben.

Was Das Kostet und Wann Es Sinn Macht

Ploi berechnet eine monatliche Pauschalgebühr pro Server, derzeit etwa acht Euro für den ersten Server. Das deckt unbegrenzte Sites auf diesem Server ab. Füge einen fünf-Euro-Hetzner-CX22 hinzu und du hast einen produktionsreifen Host für eine Handvoll Apps für unter fünfzehn Euro pro Monat insgesamt. Vercel oder Railway bei gleichem Nutzungsgrad kosten dich drei- bis fünfmal so viel.

Der Kompromiss ist real: Du besitzt den Server, was bedeutet, dass du die OS-Patches, die Disk und den gelegentlichen Absturz um 2 Uhr nachts besitzt. Für Projekte, die eine Datenbank, Hintergrundjobs oder ein benutzerdefiniertes Binary benötigen, spricht die Rechnung stark für einen VPS mit Ploi gegenüber jedem verwalteten PaaS. Für eine einfache statische Website oder eine reine serverlose API gewinnt der PaaS wahrscheinlich bei der Bequemlichkeit.

  • Beste Eignung: Laravel, Rails, Django oder jede App mit Datenbank, Queue und Cron.
  • Gute Eignung: Node-Dienste, die einen persistenten Prozess und eine Redis-Verbindung benötigen.
  • Neutrale Eignung: Statische Sites, die nur ein schnelles CDN brauchen. Verwende stattdessen ein CDN.
  • Schlechte Eignung: Teams, die GitOps, Kubernetes oder Infrastructure-as-Code in der Versionskontrolle möchten. Ploi ist kein Terraform.

Für einen Einzelentwickler oder ein kleines Team, bei dem eine Person die Infra besitzt, eliminiert Ploi den operativen Aufwand, ohne eine neue Abstraktion hinzuzufügen, gegen die du ankämpfen müsstest. Der Server gehört dir, die Dateien sind normal und der SSH-Schlüssel liegt in deinen Händen. Das ist der ganze Punkt.

Portfolio · Schriftfeld
Gezeichnet von
G. STANCUTA
Disziplin
AI & AUTOMATION
Standort
MORTER · SÜDTIROL
Status
Verfügbar
Sprachen
IT · EN · RO · DE+
Stack
PLOI · HETZNER
Revision
REV 2026.A
2026

© 2026 Gabriel Stancuta · jumpinotech.com — Mit KI entworfen, gebaut, um sich selbst zu betreiben.