Installation und Betrieb des Manage-Servers. Voraussetzungen: PHP 8.0 oder neuer und ein Webserver. Kein Datenbankserver, kein Composer, kein Build-Schritt.
Repository in ein Verzeichnis des Webservers legen, zum Beispiel
/var/www/manage.
Konfiguration anlegen:
cp config.sample.php config.php
Passwort-Hash erzeugen und eintragen:
php -r 'echo password_hash("ein-langes-passwort", PASSWORD_DEFAULT), PHP_EOL;'
define("MANAGE_ADMIN_PASSWORD_HASH", '$2y$12$…');
Einfache Anführungszeichen verwenden – ein bcrypt-Hash enthält $.
Öffentliche URL setzen. Ohne diesen Wert kann kein Client ein Paket herunterladen:
define("MANAGE_PUBLIC_URL", "https://manage.example.org");
Absolut, ohne Schrägstrich am Ende. Liegt die Installation in einem
Unterverzeichnis, gehört es dazu: https://example.org/manage.
Produkt benennen. MANAGE_PACKAGE_PREFIX bestimmt den Dateinamen der
gespeicherten Pakete und sollte zum Build-Skript des Projekts passen:
define("MANAGE_PRODUCT_NAME", "Example Orderform");
define("MANAGE_PACKAGE_PREFIX", "example-orderform");
Schreibrechte auf storage/ sicherstellen. Das Verzeichnis wird bei Bedarf
selbst angelegt:
mkdir -p storage && chown www-data:www-data storage && chmod 2775 storage
Oberfläche öffnen: https://manage.example.org/admin/login.php.
Unter Einstellungen → Diagnose steht danach, ob alles Wesentliche stimmt: öffentliche URL, Schreibrechte, Passwort, Upload-Limits.
Die mitgelieferte .htaccess sperrt storage/, includes/, client-package/
sowie config.php und setzt Sicherheits-Header. Sie funktioniert nur, wenn
AllowOverride All für das Verzeichnis gesetzt ist.
Für nginx greift keine .htaccess. Die Sperren müssen von Hand gesetzt werden:
location ^~ /storage/ { deny all; return 404; }
location ^~ /includes/ { deny all; return 404; }
location ^~ /client-package/ { deny all; return 404; }
location = /config.php { deny all; return 404; }
location ~ /\. { deny all; return 404; }
Prüfen, dass die Sperren greifen:
curl -s -o /dev/null -w "%{http_code}\n" https://manage.example.org/config.php
curl -s -o /dev/null -w "%{http_code}\n" https://manage.example.org/storage/instances.json
Beides muss 403 oder 404 liefern.
Backups und Release-Pakete werden per HTTP hochgeladen. Beide PHP-Grenzen müssen
groß genug sein, post_max_size mindestens so groß wie upload_max_filesize:
upload_max_filesize = 256M
post_max_size = 256M
max_execution_time = 300
memory_limit = 256M
Die aktuellen Werte zeigt die Diagnose-Seite. Ist der Wert zu klein, meldet der Client eine Fehlermeldung, die die Ursache ausdrücklich benennt.
memory_limit wird relevant, wenn das S3-Archiv aktiv ist: Ein Upload zu S3 hält
die Datei vollständig im Speicher.
Unter Einstellungen einstellbar, gespeichert in storage/settings.json. Die
Werte dort haben Vorrang vor den Konstanten in config.php.
Änderungen werden sofort angewendet, nicht erst beim nächsten Upload.
Ohne S3 liegen alle Backups auf der lokalen Platte. Mit S3 wird jedes empfangene Backup zusätzlich in ein S3-kompatibles Objektspeicher-System geschoben; lokal bleiben nur die neuesten Kopien.
define("MANAGE_S3_ENABLED", true);
define("MANAGE_S3_ENDPOINT", "https://fsn1.your-objectstorage.com");
define("MANAGE_S3_REGION", "fsn1");
define("MANAGE_S3_BUCKET", "mein-backup-bucket");
define("MANAGE_S3_PREFIX", "manage-backups");
define("MANAGE_S3_ACCESS_KEY", "…");
define("MANAGE_S3_SECRET_KEY", "…");
Objekte liegen unter <prefix>/<instanz>/<dateiname>.
Adressierung: Standard ist virtual-hosted (https://<bucket>.<endpoint>/<key>),
was Hetzner und die meisten Anbieter erwarten. Verlangt der Anbieter path-style,
MANAGE_S3_PATH_STYLE auf true setzen.
Verhalten:
Fehlersuche über storage/logs/s3.log und den Auszug unter Einstellungen:
AccessDenied oder eine Umleitung in der Statuskette deuten fast immer auf die
falsche Adressierungsart hin, SignatureDoesNotMatch auf falsche Region oder
falschen Secret Key. Umleitungen werden bewusst nicht verfolgt, damit eine
Fehlkonfiguration sichtbar wird.
Der Manage-Server hält Release-Pakete und die Backups aller Instanzen – er ist selbst sicherungswürdig. Zu sichern sind:
storage/ – Instanzen, Manifest, Pakete, Backups, Einstellungenconfig.php – ZugangsdatenBei aktivem S3-Archiv liegen die Backups zusätzlich im Bucket; storage/instances.json
und storage/releases/ aber nicht.
storage/logs/ und rotieren automatisch.config.php; angemeldete Sitzungen bleiben bis
zum Ablauf bestehen. Sollen sie sofort enden, session.save_path leeren oder
session_name in includes/auth.php ändern.