Installationsanleitung
Inhalt
Kurz gesagt
PHP 8.1 oder neuer, Apache mit mod_rewrite, ein SSL-Zertifikat und Schreibrechte. Keine Datenbank, kein Composer, kein npm. Die Domain zeigt auf den Ordner public/.
1. Systemvoraussetzungen
CMF hat bewusst wenige Anforderungen. Ein üblicher Webspace mit PHP reicht.
.htaccess.htaccess leitet alle Aufrufe auf HTTPS umnginx: CMF liefert keine nginx-Konfiguration mit. Die Regeln aus .htaccess – Weiterleitung aller Seiten auf index.php, HTTPS, Sperre für config/ und content/, keine Skripte in media/ und files/, Security-Header – musst du dort selbst in die Server-Konfiguration übertragen.
2. Ordnerstruktur verstehen
Das ist der wichtigste Punkt der Installation. CMF trennt öffentliche und private Dateien:
public/ = DocumentRoot
Der Ordner public/ ist das Web-Root-Verzeichnis – der Ordner, auf den die Domain zeigt. Nur er ist öffentlich erreichbar.
Er enthält:
index.php– Websiteadmin.php– Admin-Bereichapi.php– REST-API.htaccess– Weiterleitungen, HTTPS, Caching, Schutzregelnassets/– CSS, JavaScript, Schriftenmedia/– hochgeladene Dateienfiles/– Download-Dateien, z. B.README_MASCHINEN.md
Dazu schreibt CMF hier automatisch sitemap.xml, robots.txt, feed.xml, llms.txt und search-index.json.
Alles andere = nicht öffentlich
Die Ordner app/, config/ und content/ liegen neben public/, also eine Ebene über dem DocumentRoot. Über den Browser sind sie nicht erreichbar – das ist Absicht.
app/– der PHP-Systemcodeconfig/–site.json, Benutzer (Passwörter nur als Hash), Themecontent/– Seiten, Blog-Beiträge, Header/Footer und Formular-Einsendungen als JSONversion.json– installierte Version
In config/ und content/ liegt zusätzlich je eine .htaccess, die jeden Zugriff sperrt – ein Sicherheitsnetz, falls der DocumentRoot doch einmal falsch gesetzt ist.
Die häufigste Fehlerquelle: Den Inhalt von public/ in ein anders benanntes Web-Root (etwa htdocs/) zu kopieren, funktioniert nicht. CMF erwartet app/, config/, content/ und public/ nebeneinander in einem Ordner – und schreibt Sitemap, Feed und Theme-CSS nach public/. Lässt dein Hoster keinen eigenen DocumentRoot zu, frag dort nach, bevor du installierst.
3. Hochladen und einrichten
Die Struktur aus dem ZIP bleibt auf dem Server genau so erhalten. Du lädst alles in einen Projektordner und lässt die Domain auf dessen Unterordner public/ zeigen.
Das Archiv von der Download-Seite lokal entpacken
app/, config/, content/, public/ und version.json in einen Projektordner kopieren
Im Hosting-Panel die Domain auf den Ordner public/ zeigen lassen
Schreibrechte setzen, name, lang und baseUrl eintragen
Domain aufrufen – die Startseite sollte erscheinen
So sieht die Struktur auf dem Server aus:
/projektordner/ ← nicht öffentlich
├── app/ ← PHP-Systemcode
├── config/ ← site.json, Benutzer, Theme
├── content/ ← Seiten, Blog, Einsendungen
├── version.json ← installierte Version
└── public/ ← DocumentRoot (hierhin zeigt die Domain)
├── index.php
├── admin.php
├── api.php
├── .htaccess
├── assets/
├── files/
└── media/4. Schreibrechte
CMF speichert alles als Dateien. PHP braucht deshalb Schreibrechte auf diese Ordner – einschließlich aller Unterordner und Dateien darin. Welche Werte nötig sind, hängt vom Hoster ab: Oft genügt 755 für Ordner; läuft PHP unter einem anderen Benutzer als dein FTP-Zugang, braucht es 775.
config/
Benutzer, Theme, Login-Sperre und die Backups des System-Updates. Nötig für: Passwörter, Benutzer, Theme speichern, Updates.
content/
Seiten, Blog-Beiträge, Header/Footer und Formular-Einsendungen. Nötig für: jedes Speichern im Admin oder per API.
public/
Hier entstehen sitemap.xml, robots.txt, feed.xml, llms.txt und search-index.json bei jeder Änderung neu.
public/media/
Speicherort für hochgeladene Bilder, Videos und Dokumente. Nötig für: Upload im Admin und per API.
public/assets/css/
Hier schreibt CMF theme.css und custom.css. Nötig für: Theme speichern und Custom CSS.
Für das System-Update
Zusätzlich app/ und version.json. Das Update ersetzt außerdem index.php, admin.php, api.php und public/assets/js/.
5. Konfiguration: site.json
Anpassen musst du nur eine Datei: config/site.json. Eine Oberfläche dafür gibt es im Admin nicht – du bearbeitest sie direkt oder per API (site_update). Das Minimum:
{
"name": "Meine Website",
"lang": "de",
"baseUrl": "https://meine-domain.de"
}| Feld | Wert | Wirkung |
|---|---|---|
name (Pflicht) | Text | Name der Website: Titel-Anhang (ohne title_suffix), og:site_name, strukturierte Daten, Überschrift von llms.txt und Feed |
lang (Pflicht) | Sprachcode, z. B. de | <html lang>, og:locale (aus de wird de_DE), Sprache des Feeds |
baseUrl | Vollständige URL ohne Schrägstrich am Ende | Canonical, Sitemap, Feed, llms.txt, absolute Bild-URLs, strukturierte Daten. Fehlt sie, fehlen Canonical und strukturierte Daten |
og_image | Pfad, z. B. /media/…/vorschau.png | Vorschaubild beim Teilen, wenn eine Seite kein eigenes Bild hat |
logo | Pfad zum Logo | Logo im Organization-Schema; eine SVG-Datei dient zusätzlich als Favicon, falls keine favicon.svg vorhanden ist |
title_suffix | Text, darf leer sein | Anhang im Seitentitel („Seite | Anhang“). Ohne das Feld wird name angehängt, ein leerer Wert hängt nichts an |
software_schema | true / false | Gibt auf der Startseite zusätzlich ein SoftwareApplication-Schema aus |
software_category | Text | Kategorie im Schema (Standard: DeveloperApplication) |
software_version | Text | Version im Schema (Standard: Version aus version.json) |
download_url | Pfad oder URL | Download-Adresse im Schema (Standard: /files/cmf_latest.zip) |
csp | Objekt mit Listen: script_src, connect_src, style_src, img_src, font_src, media_src, frame_src | Erlaubt zusätzliche fremde Quellen in der Content-Security-Policy, z. B. für ein externes Widget oder eine Schrift. Die strenge Basis bleibt bestehen |
Nach einer Änderung
Die baseUrl muss zur echten Domain passen. Sitemap, Feed und llms.txt schreibt CMF neu, sobald du eine Seite oder einen Beitrag speicherst. Hast du nur site.json geändert, rufst du dafür die API-Aktion sitemap_generate auf – oder speicherst einmal eine Seite.
README_MASCHINEN.md ist keine Konfiguration
Die Datei public/files/README_MASCHINEN.md ist eine Kurzreferenz der API, die du einem Agenten als Kontext mitgibst. Für den Betrieb musst du sie nicht anpassen.
Wichtig: Trag dort nie deinen API-Token ein. Die Datei ist öffentlich abrufbar und wird in der automatisch erzeugten llms.txt verlinkt. Wenn du sie anpassen willst, dann als Kopie auf deinem Rechner.
6. Erster Login
Sobald die Dateien liegen und site.json angepasst ist, kann es losgehen:
Admin aufrufen
Den Admin-Bereich erreichst du unter:
https://meine-domain.de/admin.phpDas Download-Paket enthält einen Zugang mit Benutzername admin und Passwort admin.
Nach Fehlversuchen wartet der Login jedes Mal länger: 5 Sekunden, dann 25, 125 … bis höchstens eine Stunde.
Eigenes Passwort – Pflicht
Wer sich mit dem Standard-Passwort anmeldet, landet sofort bei „Eigenes Passwort festlegen“. Du gibst das neue Passwort zweimal ein, mindestens 8 Zeichen, dann „Passwort speichern“. Vorher ist keine andere Admin-Seite erreichbar.
In config/users.json steht kein lesbares Passwort, nur ein Hash. Später änderst du Passwörter unter Benutzer → Passwort ändern.
Installation prüfen
- ✓ Startseite lädt über HTTPS
- ✓ Eine Seite lässt sich speichern (
content/) - ✓ Ein Bild lässt sich hochladen (
public/media/) - ✓ „Theme speichern“ wirkt (
public/assets/css/) - ✓
/sitemap.xmlund/llms.txtzeigen deine Domain
Klappt etwas nicht, prüfe zuerst DocumentRoot und Schreibrechte.
7. API-Zugang anlegen
Skripte, Workflows und Agenten melden sich mit einem Token an. So legst du ihn an:
- Im Admin Benutzer öffnen.
- Unter „Neuen Zugang anlegen“ Benutzername und Passwort (mindestens 8 Zeichen) eingeben.
- Das Häkchen „API-Zugang anlegen“ setzen und „Benutzer anlegen“ klicken.
- Das Token (beginnt mit
cms_) erscheint genau einmal unter „API-Token erzeugt“. Sofort kopieren und sicher ablegen – gespeichert wird nur ein Hash.
Die Maschine schickt es bei jedem Aufruf mit: Authorization: Bearer cms_…
Gut zu wissen: Ein API-Benutzer ist gleichzeitig ein vollwertiger Admin – eingeschränkte Rollen gibt es nicht. Ein Token lässt sich weder bearbeiten noch erneuern: Für ein neues legst du einen neuen Zugang an und löschst den alten. Am besten bekommt jeder Agent seinen eigenen Zugang. Wie es danach weitergeht, zeigt die Maschinen-Anleitung.
8. System-Update, Backup und Rollback
Updates spielst du im Admin ein. Unter Einstellungen vergleicht der Bereich „System-Update“ die installierte mit der verfügbaren Version.
Einstellungen → Export → „ZIP exportieren“ – das Update sichert nur Systemdateien, keine Inhalte
„Update auf … installieren“ klicken und bestätigen
Unter „Hinweise zum letzten Update“ steht, was nicht ersetzt wurde
„Rollback zur vorherigen Version“ stellt den Stand vor dem Update wieder her
Was beim Update passiert
CMF lädt das Update-Paket per HTTPS vom Update-Server, legt ein Backup aller Dateien an, die es ersetzt, und tauscht dann den Systemcode aus: app/, index.php, admin.php, api.php und das JavaScript. Behalten wird nur das jüngste Backup.
Unangetastet bleiben Inhalte, Medien, public/files/, site.json, Benutzer, Theme und custom.css.
Angepasste Dateien bleiben (seit 1.17)
Seit Version 1.17 enthält das Update-Paket public/.htaccess, base.css, admin.css und die Schriften nicht mehr. Hast du diese Dateien angepasst – eigene Weiterleitungen, eigene CSP, Farben –, bleiben sie stehen. Unveränderte Standard-Dateien zieht CMF beim ersten Aufruf nach dem Update selbst nach, neue CSS-Regeln kommen dann über cmf-compat.css dazu. Eigene Schriften in public/assets/fonts/ werden nicht gelöscht.
Aktualisierst du von einer Version vor 1.14, läuft die Content-Security-Policy zunächst nur beobachtend (Report-Only), bis in site.json ein csp-Eintrag steht. Auch darauf weist der Update-Bereich hin.