Exploitation
Options de démarrage
| Option | Variable d’environnement | Par défaut | |
|---|---|---|---|
-addr |
IC_ADDR |
:8080 |
Adresse et port |
-data |
IC_DATA |
./data |
Dossier de données |
-cache-mb |
IC_CACHE_MB |
128 |
Cache des pages en Mo, 0 = désactivé |
-secure-cookies |
IC_SECURE_COOKIES=1 |
désactivé | Cookie de session uniquement via HTTPS – à activer impérativement derrière HTTPS |
-rate-limit |
IC_RATE_LIMIT |
120 |
Requêtes API par minute et par IP sans connexion (dix fois plus avec token/session), 0 = désactivé – voir la doc de l’API |
-headless |
IC_HEADLESS=1 |
désactivé | Sans app d’admin, imposer la connexion et les sessions – voir Serveur headless |
| – | IC_MASTER_TOKEN |
– | Token avec droit d’écriture sans compte utilisateur (au moins 32 caractères) – voir Serveur headless |
| – | IC_SETUP_TOKEN |
– | Optionnel : secret exigé pour la première installation (premier compte admin) – empêche qu’un inconnu arrive le premier sur une instance fraîchement publiée et encore vide. Demandé dans le formulaire d’installation |
-media-cache-mb |
IC_MEDIA_CACHE_MB |
512 |
Cache disque pour les médias dans S3 en Mo, 0 = désactivé – voir Stocker les médias dans S3 |
| – | IC_ENCRYPTION_KEY |
– | Clé pour les identifiants chiffrés dans les paramètres (au moins 32 caractères) ; sans elle, IllusionCMS crée data/secret.key – voir Stocker les médias dans S3 |
Vous définissez au démarrage les variables d’environnement pour les sources REST ({env.NAME}). Les variables préfixées par IC_ (configuration du CMS, p. ex. IC_MASTER_TOKEN) ne sont jamais lisibles ici. Les Workflows n’ont pas accès aux variables d’environnement.
En outre : -version affiche la version, -create-token "Name" crée un token API avec droit d’écriture, l’affiche et se termine, -enable-admin réactive un admin désactivé dans les paramètres, -healthcheck interroge /healthz du serveur en cours d’exécution et se termine avec le code de sortie 0 ou 1 – prévu pour le HEALTHCHECK d’un conteneur Docker.
Docker et Coolify : des fichiers Compose prêts à l’emploi (autonome derrière un reverse proxy comme Apache, et pour Coolify) sont fournis dans chaque version sous la forme illusioncms-vX.Y.Z-deploy.zip (avec les binaires Linux, instructions dans le README.md inclus) et dans le dépôt de déploiement IllusionCMS-Deployment. Important derrière un proxy : le proxy doit transmettre l’en-tête Host (avec Apache, ProxyPreserveHost On) – sinon IllusionCMS ne peut pas associer le site au domaine – et définir X-Forwarded-Proto, afin que le sitemap et robots.txt utilisent https://.
Dossier de données et sauvegarde
data/
illusion.db base de données (pages, Snippets, CSS/JS, Collections, paramètres …)
illusion.db-wal journal d’écriture de la base de données (en fait partie !)
media/2026/10/… fichiers téléversés et importés
backups/ sauvegardes automatiques : nocturnes sans médias (les 7 dernières)
et avant l’import d’un Bundle, médias compris (les 3 dernières)
cache/media/ cache disque des médias depuis S3 (seulement avec S3)
secret.key clé des identifiants chiffrés (sans IC_ENCRYPTION_KEY)
Sauvegardes automatiques : chaque nuit à partir de 3 h (heure du serveur), IllusionCMS sauvegarde l’intégralité du contenu – pages, CSS/JS, Snippets, Collections, paramètres des fichiers … – sans les fichiers médias eux-mêmes, mais seulement si quelque chose a changé depuis la dernière sauvegarde nocturne. Les 7 dernières sont conservées. Restaurer : sous Paramètres → Synchronisation, télécharger la sauvegarde et la réimporter ; le dossier des médias reste inchangé. Si les entrées des Collections avec Données live doivent elles aussi revenir à l’état de la sauvegarde, cochez lors de l’import Reprendre aussi du bundle les entrées des Collections avec données live. Il est préférable de sauvegarder en plus les fichiers médias avec le dossier de données (ils changent rarement et ne sont supprimés que si vous les supprimez explicitement).
Sauvegarde : le plus sûr est d’arrêter brièvement le serveur et de copier tout le dossier. En fonctionnement : sqlite3 data/illusion.db ".backup backup.db" plus une copie de media/ – ou simplement télécharger un Bundle (contient tout le contenu, mais ni les comptes ni les tokens).
Stocker les médias dans S3
Par défaut, les fichiers téléversés et importés se trouvent dans data/media. Au choix, IllusionCMS les place dans un stockage compatible S3 – pratique si le serveur a peu de place ou si les fichiers doivent être sauvegardés séparément du serveur. Les adresses ne changent pas : les fichiers restent accessibles sous /media/…, IllusionCMS les récupère lui-même dans le bucket (y compris par plages pour les vidéos et les téléchargements reprenables). Le bucket reste privé, il n’a pas besoin d’être lisible publiquement.
Où : Paramètres → Stockage (en mode distant pour le serveur connecté). En haut figurent le stockage actif, le nombre et la taille des fichiers et le remplissage du cache disque.
Champs :
- Endpoint – adresse du service S3, p. ex.
https://s3.eu-central-1.amazonaws.com. - Région – p. ex.
eu-central-1; avec Garage généralementgarage, avec Cloudflare R2auto. Vide =us-east-1. - Bucket – doit déjà exister. Préfixe (facultatif) – p. ex.
cms/si plusieurs applications partagent un bucket. - Clé d’accès et clé secrète – la clé doit pouvoir lire, écrire, supprimer et lister. Le secret n’est plus jamais affiché ; si vous laissez le champ vide plus tard, le secret enregistré est conservé.
- Path style – adressage
endpoint/bucket/fichierau lieu debucket.endpoint/fichier. Nécessaire pour Garage et les endpoints avec une adresse IP.
| Fournisseur | Endpoint | Région | Path style |
|---|---|---|---|
| Garage (auto-hébergé) | http://127.0.0.1:3900 ou votre adresse Garage |
garage |
activé |
| Hetzner Object Storage | https://fsn1.your-objectstorage.com (ou nbg1, hel1) |
fsn1 |
désactivé |
| Cloudflare R2 | https://<account-id>.r2.cloudflarestorage.com |
auto |
activé |
| AWS S3 | https://s3.eu-central-1.amazonaws.com |
eu-central-1 |
désactivé |
Tester la connexion écrit, lit et supprime un petit objet de test dans le bucket et indique clairement ce qui manque (adresse injoignable, clé inconnue, secret erroné, bucket absent, droits manquants). Enregistrer mémorise les données – tant que le stockage local est actif, seulement comme brouillon.
Déménager : Passer à S3 … lance une migration guidée en arrière-plan : tous les fichiers sont copiés (ce qui existe déjà à la cible avec la même taille est ignoré – un déménagement interrompu reprend donc là où il s’est arrêté), puis chaque copie est vérifiée, et ce n’est qu’ensuite qu’IllusionCMS bascule et vide le cache des pages. Vous pouvez continuer à travailler pendant ce temps : les téléversements et suppressions vont d’abord dans l’ancien stockage, sont consignés et repris lors du basculement – les écritures ne s’interrompent que pendant ce bref instant. Avec Annuler ou en cas d’erreur, l’ancien stockage reste actif. Si Supprimer ensuite les anciens fichiers est coché, IllusionCMS nettoie l’ancien stockage après un basculement réussi ; sinon, il reste disponible en secours. Revenir au stockage local … fonctionne de la même façon dans l’autre sens. Le bucket et le préfixe d’un stockage S3 actif ne se modifient que par migration ; de nouveaux identifiants pour le même bucket s’appliquent immédiatement après un test réussi.
Cache disque : devant S3 se trouve un cache local dans data/cache/media (512 Mo par défaut, option de démarrage -media-cache-mb ou IC_MEDIA_CACHE_MB, par instance aussi dans les paramètres de stockage). Il accélère surtout les variantes d’images et le WebP et continue de livrer les fichiers en cache si S3 est brièvement injoignable. Un bucket ne doit être utilisé que par une seule instance IllusionCMS (le cache suppose que toutes les modifications passent par elle) – pour une deuxième instance, utilisez un bucket ou un préfixe distinct.
Identifiants chiffrés : le secret n’est stocké dans la base de données que sous forme chiffrée (AES-256-GCM). La clé provient de la variable d’environnement IC_ENCRYPTION_KEY (au moins 32 caractères, p. ex. openssl rand -hex 32) ; si elle n’est pas définie, IllusionCMS crée au premier besoin le fichier data/secret.key (lisible uniquement par le propriétaire). Emportez la clé lors d’un déménagement vers un autre serveur – copiez data/secret.key ou définissez la même IC_ENCRYPTION_KEY. Si la clé manque ou est différente, le secret ne peut plus être déchiffré : IllusionCMS démarre alors avec les fichiers locaux et affiche l’erreur dans les paramètres de stockage – saisissez de nouveau le secret et enregistrez, S3 s’applique alors à nouveau. Les Bundles ne contiennent volontairement pas le paramètre de stockage.
Ce qui est chiffré et ce qui ne l’est pas : sont chiffrés avec la même clé dans la base : le secret S3, les secrets de webhooks, le mot de passe SMTP, les jetons IllusionDB et les jetons des connexions ; les anciennes valeurs en clair restent lisibles et sont chiffrées à la prochaine sauvegarde. Les secrets enregistrés (mot de passe SMTP, jeton IllusionDB, secret S3, jeton de connexion) ne sont réutilisés que pour la même cible – si l’hôte, l’adresse, l’endpoint ou le bucket change, il faut les saisir de nouveau. Ne sont pas chiffrés les en-têtes des sources REST (Authorization …) : ils font partie du contenu et figurent donc dans les bundles, les sauvegardes nocturnes et lors de l’envoi vers une autre instance – c’est la seule façon de restaurer entièrement une instance. Traitez bundles et sauvegardes comme des identifiants (le dossier data/backups et le cache média ne sont lisibles que par l’utilisateur du serveur) ; les identifiants des sources peuvent aussi venir de variables d’environnement ({env.SHOP_TOKEN}), ils ne sont alors stockés nulle part dans la base.
Sauvegardes : même avec S3, la base de données reste locale dans data/illusion.db (de même que les sauvegardes nocturnes). Pour la sauvegarder en continu dans le même bucket, Litestream convient bien – un programme distinct à côté d’IllusionCMS qui réplique en continu la base SQLite. Exemple de litestream.yml (un exemple Docker Compose complet figure dans le README.md du paquet de déploiement) :
dbs:
- path: /data/illusion.db
replicas:
- type: s3
endpoint: https://fsn1.your-objectstorage.com
bucket: firma-media
path: litestream/illusion.db
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
Restauration, serveur arrêté, avec litestream restore -config litestream.yml /data/illusion.db. Le fournisseur S3 ne sauvegarde pas automatiquement les fichiers médias eux-mêmes – activez si possible le versionnage ou la réplication du bucket chez le fournisseur.
Construire en local, publier en ligne (Bundles)
Vous pouvez construire un site en local, puis le transférer intégralement sur votre serveur en ligne. Un Bundle est un fichier avec l’extension .icb (IllusionCMS-Bundle, techniquement un ZIP) contenant l’ensemble du contenu de l’instance : sites, pages, CSS/JS, Snippets, fichiers, Collections, sources REST et redirections. Les comptes et les tokens API n’en font pas partie – sur le serveur, vous continuez à vous connecter avec votre compte de là-bas.
Tout le nécessaire se trouve sous Paramètres → Synchronisation :
- Télécharger – le Bundle sous forme de fichier
.icb. - Téléverser et importer – sur le serveur en ligne : choisir le fichier
.icb, Importer et remplacer. Les Bundles et sauvegardes de versions plus anciennes (.zip) peuvent toujours être importés. - Synchroniser avec un serveur – depuis l’admin local, en une seule étape, via une connexion enregistrée : Téléverser remplace le contenu du serveur par le contenu local, Récupérer rapatrie ici l’état du serveur, données live comprises (p. ex. sur un nouvel ordinateur ou après une correction d’urgence en ligne). La progression est affichée. Si quelque chose a changé du côté qui sera remplacé depuis la dernière synchronisation, le CMS vous avertit au préalable – les données live ne comptent pas comme modification.
Bon à savoir :
- L’import remplace l’intégralité du contenu de la cible – ce qui n’a été modifié qu’en ligne est ensuite perdu. Au préalable, le serveur sauvegarde automatiquement son état précédent (les 3 dernières sauvegardes peuvent être téléchargées dans la même vue ; restaurer = importer la sauvegarde).
- Les données live restent : les entrées des Collections cochées Données live (p. ex. les demandes de contact) sont toujours conservées sur la cible – y compris celles qui arrivent pendant que vous travaillez en local. Les entrées locales de ces Collections ne sont pas transférées. Dans l’autre sens (importer en local un Bundle du serveur en production, restaurer une sauvegarde), vous les reprenez en cochant Reprendre aussi du bundle les entrées des Collections avec données live.
- Conserver les contenus gérés en ligne : avec Conserver les entrées de Collections, les entrées du serveur sont conservées (p. ex. des articles de blog rédigés en ligne) – le layout, les pages et le code proviennent malgré tout de la version locale. L’association se fait via le Slug de la Collection.
- Domaines : en local, votre site n’a généralement pas de domaine. Dans ce cas, le site sur le serveur conserve ses domaines enregistrés. Si vous saisissez des domaines en local, ils sont repris.
- Les fichiers inchangés ne sont pas réécrits – les transferts répétés vont plus vite. Le Bundle entier est néanmoins téléversé.
- Les deux instances devraient avoir la même version d’IllusionCMS ; un serveur plus ancien refuse les Bundles d’une version plus récente.
- Si le serveur tourne derrière nginx,
client_max_body_sizedoit être assez grand pour le Bundle (Caddy : pas de limite). - Scriptable :
curl -H "Authorization: Bearer <token>" -H "Content-Type: application/zip" --data-binary @bundle.icb https://www.firma.de/api/v1/bundle(voir l’API).
Plusieurs instances : travailler en direct ou synchroniser
Sous Paramètres → Connexions, vous saisissez d’autres instances IllusionCMS – nom, adresse et un token API avec droit d’écriture provenant de là-bas (sur le serveur sous Paramètres → Tokens API ; pour un serveur sans admin, le token maître ou via -create-token). Le token reste dans la base de données locale, n’est pas affiché et ne fait pas partie du Bundle. Vérifier indique si le serveur est joignable, quelle version y tourne et s’il fonctionne en mode headless. Peu importe que l’admin tourne sur le serveur lui-même – seul le token est nécessaire. Vous gérez ainsi autant d’instances que vous voulez depuis une seule app locale ; le mode headless est une option supplémentaire pour les serveurs que vous gérez exclusivement de cette façon.
Avec une connexion, il existe deux façons de travailler – vous pouvez combiner les deux :
- Travailler en direct : en haut du menu figure l’instance avec laquelle l’admin travaille actuellement (Local). Si vous y choisissez une connexion, toutes les vues – pages, fichiers, Collections, statistiques, Workflows, journal 404 … – s’adressent directement à ce serveur ; les modifications prennent effet immédiatement. Le menu affiche alors le nom de la connexion avec LIVE. Vous gérez ainsi plusieurs sites sur différents serveurs depuis une seule app locale, et vous voyez directement les données live comme les demandes de contact. Seuls les comptes, les tokens API et les connexions elles-mêmes restent locaux. L’aperçu des pages, les Pens et les adresses des Workflows pointent vers le serveur.
- Construire en local et synchroniser : essayer en local sans que les visiteurs n’en voient rien, puis téléverser sous Paramètres → Synchronisation (voir ci-dessus). Les données live sur le serveur sont alors conservées.
Versions : l’app d’admin provient toujours de votre instance locale. Lors du basculement (et à chaque chargement), elle vérifie que le serveur a la même version d’IllusionCMS. Si elle diffère ou si le serveur est injoignable, le sélecteur devient rouge au lieu de jaune, et une remarque indique les deux versions ; dans le menu de sélection, chaque connexion affiche sa version et, le cas échéant, un ⚠. Vous pouvez quand même travailler, mais certaines fonctions peuvent manquer ou échouer – le mieux est de mettre à jour les deux instances ensemble.
Le mode live convient aux corrections rapides, l’instance locale aux refontes plus importantes (nouveau layout, nombreuses modifications CSS) – les brouillons n’existent que pour les pages ; un fichier CSS ou un Snippet modifié s’applique immédiatement partout en production.
Serveur headless (sans admin)
Si vous ne gérez plus votre serveur en production que depuis l’app locale, vous n’y avez pas besoin d’admin. Sans admin, le serveur sert le site, l’API pour les tokens, les entrées HTTP des Workflows et les Pens publics – mais pas de /cms-admin, pas de connexion, pas de sessions et pas de gestion des comptes ni des tokens (tout renvoie 404). Cela réduit la surface d’attaque : il n’y a pas de page de connexion que quelqu’un pourrait tester à la chaîne.
Le plus simple – sans aucun compte utilisateur : au démarrage, définir un token maître et désactiver l’admin :
IC_MASTER_TOKEN=$(openssl rand -hex 32) # à noter – c’est le token pour la connexion
IC_HEADLESS=1
Le token maître vaut comme un token API avec droit d’écriture, mais ne figure dans aucune base de données et ne nécessite pas de compte (au moins 32 caractères, sinon le serveur ne démarre pas). En local, vous le saisissez sous Paramètres → Connexions. Dans l’historique, il apparaît comme auteur Master-Token. Il ne gère ni les comptes ni les tokens – cela reste réservé à l’admin. Il est bloqué dès que vous supprimez la variable et redémarrez.
Désactiver l’admin par un interrupteur : au lieu de IC_HEADLESS=1, c’est aussi possible sous Paramètres → Système → Désactiver l’admin – dans l’admin du serveur lui-même ou, plus confortablement, depuis votre app locale en mode distant. Ce n’est possible que s’il existe un token avec droit d’écriture (ou si un token maître est défini), afin que vous ne vous enfermiez pas dehors. Pour le réactiver : en mode distant sous Paramètres → Système, via l’API (PUT /api/v1/system) ou sur le serveur avec illusioncms -enable-admin. Issue de secours si plus aucun token n’est connu : définir IC_MASTER_TOKEN, redémarrer, se connecter avec et activer l’admin. Avec IC_HEADLESS=1, en revanche, l’admin est désactivé de façon fixe et l’interrupteur est bloqué.
Au lieu d’un token maître, un token API normal convient aussi : le créer sur le serveur sous Paramètres → Tokens API tant que l’admin tourne encore, ou en ligne de commande – dans le conteneur Docker, p. ex. docker exec <container> illusioncms -data /data -create-token "Lokales Admin".
Exporter en site statique
Un site peut être exporté intégralement sous forme de pages HTML statiques – pour un simple hébergement web avec Apache, sans qu’IllusionCMS doive y tourner. Dans l’éditeur de la page d’accueil, sous Paramètres → Site → Exporter en site statique :
- Vérifier l’export – rend toutes les pages et affiche un rapport : nombre de pages, fichiers et taille, pages avec des erreurs de template, liens internes morts et fichiers manquants.
- Télécharger le ZIP et décompresser son contenu dans le répertoire racine du domaine (p. ex.
htdocs/oupublic_html/).
Ce qu’il contient :
- Chaque page sous la forme
pfad/index.html–/leistungendevientleistungen/index.html. Apache redirige automatiquement/leistungenvers/leistungen/. - Les pages de détail derrière les pages Catch-All (articles de blog individuels) sont incluses si elles figurent dans le sitemap (Collections ou source du sitemap, p. ex. IllusionDB) ou si un lien y mène quelque part – p. ex. depuis la vue d’ensemble du blog.
robots.txtcomme dans le CMS.- La page 404 sous forme de
404.htmlet un.htaccessqui l’intègre (ErrorDocument 404 /404.html) – avec toutes les redirections du site. - Tous les fichiers CSS et JS,
sitemap.xml(pour le premier domaine du site ou l’URL de base indiquée) et les images utilisées avec leurs variantes srcset. Avec Inclure tous les fichiers de la médiathèque, le dossier des médias entier est inclus – nécessaire lorsque du JavaScript compose lui-même des URL d’images. - Les fichiers privés sont toujours exclus – même lorsque tous les fichiers de la médiathèque sont inclus –, avec leurs variantes et versions WebP ; le rapport indique leur nombre.
Limites : tout est un instantané au moment de l’export – les données REST, les Collections et les modifications ultérieures nécessitent un nouvel export. Les pages avec paramètres de requête (?seite=2) n’existent pas en statique, pas plus que les appels /api/v1 depuis JavaScript. L’export doit être placé dans le répertoire racine du domaine, pas dans un sous-dossier (les liens commencent par /).
Contrôle de santé
GET /healthz répond sans connexion avec 200 et {"status":"ok", …} tant que la base de données est accessible, sinon avec 503. Convient à la surveillance de disponibilité, au HEALTHCHECK de Docker ou aux répartiteurs de charge. La réponse contient en outre l’identifiant de build de l’app d’admin et le commit Git du binaire – pratique pour vérifier qu’une mise à jour tourne vraiment.
Derrière un reverse proxy (HTTPS)
IllusionCMS ne parle lui-même que HTTP. Pour HTTPS, placez un proxy devant, p. ex. Caddy (qui obtient les certificats automatiquement) :
www.firma.de, shop.firma.de {
reverse_proxy 127.0.0.1:8080
}
firma.de {
redir https://www.firma.de{uri}
}
Avec plusieurs sites, vous déclarez tous les domaines dans le proxy ; IllusionCMS choisit le site d’après le domaine appelé (en-tête Host, que Caddy transmet sans modification).
Démarrez ensuite le serveur avec -addr 127.0.0.1:8080 -secure-cookies. Le sitemap reprend le domaine et le schéma de X-Forwarded-Host/X-Forwarded-Proto, que Caddy définit automatiquement.
IllusionCMS peut envoyer lui-même des en-têtes de protection comme HSTS (En-têtes de sécurité). La redirection de http:// vers https:// devrait être permanente côté proxy (301 ou 308, par défaut avec Caddy). Avec Traefik, il faut pour cela permanent: true sur le middleware de redirection, sinon il redirige avec 302. Pour Coolify, des instructions figurent dans le paquet de déploiement (README.md, section Coolify).
IllusionCMS compresse lui-même les pages HTML, le CSS/JS et le sitemap (gzip). Une compression dans le proxy n’est donc pas nécessaire. Désactivez-la plutôt là-bas, sinon les images sont elles aussi recompressées inutilement.
En tant que service (systemd)
[Unit]
Description=IllusionCMS
After=network.target
[Service]
ExecStart=/opt/illusioncms/illusioncms -addr 127.0.0.1:8080 -data /var/lib/illusioncms -secure-cookies
Environment=SHOP_TOKEN=…
Restart=on-failure
User=illusioncms
[Install]
WantedBy=multi-user.target