Configurer une application pour Catena
Catena gère une application à partir d’étiquettes (labels) écrites dans son fichier compose : il publie l’adresse, place la barrière de connexion devant, sauvegarde les données, met l’application à jour et la surveille sur la page d’état. Dans ce guide, vous ajoutez une application depuis un dépôt, puis vous préparez le fichier compose propre à une application et le publiez dans un dépôt à vous. Une application qui passe par toutes les étapes est entièrement gérée.
Quand le logiciel figure au catalogue de Catena, l’entrée du catalogue est le chemin le plus court : ses étiquettes, ses réseaux, son placement et son client de connexion sont déjà en place, et vous l’ajoutez comme l’explique Ajouter une application depuis un dépôt.
Ajouter une application depuis un dépôt
Section intitulée « Ajouter une application depuis un dépôt »Les administrateurs ajoutent, configurent et suppriment les applications sous Gérer les applications, sous les tuiles de la page Applications. Chaque application vit dans son propre dossier sur le serveur : son fichier compose, un fichier de réglages et une note sur sa provenance. Le dossier figure dans chaque sauvegarde et fait tourner l’application sans Catena (voir Restaurer une application sur n’importe quelle machine).
Une application vient d’un dépôt git de la liste du serveur. Le catalogue de Catena figure d’emblée sur la liste et est de confiance. Pour ajouter une application :
- Ouvrez Applications et allez à Ajouter une application.
- Choisissez le Dépôt, saisissez le nom de l’Application et appuyez sur Afficher les versions.
- Choisissez une Version. La liste contient les dix plus récentes. Une version est une étiquette (tag) que le dépôt a publiée pour l’application.
- Au besoin, saisissez Nom sur ce serveur : lettres minuscules, chiffres et traits d’union. Sans nom, l’application garde le sien. Un nom qui est déjà un dossier ou une application du serveur est refusé.
- Appuyez sur Ajouter.
Catena récupère l’application à cette version, vérifie son fichier compose (voir Vérifier une application avec le panneau), écrit le dossier et le déploie. Un fichier qui comporte une erreur à la vérification est refusé et n’est pas conservé; les avertissements et les notes n’arrêtent pas le déploiement. La page indique alors “<application> a été ajoutée.” et la tuile de l’application apparaît dès que Catena l’a prise en compte, en quelques secondes. Un refus affiche la réponse du serveur sous l’avis.
Réglages, démarrage, arrêt et suppression
Section intitulée « Réglages, démarrage, arrêt et suppression »Chaque application a une fiche sous Gérer les applications :
- Réglages. Les valeurs que l’application vous laisse changer, chacune avec sa valeur par défaut. Saisissez les valeurs et appuyez sur Enregistrer les réglages : l’application est déployée de nouveau une seule fois avec toutes ces valeurs. Seules les valeurs que vous avez modifiées sont écrites, et une valeur qu’un autre administrateur a changée depuis l’ouverture de la page est refusée comme périmée. Une valeur sur plusieurs lignes est affichée mais n’est pas modifiable ici. Si cela échoue, la page indique “Les réglages ont été enregistrés, mais
<application>n’a pas redémarré avec eux. La démarrer de nouveau pour les appliquer.” Une application arrêtée prend les valeurs quand vous la démarrez. Une valeur secrète n’est jamais réaffichée : son champ indique “Une valeur est définie” ou “Aucune valeur définie”, et vous saisissez une nouvelle valeur dans son propre champ puis appuyez sur Enregistrer pour la remplacer. Les valeurs que Catena génère ou garde elle-même sont listées par nom et en lecture seule. Une valeur est stockée en texte brut; ni Docker ni un shell ne l’exécute comme une commande. - Démarrer et Arrêter. L’arrêt demande de cocher la case de confirmation et garde les données de l’application.
- Supprimer. Demande de cocher la case de confirmation. Cochez Supprimer aussi ses données (irréversible) pour supprimer aussi les données de l’application; sans cela, les données restent.
Un badge sur la fiche indique si l’application est toujours telle que Catena l’a déployée, et la fiche montre une mise à jour qui attend votre décision. Une application que vous avez modifiée à la main, ou par un autre gestionnaire de conteneurs, n’est pas mise à jour, et son badge le dit. Les badges, la liste Hors de Catena et les applications facultatives Portainer et Arcane du catalogue sont expliqués sous Applications modifiées hors de Catena.
Dépôts, sous Gérer les applications, liste les dépôts d’où vous pouvez ajouter des applications. Pour en ajouter un :
- Saisissez son Adresse du dépôt : une adresse
https://sans mot de passe, sans paramètres de requête et sans fragment. - Pour un dépôt privé, saisissez un Jeton d’accès. Il est enregistré sur le serveur et jamais réaffiché; la liste indique seulement “Jeton enregistré”. Pour le remplacer, saisissez-en un nouveau. Pour le supprimer, cochez Supprimer le jeton enregistré.
- Cochez De confiance : appliquer ses mises à jour d’elles-mêmes seulement pour un dépôt dont vous faites confiance à l’auteur. Les mises à jour d’un dépôt de confiance s’appliquent d’elles-mêmes à l’entretien nocturne; pour les autres, chaque mise à jour attend votre décision sur la fiche de l’application (voir Applications ajoutées depuis un dépôt).
- Appuyez sur Enregistrer le dépôt.
Enregistrer une adresse déjà sur la liste change sa confiance et son jeton. Retirer enlève un dépôt de la liste, avec son jeton; les applications déjà ajoutées depuis lui restent.
Un dépôt contient un dossier par application sous blueprints/, soit blueprints/<application>/docker-compose.yml avec les autres fichiers de l’application à côté, au plus 500 fichiers et 5 Mio, sans lien ni sous-module. Il publie chaque version sous forme d’étiquette écrite <application>/<version>-<révision>, comme my-app/1.2.3-1, où la version et la révision utilisent des lettres, des chiffres et les caractères ., _, + et -.
Catena lit les fichiers d’un dépôt comme des données et les vérifie avant de les déployer. Seul un fichier inchangé du catalogue de Catena peut donner à une application le réseau du serveur ou le moteur de conteneurs, lire des secrets stockés ou prendre des valeurs qu’une autre application fournit. Tout autre fichier qui les demande est refusé.
Ce qu’une application peut demander à Catena
Section intitulée « Ce qu’une application peut demander à Catena »Le bloc x-catena d’une application (voir Déclarer les réglages et Déclarer le mode de sauvegarde et les étapes de mise à jour) peut déclarer ce dont l’application a besoin du serveur. Catena y répond avant chaque déploiement : un certificat pour les noms de l’application et des enregistrements DNS dans les zones que le serveur sert. Un nom hors des domaines que le serveur sert est refusé, sauf si le fichier est un fichier inchangé du catalogue de Catena. Les étiquettes demandent la connexion (voir Connexion avec les comptes Catena), et le bloc peut tirer les utilisateurs d’une application d’un groupe de connexion.
Une application peut aussi fournir un service à d’autres applications, que celles qui l’utilisent trouvent d’elles-mêmes. Dès que l’application ClamAV du catalogue tourne, Nextcloud et le serveur de courriel sont déployés de nouveau une fois avec son adresse et analysent par son intermédiaire. Nextcloud se configure de la même façon pour l’éditeur OnlyOffice ou Collabora du catalogue. L’application de relais d’appels du catalogue fournit le relais qu’utilisent Nextcloud Talk et Element : l’ajouter les déploie de nouveau une fois avec son adresse et son secret, et la retirer les remet comme avant. Ajouter Talk ou Element n’ajoute jamais le relais, et le relais ne peut pas être ajouté avant que le serveur ait son domaine, parce qu’il a besoin d’un nom et d’un certificat. L’application de serveur de courriel fait publier par Catena son enregistrement d’adresse, son enregistrement MTA-STS et son enregistrement TLS-RPT; vous publiez vous-même ses enregistrements MX, SPF, DKIM et DMARC.
Comment Catena lit une application
Section intitulée « Comment Catena lit une application »Une application est un ensemble de services. L’un d’eux, le service d’entrée, répond aux requêtes web : le serveur web ou le serveur d’application. Les autres (base de données, cache, tâches de fond) sont internes et restent hors de portée d’Internet et des autres applications.
Vous écrivez les étiquettes sous la clé labels: propre à chaque service, en liste, une "clé=valeur" par ligne. La page d’état, les restaurations, les migrations et les mises à jour les lisent à cet endroit; les étiquettes placées sous deploy.labels leur échappent.
Un service qui porte vps.route.host a une adresse publique, et son port, qui peut entrer et son contrôle de santé sont lus sur ce service seulement. La plupart des applications ont une seule adresse, sur le service d’entrée. Une application peut en avoir plusieurs, comme un site public et une page d’administration servie par un autre service. Avec deux adresses ou plus, vous marquez l’adresse principale avec vps.route.main=true sur son service. Les étiquettes qui décrivent l’application dans son ensemble (sa tuile, son titre sur la page d’état, son entrée de connexion, vps.auth.protected) sont lues sur le service de l’adresse principale seulement, telles que l’application en cours d’exécution les a, et sont ignorées sur tout autre service. Avec une seule adresse, ce service est l’adresse principale et n’a pas besoin de marque. Quand une application a deux adresses ou plus et que aucune ou plusieurs sont marquées principales, l’application n’a aucune route.
L’accès se règle par adresse et n’est jamais hérité : une adresse sans étiquette d’accès n’admet que les administrateurs, même quand l’adresse principale est publique. Deux adresses ne peuvent pas partager un nom d’hôte : celle qui a été déployée en premier le garde, et l’autre n’a aucune route. La politique de mise à jour et les ports publiés décrivent un service en particulier, et chacun est facultatif. L’application à laquelle un service appartient est le nom de l’application sur le serveur, et le service est sa clé dans le fichier; Catena lit les deux dans Docker Swarm lui-même, aucune étiquette ne les nomme. La référence des étiquettes indique où va chacune.
La valeur d’une étiquette peut être une ${VARIABLE} des réglages de l’application (voir Déclarer les réglages) : Catena lit la valeur qu’a reçue le service déployé. Une étiquette vps.* que Catena ne reconnaît pas reste sans effet.
Le squelette ci-dessous contient chaque élément qu’ajoutent les étapes : un service d’entrée web et une base de données db.
services: web: image: example/web:1.2.3 deploy: placement: constraints: - node.labels.catena.role==data volumes: - web-data:/data cap_drop: - NET_RAW networks: - catena-network - default labels: - "vps.route.host=my-app.yourdomain.com" - "vps.route.port=8080" - "vps.auth.groups=staff" - "vps.health.path=/health"
db: image: postgres:1.2.3-alpine deploy: placement: constraints: - node.labels.catena.role==data environment: POSTGRES_USER: my-app POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - db-data:/var/lib/postgresql/data networks: - default
volumes: web-data: db-data:
networks: catena-network: external: trueÉtape 1 : Choisir le nom de l’application
Section intitulée « Étape 1 : Choisir le nom de l’application »Donnez à l’application un nom court fait de lettres minuscules, de chiffres et de traits d’union, comme my-app. C’est le nom de l’application sur le serveur, que vous donnez en ajoutant l’application (étape 7). Les restaurations, les migrations et les mises à jour trouvent l’application par ce nom, et le mandataire joint le service d’entrée à my-app_web : le nom de l’application, un trait de soulignement et la clé du service dans le fichier.
Étape 2 : Préparer le fichier pour Docker Swarm
Section intitulée « Étape 2 : Préparer le fichier pour Docker Swarm »Les applications tournent sur Docker Swarm, qui refuse certaines clés compose net et en ignore d’autres sans rien dire. Le catalogue est vérifié contre ces règles; quand vous écrivez un fichier à la main, vous les respectez vous-même.
- Politique de redémarrage. Swarm relance par défaut un service arrêté. N’écrivez
deploy.restart_policyque pour un service qui ne doit pas être relancé (condition: none) ou seulement après un échec (condition: on-failure), comme une tâche d’initialisation. - Placement des données. Chaque service qui monte un volume nommé ou un dossier de l’hôte porte la contrainte de placement
node.labels.catena.role==data. Un volume est local à un serveur : sur un autre, swarm le crée vide, sans erreur. - Pas de
depends_on. Swarm n’ordonne pas les démarrages et abandonne la clé sans message. Swarm relance un service parti trop tôt. Quand un plantage suivi d’un redémarrage fait des dégâts (un installateur qui s’arrête à moitié), l’entrypoint attend lui-même la base de données. - Pas de
configs:en ligne. La vérification refuse une entréefile:oucontent:(règle S4). L’entrypoint du service écrit plutôt le fichier de configuration. Seuls lesconfigsexternal: truesont acceptés. tmpfsen forme longue (type: tmpfs). La clé courte est ignorée en silence. Un montage tmpfs estnoexec; un chemin qui doit exécuter du code est un volume.- Ports publiés en forme longue avec
mode: host, qui conserve l’adresse réelle du client (le mode par défaut la remplace). L’étape 4 donne l’étiquette qui les ouvre dans le coupe-feu. - Clés refusées, qui font rejeter tout le fichier par swarm :
mem_limit,memswap_limit,cpus,cpu_shares,volumes_from,profiles,scale. Les limites vont dansdeploy.resources.limits, le nombre de répliques dansdeploy.replicas. - Clés ignorées, sans effet :
restart,container_name,expose,links,external_links,build,network_mode,security_opt,shm_size. Les images sont construites et publiées ailleurs; swarm ne fait que les télécharger. - Clés d’accès au serveur. Swarm abandonne aussi
privileged,pidetdevices: l’application tourne sans ce qu’elle demandait. La vérification d’application du panneau signaleprivileged: true,pid: hostetdevicescomme des erreurs (X1, X3, X5) : le fichier demande le contrôle du serveur. Le fichier corrigé garde la clé : vous décidez. - Pas d’accès réseau brut sur
catena-network. Docker donne à chaque conteneur le droit d’envoyer des paquets réseau bruts, ce qui permet à un conteneur decatena-networkde forger du trafic vers les services propres de Catena. Chaque service qui rejointcatena-networkportecap_drop: [NET_RAW]. Une application qui a besoin des paquets bruts (un analyseur de réseau, par exemple) ajoute plutôtcap_add: [NET_RAW]. La vérification d’application du panneau signale un service qui le garde (X11), et le fichier corrigé porte le retrait. Une application déjà déployée garde l’accès jusqu’à ce que vous publiiez le fichier corrigé comme nouvelle version. - Versions complètes. Chaque image porte une version complète, comme
1.2.3ou1.2.3-alpine. Seules celles-là sont mises à jour automatiquement :latest,stable,1.2ou1ne sont jamais modifiées.
Étape 3 : Raccorder le service d’entrée
Section intitulée « Étape 3 : Raccorder le service d’entrée »Le service d’entrée se joint au réseau externe catena-network et garde le réseau default de l’application pour joindre les services internes. Aucun alias n’est nécessaire. Les services internes restent sur default seulement. Le fichier déclare catena-network comme external: true (voir le squelette ci-dessus).
Le mandataire inverse joint le service d’entrée par ce réseau, et de même tout autre service qui a une adresse. Un service avec une adresse qui n’est pas sur catena-network n’a aucune route pour cette adresse. Un service interne sans entrée catena-network est inaccessible au mandataire et aux autres applications.
Étape 4 : Étiqueter le service d’entrée
Section intitulée « Étape 4 : Étiqueter le service d’entrée »Écrivez ces étiquettes sur le service d’entrée :
vps.route.hostavec l’adresse publique, commemy-app.yourdomain.com. Sans elle, l’application n’a ni route, ni tuile, ni carte sur la page d’état.vps.route.portavec le port d’écoute de l’application dans son conteneur, s’il n’est pas 80.- Qui peut entrer :
vps.auth.mode=publicpour une application ouverte à tous. La connexion propre à l’application, s’il y en a une, reste aux commandes.vps.auth.groupsavec les groupes Keycloak admis, pour une application privée. Une personne dans l’un d’eux entre.- Aucune des deux : seuls les administrateurs entrent.
vps.health.pathavec une adresse de l’application qui répond 200 quand l’application fonctionne, comme/health. Sans elle, la page d’état vérifie la page d’accueil de l’application : une application publique est en marche quand la page répond sans erreur, et une application derrière la connexion quand elle renvoie les visiteurs vers la connexion.- Au besoin, le nom, l’icône et la description de la tuile dans l’onglet Applications, et le titre de la carte sur la page d’état.
Les administrateurs entrent toujours. Aucune étiquette ne crée de groupe : les groupes existent déjà dans Keycloak, gérés dans sa console d’administration à auth.yourdomain.com ou dans le panneau Personnes avec Catena Pro (voir Connexion et personnes). La barrière décide qui atteint l’application, pas ce qu’une personne peut y faire : les rôles et permissions internes relèvent des réglages de l’application elle-même.
Un service qui publie un port pour un protocole autre que le web (courriel, relais TURN) porte aussi vps.expose.tcp ou vps.expose.udp avec ces ports, ce qui les ouvre dans le coupe-feu du serveur. Une étiquette n’ouvre jamais un port que le serveur déclare lui-même (SSH, ou un port réservé au serveur ou à votre réseau privé) : Catena ignore cette entrée et la consigne dans son journal.
services: relay: image: example/relay:1.2.3 ports: - target: 3478 published: 3478 protocol: udp mode: host labels: - "vps.expose.udp=3478"Une autre adresse (facultatif)
Section intitulée « Une autre adresse (facultatif) »Quand un autre service de l’application répond sur une adresse qui lui est propre, comme une page d’administration, donnez aussi des étiquettes à ce service :
- Sur le service d’entrée, ajoutez
vps.route.main=true. Elle marque l’adresse qu’ouvre la tuile et qui porte les étiquettes de l’application entière. - Sur l’autre service, ajoutez
vps.route.hostavec son adresse propre,vps.route.ports’il n’est pas 80, et son accès :vps.auth.mode=public, ouvps.auth.groupsavec les groupes admis. Sans l’un ni l’autre, seuls les administrateurs entrent, quoi que permette l’adresse principale. - Ajoutez-y
vps.health.pathquand sa page d’accueil ne convient pas comme contrôle. La page d’état affiche alors une carte par adresse. - Reliez aussi ce service à
catena-network(étape 3).
Laissez la tuile, le titre sur la page d’état, vps.auth.protected et les étiquettes de connexion sur le service d’entrée. Dans le fichier ci-dessous, web est public et admin admet le groupe staff :
services: web: image: example/web:1.2.3 cap_drop: - NET_RAW networks: - catena-network - default labels: - "vps.route.host=my-app.yourdomain.com" - "vps.route.main=true" - "vps.auth.mode=public" - "vps.health.path=/health" - "vps.display-name=My app"
admin: image: example/admin:1.2.3 cap_drop: - NET_RAW networks: - catena-network - default labels: - "vps.route.host=my-app-admin.yourdomain.com" - "vps.route.port=8080" - "vps.auth.groups=staff"
networks: catena-network: external: trueÉtape 5 : Régler la politique de mise à jour (facultatif)
Section intitulée « Étape 5 : Régler la politique de mise à jour (facultatif) »Par défaut, une image ne passe qu’aux nouvelles versions correctives. Un service qui doit avancer davantage, ou pas du tout, porte vps.auto-update (voir Mises à jour).
Rien d’autre ne s’étiquette par service. Un service dont l’image est une base de données ou un cache (PostgreSQL, PostGIS, TimescaleDB, MariaDB, MySQL, MongoDB, Redis, Valkey, KeyDB, Memcached, Elasticsearch, OpenSearch) est reconnu par son image et continue de tourner quand une migration met en pause le reste de l’application.
Étape 6 : Prévoir les données
Section intitulée « Étape 6 : Prévoir les données »- Les volumes nommés résident dans le dossier des volumes Docker et figurent dans chaque sauvegarde. Chaque volume est déclaré par son nom : les volumes anonymes sont aussi sauvegardés, mais une restauration d’une seule application ne les atteint pas.
- Les montages liés (bind) dans la zone des applications sont inclus. Un montage lié vers tout autre chemin absolu fait échouer la sauvegarde, sauf si vous inscrivez ce dossier sous Paramètres > Dépôt de sauvegarde > Autres dossiers à sauvegarder (séparés par des virgules). Voir Sauvegardes et stockage S3.
- Les bases de données sont copiées automatiquement avant chaque sauvegarde. C’est le nom de l’image qui décide, pas une étiquette :
- un conteneur en cours d’exécution dont le nom d’image contient
postgresest copié avecpg_dumpall, sous l’utilisateur dePOSTGRES_USER; - un conteneur dont le nom d’image contient
mariadboumysqlest copié, et exigeMARIADB_ROOT_PASSWORDouMYSQL_ROOT_PASSWORDdans son environnement; - une copie qui échoue fait échouer la sauvegarde.
- un conteneur en cours d’exécution dont le nom d’image contient
- Les autres moteurs (MongoDB, SQLite et semblables) n’ont aucune copie automatique. Vous avez besoin de l’exportation propre à l’application, ou d’une copie de volume cohérente en soi.
- Les grands ensembles de fichiers gagnent à vivre dans un stockage S3 plutôt que dans un volume local, ce qui garde la sauvegarde légère.
Une sauvegarde ne met pas en pause une application ajoutée à la main, sauf si le fichier déclare un mode de sauvegarde (voir Déclarer le mode de sauvegarde et les étapes de mise à jour) : sinon rien n’est placé en mode maintenance autour de l’instantané. Une entrée du catalogue peut le demander : Nextcloud, par exemple, est placé en mode maintenance pendant la sauvegarde de l’entretien nocturne et en est sorti ensuite, même quand la sauvegarde échoue.
Étape 7 : Publier et ajouter
Section intitulée « Étape 7 : Publier et ajouter »- Dans un dépôt git joignable en
https://, placez le fichier compose àblueprints/<application>/docker-compose.yml, où<application>est le nom de l’étape 1, avec les autres fichiers de l’application à côté. - Étiquetez la version
<application>/<version>-<révision>, commemy-app/1.2.3-1. - Sous Dépôts, sur la page Applications, enregistrez l’adresse du dépôt, avec un jeton d’accès s’il est privé (voir Dépôts).
- Sous Ajouter une application, choisissez le dépôt, saisissez
<application>, choisissez la version et appuyez sur Ajouter (voir Ajouter une application depuis un dépôt). - Saisissez les mots de passe et les clés comme réglages de l’application (voir Déclarer les réglages). Ils restent hors du fichier et vous pouvez les renouveler sans publier de nouvelle version.
Pour modifier l’application plus tard, publiez une nouvelle étiquette; l’application y passe comme l’explique Applications ajoutées depuis un dépôt.
Étape 8 : Vérifier
Section intitulée « Étape 8 : Vérifier »- Patientez quelques secondes : Catena prend le déploiement en compte d’elle-même, et revérifie chaque heure.
- Ouvrez l’adresse. Une application privée affiche d’abord la page de connexion; une application publique s’ouvre directement.
- La tuile de l’application figure dans l’onglet Applications, et sa carte sur la page d’état passe au vert.
Quand une vérification échoue, le tableau de dépannage énumère les causes habituelles. Pour repérer la plupart des erreurs avant de déployer, vérifiez le fichier avec le panneau.
Connexion avec les comptes Catena (facultatif)
Section intitulée « Connexion avec les comptes Catena (facultatif) »Une application qui prend en charge OpenID Connect peut laisser les gens se connecter avec leur compte Catena plutôt qu’avec un mot de passe distinct. Les étiquettes font créer à Catena l’entrée de connexion propre à l’application dans Keycloak et lui remettent son identifiant, son secret et son émetteur.
- Ajoutez ces étiquettes au service d’entrée :
vps.auth.oidc=true.vps.auth.oidc.redirect_urisavec l’adresse de rappel de l’application (sa documentation la nomme), commehttps://my-app.yourdomain.com/auth/callback. Séparez plusieurs adresses par des virgules.vps.auth.oidc.public=trueseulement pour une application qui ne peut pas garder de secret, comme une application de téléphone. L’entrée n’a alors aucun secret et exige PKCE.
- Dans le fichier compose, transmettez les trois valeurs à l’application sous les noms qu’elle attend, avec une valeur par défaut vide pour que le premier déploiement fonctionne :
${OIDC_CLIENT_ID:-},${OIDC_CLIENT_SECRET:-}(absente pour une application publique) et${OIDC_ISSUER_URL:-}. - Ajoutez l’application. Dans les minutes qui suivent, Catena crée l’entrée, écrit les trois valeurs dans les réglages de l’application et déploie de nouveau l’application quand elles changent. Keycloak génère le secret; Catena le copie.
Chaque adresse de retour est en https:// sur un domaine que ce serveur sert, ou le schéma propre d’une application de téléphone, comme app.immich:///oauth-callback. Un *, un http:// simple ou un # est refusé. Quand une étiquette est erronée, Catena ne crée ni ne modifie rien pour cette application.
Les personnes qui peuvent se connecter par le bouton propre à l’application suivent les groupes de l’application : les administrateurs seulement pour une application que seuls eux peuvent ouvrir, le personnel et les administrateurs quand les groupes dépassent admin, et tous les comptes quand client en fait partie. Une application publique sans vps.auth.groups admet le personnel et les administrateurs.
Catena ne modifie que les entrées qu’elle a créées. Une entrée de même nom que vous avez créée à la main n’est jamais reprise. Retirer les étiquettes, ou l’application, supprime l’entrée créée par Catena.
Pour vérifier que cela a fonctionné :
- Dans l’onglet Applications, un administrateur voit sur la tuile de l’application connexion prête, connexion en attente ou connexion en échec, avec la raison, à la place du badge OIDC. Le personnel voit le badge OIDC.
- En attente signifie que Catena réessaie d’elle-même. En échec signifie que quelque chose est à corriger, et la tuile dit quoi. L’onglet Journal nomme aussi l’application et la raison.
Voir Authentification unique pour le fonctionnement de la connexion entre applications.
Déclarer les réglages (facultatif)
Section intitulée « Déclarer les réglages (facultatif) »Les valeurs que le fichier d’une application lit sous la forme ${VARIABLE} viennent de son fichier de réglages. Déclarez chacune dans le bloc x-catena, avec schema: 2, comme l’un des deux :
- un réglage que vous changez sur la fiche de l’application, avec une valeur par défaut et une étiquette en anglais et en français;
- un secret généré que Catena produit au premier déploiement, avec sa longueur et son alphabet (
alnumouhex).
x-catena: schema: 2 env: APP_HOSTNAME: setting: default: my-app.yourdomain.com label: { en: "Address", fr: "Adresse" } DB_PASSWORD: generated: { length: 32, alphabet: alnum }Une variable qui n’est ni déclarée ni écrite par Catena, comme le sont les valeurs de connexion, se lit comme vide.
Déclarer le mode de sauvegarde et les étapes de mise à jour (facultatif)
Section intitulée « Déclarer le mode de sauvegarde et les étapes de mise à jour (facultatif) »Une application peut porter son propre mode de sauvegarde et ses propres étapes de mise à jour dans un bloc x-catena, au début de son fichier compose. Le dossier de l’application garde le fichier tel que Catena l’a déployé : le bloc voyage donc avec l’application, les sauvegardes et les restaurations le ramènent, et le serveur le lit dans ce fichier, pas dans le catalogue.
x-catena: schema: 1 quiesce: service: web pre: - ["pkill", "-STOP", "-x", "node"] post: - ["pkill", "-CONT", "-x", "node"] timeout_seconds: 10 lifecycle: service: web migrate: - ["yarn", "db:migrate"] versioned_volumes: ["web-data"] timeout_seconds: 900Commencez le bloc par schema: 1. Chaque commande est une liste de mots (["yarn", "db:migrate"]), exécutée avec docker exec dans le service nommé de l’application, sans interpréteur de commandes. Chaque section indique service et timeout_seconds; user est facultatif et nomme le compte sous lequel les commandes s’exécutent.
quiesceest le mode de sauvegarde. L’entretien nocturne exécute les commandespreavant la sauvegarde, par exemple pour placer l’application en mode maintenance, et les commandespostaprès, même quand la sauvegarde échoue. L’entretien nocturne exige Catena Pro ou Catena Business (voir Horaires).postdoit réussir même sipren’a jamais été exécutée. Chaque commande peut durer jusqu’à 60 secondes. Une commande encore en cours à la fin de son délai dispose d’autant de temps en plus, jusqu’à deux minutes, pour se terminer, puis elle est arrêtée, avant l’exécution de la commande suivante; une commande arrêtée est consignée dans l’onglet Journal.lifecyclecontient les étapes de mise à jour, chaque commande pouvant durer jusqu’à 3600 secondes :before_updates’exécute dans le conteneur en marche juste avant qu’une mise à jour déploie la nouvelle image, etafter_updateune fois la mise à jour réglée, qu’elle soit conservée ou annulée.migrates’exécute quand une mise à jour change l’image deservice, et après une restauration du serveur entier une fois les bases de données remises en place. Si elle échoue après une mise à jour, la mise à jour est annulée, image et base de données.versioned_volumesliste les volumes nommés de l’application que la nouvelle version transforme sur place et que la version précédente ne sait plus lire. Le serveur copie chacun avant une mise à jour qui changeserviceet remet la copie en place si la mise à jour est annulée. Un volume que monte une base de données ou un service qui ne s’exécute qu’une fois ne peut pas figurer dans la liste.
Les mises à jour elles-mêmes s’exécutent pendant l’entretien nocturne, qui exige Catena Pro ou Catena Business (voir Mises à jour).
Le serveur refuse les mises à jour de l’application quand le bloc ne tient pas pour son fichier. Les règles :
- Un
servicenomme un service que le fichier déclare. - Aucune valeur ne contient de
$: Docker le lit comme une variable quand il déploie le fichier. Écrivez les commandes sans$. - Aucune valeur ne nomme une image du fichier, car une mise à jour les réécrit.
- Un délai reste dans sa limite.
- Un format plus récent que celui que le serveur lit est refusé tant que le serveur n’est pas mis à jour.
Vérifiez le fichier avec le panneau avant de déployer : la règle K17 signale chacun de ces cas et liste les commandes que le bloc fait exécuter par le serveur.
Référence des étiquettes
Section intitulée « Référence des étiquettes »Chaque étiquette va sous la clé labels: propre au service.
Sur chaque service avec une adresse
Section intitulée « Sur chaque service avec une adresse »Sur chaque service qui porte vps.route.host : le service d’entrée et toute autre adresse. Chaque adresse lit les siennes.
| Étiquette | Valeurs | Défaut | Description |
|---|---|---|---|
vps.route.host |
Une adresse sous yourdomain.com |
aucun | Adresse publique. Le service qui la porte a une adresse de l’application. Sans elle sur aucun service, l’application n’a ni route, ni tuile, ni carte sur la page d’état. Deux adresses ne peuvent pas partager un nom d’hôte : celle déployée en premier le garde. |
vps.route.port |
Un numéro de port | 80 |
Port d’écoute du service dans son conteneur. |
vps.auth.mode |
public, private, admin-only |
aucun | public : aucune barrière. private : les groupes de vps.auth.groups, ou admin, client et staff quand aucun n’est listé. admin-only : administrateurs seulement. |
vps.auth.groups |
Noms de groupes Keycloak, séparés par des virgules | aucun | Groupes admis; une personne dans l’un d’eux entre. Ignorée avec public et admin-only. Le groupe visitor rend l’adresse publique. |
vps.health.path |
Un chemin d’URL | aucun | Adresse que la page d’état vérifie toutes les 2 minutes; l’adresse est en marche quand elle répond 200. Sans elle, la vérification lit la page d’accueil : une adresse publique est en marche quand elle répond sans erreur, une adresse derrière la connexion quand elle renvoie les visiteurs vers la connexion. |
vps.health.expect |
Texte | aucun | Texte que la réponse doit contenir. Sert seulement avec vps.health.path. |
Sans vps.auth.mode ni vps.auth.groups, seuls les administrateurs entrent. Cela vaut pour chaque adresse séparément : une adresse ne prend pas l’accès de l’adresse principale. Les administrateurs entrent toujours à une adresse privée.
Sur le service d’entrée, une seule fois
Section intitulée « Sur le service d’entrée, une seule fois »Sur le service de l’adresse principale seulement. Sur tout autre service, ces étiquettes sont ignorées.
| Étiquette | Valeurs | Défaut | Description |
|---|---|---|---|
vps.route.main |
true, false |
false |
Marque l’adresse principale. Nécessaire seulement quand l’application a deux adresses ou plus, sur un seul service exactement. Avec aucune ou plusieurs marquées, l’application n’a aucune route. |
vps.auth.protected |
true, false |
false |
true désigne une application qui ne doit pas être publique : si ses étiquettes la rendent publique quand même, sa tuile dans Applications porte le badge “devrait exiger une connexion”, visible des administrateurs seulement. |
vps.auth.oidc |
true, false |
false |
Catena crée l’entrée de connexion propre à l’application dans Keycloak et place OIDC_CLIENT_ID, OIDC_CLIENT_SECRET et OIDC_ISSUER_URL dans les réglages de l’application. Le personnel voit un badge OIDC sur la tuile; les administrateurs voient l’état de la connexion. |
vps.auth.oidc.redirect_uris |
Adresses, séparées par des virgules | aucun | Adresses de retour de l’entrée de connexion. Obligatoire avec vps.auth.oidc. Voir Connexion avec les comptes Catena. |
vps.auth.oidc.public |
true, false |
false |
true pour une application qui n’envoie aucun secret : l’entrée n’a aucun secret et exige PKCE. |
vps.display-name |
Texte | l’adresse principale | Titre de la carte de l’adresse principale sur la page d’état. Les cartes des autres adresses portent leur adresse pour titre. |
vps.homepage.name |
Texte | le nom de l’application sur le serveur | Titre de la tuile dans l’onglet Applications. |
vps.homepage.icon |
Un nom d’icône, ou l’adresse d’une image | mdi-application |
Icône de la tuile. Une adresse qui commence par http s’affiche comme image. |
vps.homepage.description |
Texte | aucun | Sous-titre de la tuile. |
vps.homepage.hidden |
true, false |
false |
Masque la tuile pour tous sauf les administrateurs. L’application reste joignable. |
Mises à jour
Section intitulée « Mises à jour »Sur n’importe quel service, facultatif, et lue sur le service qui la porte.
| Étiquette | Valeurs | Défaut | Description |
|---|---|---|---|
vps.auto-update |
off, patch, minor, patch+minor, major |
patch |
Jusqu’où la version de l’image peut avancer. patch garde les numéros majeur et mineur (1.2.3 vers 1.2.9). minor et patch+minor gardent le numéro majeur (1.2.3 vers 1.9.0). major accepte toute version plus récente (1.2.3 vers 2.0.0). off ne la change jamais. Une valeur invalide équivaut à patch. |
Seules les images dotées d’une version complète sont mises à jour. Les services qui exécutent la même image avancent ensemble, selon la plus restrictive de leurs étiquettes; un service sans étiquette compte comme patch. Les mises à jour s’exécutent pendant l’entretien nocturne, qui exige Catena Pro ou Catena Business (éditions); voir Mises à jour.
Ports publiés
Section intitulée « Ports publiés »Sur le service qui publie les ports.
| Étiquette | Valeurs | Défaut | Description |
|---|---|---|---|
vps.expose.tcp |
Ports ou plages, séparés par des virgules (25,465, 7000-7010) |
aucun | Ouvre ces ports TCP à Internet dans le coupe-feu du serveur. Le service les publie lui-même, en forme longue avec mode: host. Une application du catalogue à qui le réseau de l’hôte est accordé ne publie rien : ses étiquettes ouvrent les ports qu’elle écoute directement sur le serveur. Une entrée qui chevauche un port que le serveur déclare lui-même, ou une entrée invalide, est ignorée. |
vps.expose.udp |
Ports ou plages, séparés par des virgules | aucun | La même chose pour les ports UDP. |
Exemple complet : Nextcloud
Section intitulée « Exemple complet : Nextcloud »L’entrée du catalogue pour Nextcloud est la façon recommandée de l’exploiter : elle comporte plus de précautions que le fichier simplifié ci-dessous, et son client de connexion est déjà créé. Ajoutez l’entrée du catalogue et saisissez ses réglages de stockage : c’est toute la procédure, et Catena enregistre elle-même Keycloak dans Nextcloud. Le fichier ci-dessous montre la même conception avec les éléments dont une application écrite à la main a besoin, ajoutée sous le nom my-nextcloud; le mandataire joint app à my-nextcloud_app. Les versions d’images sont des valeurs fictives.
services: app: image: nextcloud:1.2.3-apache deploy: placement: constraints: - node.labels.catena.role==data entrypoint: - /bin/sh - -ec - | cat > /docker-entrypoint-hooks.d/before-starting/zz-catena.sh <<'HOOK' #!/bin/sh set -e php occ config:system:set --type int \ --value "$${NEXTCLOUD_MAX_CHUNK_SIZE}" files.chunked_upload.max_size HOOK chmod 0755 /docker-entrypoint-hooks.d/before-starting/zz-catena.sh wait_for_db() { php -r 'try { new PDO( "pgsql:host=".getenv("POSTGRES_HOST").";dbname=".getenv("POSTGRES_DB"), getenv("POSTGRES_USER"), getenv("POSTGRES_PASSWORD") ); } catch (Throwable $$e) { exit(1); } exit(0);' 2>/dev/null } waited=0 until wait_for_db; do waited=$$((waited + 2)) if [ "$$waited" -ge 300 ]; then echo "database did not answer in $${waited}s" >&2 exit 1 fi sleep 2 done exec /entrypoint.sh "$$@" - -- command: ["apache2-foreground"] environment: NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_HOSTNAME} NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER} NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD} NEXTCLOUD_MAX_CHUNK_SIZE: ${NEXTCLOUD_MAX_CHUNK_SIZE:-83886080} OVERWRITEPROTOCOL: https OVERWRITEHOST: ${NEXTCLOUD_HOSTNAME} OVERWRITECLIURL: https://${NEXTCLOUD_HOSTNAME} TRUSTED_PROXIES: 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 POSTGRES_HOST: db POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${DB_PASSWORD} REDIS_HOST: redis OBJECTSTORE_S3_BUCKET: ${S3_BUCKET} OBJECTSTORE_S3_REGION: ${S3_REGION} OBJECTSTORE_S3_HOST: ${S3_HOST} OBJECTSTORE_S3_PORT: ${S3_PORT:-443} OBJECTSTORE_S3_SSL: ${S3_SSL:-true} OBJECTSTORE_S3_USEPATH_STYLE: "true" OBJECTSTORE_S3_AUTOCREATE: "false" OBJECTSTORE_S3_KEY: ${S3_ACCESS_KEY} OBJECTSTORE_S3_SECRET: ${S3_SECRET_KEY} NEXTCLOUD_OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-} NEXTCLOUD_OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-} NEXTCLOUD_OIDC_ISSUER_URL: ${OIDC_ISSUER_URL:-} volumes: - nc-html:/var/www/html - nc-config:/var/www/html/config - nc-apps:/var/www/html/custom_apps - nc-data:/var/www/html/data labels: - "vps.route.host=nextcloud.yourdomain.com" - "vps.route.port=80" - "vps.auth.mode=public" - "vps.auth.oidc=true" - "vps.auth.oidc.redirect_uris=https://nextcloud.yourdomain.com/apps/user_oidc/code" - "vps.health.path=/status.php" - "vps.auto-update=patch" cap_drop: - NET_RAW networks: - catena-network - default
db: image: postgres:1.2.3-alpine deploy: placement: constraints: - node.labels.catena.role==data environment: POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${DB_PASSWORD} PGDATA: /var/lib/postgresql/data/pgdata volumes: - db-data:/var/lib/postgresql/data labels: - "vps.auto-update=patch" networks: - default
redis: image: redis:1.2.3-alpine labels: - "vps.auto-update=patch" networks: - default
cron: image: nextcloud:1.2.3-apache deploy: placement: constraints: - node.labels.catena.role==data entrypoint: - /bin/sh - -ec - | wait_for_db() { php -r 'try { new PDO( "pgsql:host=".getenv("POSTGRES_HOST").";dbname=".getenv("POSTGRES_DB"), getenv("POSTGRES_USER"), getenv("POSTGRES_PASSWORD") ); } catch (Throwable $$e) { exit(1); } exit(0);' 2>/dev/null } waited=0 until wait_for_db; do waited=$$((waited + 2)) if [ "$$waited" -ge 300 ]; then echo "database did not answer in $${waited}s" >&2 exit 1 fi sleep 2 done exec /cron.sh environment: POSTGRES_HOST: db POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${DB_PASSWORD} REDIS_HOST: redis OBJECTSTORE_S3_BUCKET: ${S3_BUCKET} OBJECTSTORE_S3_REGION: ${S3_REGION} OBJECTSTORE_S3_HOST: ${S3_HOST} OBJECTSTORE_S3_PORT: ${S3_PORT:-443} OBJECTSTORE_S3_SSL: ${S3_SSL:-true} OBJECTSTORE_S3_USEPATH_STYLE: "true" OBJECTSTORE_S3_KEY: ${S3_ACCESS_KEY} OBJECTSTORE_S3_SECRET: ${S3_SECRET_KEY} volumes: - nc-html:/var/www/html - nc-config:/var/www/html/config - nc-apps:/var/www/html/custom_apps - nc-data:/var/www/html/data networks: - default
volumes: nc-html: nc-config: nc-apps: nc-data: db-data:
networks: catena-network: external: trueVous déclarez les variables (NEXTCLOUD_HOSTNAME, NEXTCLOUD_ADMIN_USER, NEXTCLOUD_ADMIN_PASSWORD, DB_PASSWORD et les valeurs S3_*) comme réglages (voir Déclarer les réglages) et vous les saisissez sur la fiche de l’application. NEXTCLOUD_HOSTNAME vaut nextcloud.yourdomain.com. Catena remplit elle-même les valeurs OIDC_* (voir ci-dessous).
Pourquoi chaque élément
Section intitulée « Pourquoi chaque élément »- Stockage. Les fichiers des utilisateurs vont dans un seau S3 par les variables
OBJECTSTORE_S3_*. La sauvegarde ne contient alors que la base de données et les petits volumes locaux, et le seau est protégé par la durabilité de son propre fournisseur.nc-datacontient encore des journaux et des données applicatives : c’est donc un volume nommé.nc-htmlcontient l’arborescence du code : persistée, elle fait reconnaître un conteneur recréé comme une installation existante, qui est mise à niveau, plutôt que réinstallée par-dessus des données vivantes. - Placement.
app,dbetcronmontent des volumes : les trois sont épinglés au nœud de données.redisne conserve rien et n’a pas besoin d’épinglage : un cache manquant est simplement un cache raté. - Attente de la base de données au lieu de
depends_on. Une boucle de plantages et de redémarrages jusqu’à ce que la base réponde n’est pas sûre pour Nextcloud : l’installateur abandonne après dix essais, mais le fichier de version est alors déjà écrit, de sorte que le démarrage suivant prend la voie de la mise à niveau et l’instance reste “non installée” jusqu’à l’effacement du volume. L’entrypoint ouvre donc une vraie connexion à la base (et non un simple test TCP, car Postgres accepte les connexions pendant son démarrage) puis seulement passe la main à l’entrypoint de l’image. Après 300 secondes, il se termine pour que swarm relance la tâche. - Crochet de configuration. L’image ne remplit son dossier de configuration que s’il est vide : un fichier de configuration écrit avant le démarrage fait échouer le premier lancement. L’entrypoint écrit donc un crochet
before-startingque l’image exécute après avoir rempli le dossier.$$est l’échappement compose d’un$littéral. - Service cron. La même image exécute
/cron.shpour les tâches de fond. Il partage les quatre volumes avecapp, atterrit donc sur le même nœud, et attend la base de la même façon. - Domaines de confiance et mandataire. Le chiffrement TLS se termine en périphérie.
OVERWRITEPROTOCOL=https,OVERWRITEHOSTetOVERWRITECLIURLfont écrire des adresses https par Nextcloud,TRUSTED_PROXIEScouvre les plages privées qu’utilise le mandataire de Catena, etNEXTCLOUD_TRUSTED_DOMAINSest le nom d’hôte public. - Taille des morceaux. Cloudflare plafonne le corps d’une requête à 100 Mo sur ses forfaits Free et Pro. Le morceau de téléversement par défaut de Nextcloud est de 100 Mio, ce qui échoue en périphérie et est réessayé sans fin. 80 Mio (
83886080) laisse de la marge. La valeur 0 désactive le découpage et fait échouer tout téléversement de plus de 100 Mo. - Accès.
vps.auth.mode=publiclaisse la connexion propre à Nextcloud aux commandes, ce qui garde fonctionnels les liens de partage anonymes (/s/...) pour les gens sans compte. La connexion par Keycloak s’ajoute dans l’application (ci-dessous). - Santé.
vps.health.path=/status.phpvérifie la page qui dit que Nextcloud lui-même est en marche, au-delà de sa page d’accueil. - Sauvegardes. L’image du service
dbcontientpostgresetPOSTGRES_USERest défini : la base est donc copiée avant chaque sauvegarde.
Connexion avec OIDC
Section intitulée « Connexion avec OIDC »Dans l’application du catalogue, Catena crée le client Keycloak et enregistre elle-même le fournisseur dans Nextcloud.
Pour le fichier écrit à la main, les deux étiquettes vps.auth.oidc sur app font créer l’entrée de connexion à Catena et écrire OIDC_CLIENT_ID, OIDC_CLIENT_SECRET et OIDC_ISSUER_URL dans les réglages de l’application (voir Connexion avec les comptes Catena). L’adresse de retour des étiquettes est l’adresse de rappel de Nextcloud, https://nextcloud.yourdomain.com/apps/user_oidc/code. Quand la tuile de l’application affiche connexion prête, vous lisez les trois valeurs dans le fichier .env du dossier de l’application (voir Restaurer une application sur n’importe quelle machine), puis vous enregistrez le fournisseur dans Nextcloud avec occ, exécuté dans le conteneur app depuis l’interpréteur de commandes du serveur, l’identifiant et le secret remplaçant les deux valeurs fictives :
CT=$(docker ps -q -f label=com.docker.swarm.service.name=my-nextcloud_app | head -1)
docker exec --user 33 "$CT" php /var/www/html/occ app:enable user_oidc
docker exec --user 33 "$CT" php /var/www/html/occ user_oidc:provider keycloak \ --no-interaction \ --clientid="<client-id>" \ --clientsecret="<client-secret>" \ --discoveryuri="https://auth.yourdomain.com/realms/vps/.well-known/openid-configuration" \ --scope="openid email profile groups" \ --mapping-uid=preferred_username \ --mapping-display-name=name \ --mapping-email=email \ --mapping-groups=groups \ --group-provisioning=1La commande crée le fournisseur ou le met à jour : vous pouvez la répéter. La page de connexion de Nextcloud affiche alors Se connecter avec keycloak. Le compte administrateur local continue de fonctionner en secours.
Vérifier une application avec le panneau
Section intitulée « Vérifier une application avec le panneau »L’onglet Vérification d’application lit un fichier compose comme le liront Docker Swarm et votre serveur, avant que vous le déployiez. Seuls les administrateurs voient l’onglet; le personnel ne le voit pas.
- Ouvrez Vérification d’application.
- Dans Nom de l’application, saisissez le nom que vous donnerez à l’application (étape 1). Son adresse et ses ports ne comptent alors pas comme déjà pris par une autre application.
- Collez le fichier compose dans Fichier compose et sélectionnez Vérifier.
- Lisez les constats. Chacun porte son niveau (erreur, avertissement ou note), sa règle, le service concerné et ce qu’il faut changer. Ce que cela signifie ouvre la règle dans les listes ci-dessous.
- Quand des corrections automatiques s’appliquent, la page affiche le Fichier corrigé et les changements par rapport à votre fichier. Copiez-le dans le fichier de l’application, dans votre dépôt, et publiez une nouvelle version. Un constat marqué corrigé ci-dessous est déjà réglé dans ce fichier; tout autre est un choix que vous faites dans votre fichier.
Rien n’est déployé depuis cet onglet. La vérification compare votre fichier à ce que votre serveur détient : les adresses et les ports de ses autres applications, les domaines qu’il sert, les groupes avec lesquels on se connecte et les dossiers ajoutés à la sauvegarde. Une partie que le serveur ne peut pas lire est nommée sous les totaux, et les vérifications qui en dépendent sont omises.
Votre serveur vérifie aussi le fichier de chaque application de la page Applications toutes les heures et après chaque déploiement. Dans l’onglet Applications, un administrateur voit sur une tuile qui compte au moins une erreur ou un avertissement un lien comme Vérification : erreurs 1, avertissements 2. Les notes ne sont pas comptées. Le lien ouvre Vérification d’application avec les constats de cette application. Le serveur n’affiche pas le fichier déployé : collez le fichier compose de l’application pour voir le fichier corrigé. La tuile n’a pas de lien quand rien n’a été trouvé.
Un constat est une erreur quand le déploiement échoue, que des données sont perdues, que l’application est inaccessible ou qu’elle prend le contrôle du serveur. C’est un avertissement quand un réglage ne fait pas ce que dit le fichier. Une note est bonne à savoir.
Ce que Docker Swarm refuse ou ignore
Section intitulée « Ce que Docker Swarm refuse ou ignore »Ce que Catena lit dans le fichier
Section intitulée « Ce que Catena lit dans le fichier »| Règle | Niveau | Ce qu’elle signale |
|---|---|---|
| K1 | erreur | Un service qui a une adresse n’est pas sur catena-network, ou le fichier ne déclare pas ce réseau avec external: true : le mandataire ne peut pas le joindre. |
| K2 | erreur | Un service qui stocke des données dans un volume n’est pas épinglé au nœud de données. S’applique dès deux nœuds. |
| K3 | erreur | Plusieurs adresses sans exactement un vps.route.main=true, ou deux services avec la même adresse. |
| K4 | avertissement | Une étiquette de l’application entière sur un autre service que l’adresse principale, ou une étiquette d’adresse sur un service sans adresse : elle est ignorée. |
| K5 | avertissement | Une étiquette vps.* sous deploy.labels, où Catena ne la lit pas. |
| K6 | note | Une adresse publique sans vps.health.path. |
| K7 | avertissement | Une étiquette d’accès sans effet : un vps.auth.mode inconnu, vps.auth.groups sur une adresse publique ou réservée aux administrateurs, visitor à côté d’autres groupes, ou un groupe qui n’existe pas dans Keycloak. |
| K8 | note | Une étiquette d’image sans version complète, ou une valeur de vps.auto-update non valide. |
| K9 | erreur | Un montage de dossier hors de la zone des applications, absent de Autres dossiers à sauvegarder : la sauvegarde de nuit échoue. |
| K10 | avertissement | Le fichier correspond à une application du catalogue mais est déployé sous un autre nom : les actions du catalogue et les restaurations ne la trouvent pas. |
| K11 | note | Une étiquette vps.* que Catena ne lit pas, comme une qui nomme l’application ou le service. |
| K12 | avertissement | Un port publié qu’aucune étiquette vps.expose.tcp ou vps.expose.udp ne déclare (ouvert sur Internet), ou un port déclaré que le service ne publie pas avec mode: host. Une application du catalogue à qui le réseau de l’hôte est accordé ne publie rien et ne reçoit aucun avertissement pour ses ports déclarés. |
| K13 | note | Une base de données qui n’est pas exportée avant chaque sauvegarde : son volume est copié pendant qu’elle tourne. |
| K14 | erreur | Une adresse qu’une autre application détient déjà. |
| K15 | erreur | Une adresse qui n’est pas sous un domaine que sert votre serveur. |
| K16 | erreur | Un port qu’une autre application ouvre déjà sur votre serveur. |
| K17 | erreur, avertissement | Un bloc x-catena qui ne se lit pas ou ne tient pas pour son fichier (voir Déclarer le mode de sauvegarde et les étapes de mise à jour) : le serveur refuse les mises à jour de l’application. Un avertissement liste les commandes que le bloc fait exécuter par le serveur dans les conteneurs de l’application. |
Ce qui atteint le serveur
Section intitulée « Ce qui atteint le serveur »| Règle | Niveau | Ce qu’elle signale |
|---|---|---|
| X1 | erreur | privileged: true. |
| X2 | erreur | Le réseau propre du serveur (network_mode: host, ou le réseau externe host). Un fichier déployé tel quel depuis le catalogue de Catena dont le bloc le déclare passe. |
| X3 | erreur | pid: host, qui montre chaque processus du serveur. |
| X4 | erreur | ipc: host, qui atteint la mémoire partagée d’autres processus. |
| X5 | erreur | devices, qui atteint le matériel du serveur. |
| X6 | erreur | Le socket Docker monté dans le service, qui contrôle chaque conteneur. Un fichier déployé tel quel depuis le catalogue de Catena dont le bloc le déclare passe. |
| X7 | avertissement | cap_add : des capacités ajoutées. Ne gardez chacune que si l’application en a besoin. |
| X8 | avertissement | Un dossier du serveur monté hors de la zone des applications : l’application lit les fichiers du serveur. |
| X9 | avertissement | Un port publié sur le serveur, joignable depuis Internet sans connexion. |
| X10 | erreur | Des étiquettes Traefik, qui n’acheminent rien. Utilisez vps.route.host et vps.auth.mode ou vps.auth.groups. |
| X11 | avertissement | Un service de catena-network qui garde l’accès réseau brut, avec lequel il pourrait forger du trafic vers les services propres de Catena. Le fichier corrigé ajoute cap_drop: [NET_RAW]; une application qui a besoin de l’accès ajoute cap_add: [NET_RAW] (X7 le signale alors). |
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause et correction |
|---|---|
| 502 ou 503 sur l’adresse | Le mandataire ne joint pas l’application. Le service d’entrée est sur catena-network, et vps.route.port est son port d’écoute. Lisez les journaux du service avec docker service logs <application>_<service> sur le serveur. |
| 403 après la connexion | La personne n’est dans aucun groupe autorisé. Le groupe de vps.auth.groups existe dans Keycloak, correspond exactement (majuscules comprises), et la personne en est membre (Personnes ou Keycloak). |
| Seuls les administrateurs entrent | Ni vps.auth.mode ni vps.auth.groups n’est défini, ou le mode n’est pas public, private ou admin-only et aucun groupe n’est listé. |
| Pas de route, ou une adresse ou un accès erronés | Aucun vps.route.host, plusieurs adresses dont aucune ou deux sont marquées vps.route.main=true, ou service d’entrée qui n’est pas sur catena-network. Une étiquette de l’application entière sur un autre service que celui de l’adresse principale est ignorée. La synchronisation des routes s’exécute quelques secondes après un déploiement et toutes les heures. |
| Une adresse ne répond pas | Une autre adresse de ce serveur utilise déjà son nom d’hôte, ou son service n’est pas sur catena-network. La tuile indique à un administrateur quelle adresse et pourquoi. Donnez à l’adresse un nom d’hôte qui lui est propre, ou reliez son service à catena-network, puis publiez une nouvelle version et faites-y passer l’application. |
| Carte rouge sur la page d’état | Application publique dont la page d’accueil répond une erreur, application derrière la connexion qui ne renvoie pas les visiteurs vers la connexion, vps.health.path qui ne répond pas 200, ou texte vps.health.expect absent de la réponse. |
| La tuile indique connexion en échec ou connexion en attente | Lisez la raison sur la tuile. Une adresse de retour de vps.auth.oidc.redirect_uris doit être en https:// sur un domaine que ce serveur sert, sans * ni #. Corrigez l’étiquette dans votre dépôt, publiez une nouvelle version et faites-y passer l’application. |
| Sauvegarde échouée sur un montage lié | Le montage est hors de la zone des applications. Déplacez les données vers un volume nommé, ou inscrivez le dossier sous Paramètres > Dépôt de sauvegarde > Autres dossiers à sauvegarder (séparés par des virgules). |
| Sauvegarde échouée sur une base de données | La copie a échoué. Un conteneur MariaDB ou MySQL exige MARIADB_ROOT_PASSWORD ou MYSQL_ROOT_PASSWORD; un conteneur Postgres exige un POSTGRES_USER valide. |
| Mise à jour ignorée | L’étiquette d’image n’est pas une version complète (latest, 1.2), vps.auto-update vaut off, ou le saut dépasse l’étiquette (une version majeure sous patch). La version la plus récente peut aussi être retenue par les contrôles de vulnérabilités ou le délai d’attente, ou l’application est retenue parce qu’elle a été modifiée hors de Catena (voir Applications modifiées hors de Catena). |
| L’ajout d’une application est refusé | Le nom est déjà un dossier ou une application du serveur, la version n’est pas une étiquette de cette application dans le dépôt, le dépôt n’est pas sur la liste, ou le fichier compose comporte une erreur à la vérification (voir Vérifier une application avec le panneau). |
| Redémarrages en boucle au premier déploiement | Rien n’attend la base de données. L’entrypoint du service l’attend, comme dans l’exemple Nextcloud. |
| Données absentes après un changement de nœud | Un service avec volume n’avait pas node.labels.catena.role==data et a démarré sur un autre nœud avec un volume vide. |