Aller au contenu

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.

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 :

  1. Ouvrez Applications et allez à Ajouter une application.
  2. Choisissez le Dépôt, saisissez le nom de l’Application et appuyez sur Afficher les versions.
  3. 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.
  4. 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é.
  5. 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.

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 :

  1. Saisissez son Adresse du dépôt : une adresse https:// sans mot de passe, sans paramètres de requête et sans fragment.
  2. 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é.
  3. 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).
  4. 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é.

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.

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

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.

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_policy que 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ée file: ou content: (règle S4). L’entrypoint du service écrit plutôt le fichier de configuration. Seuls les configs external: true sont acceptés.
  • tmpfs en forme longue (type: tmpfs). La clé courte est ignorée en silence. Un montage tmpfs est noexec; 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 dans deploy.resources.limits, le nombre de répliques dans deploy.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, pid et devices : l’application tourne sans ce qu’elle demandait. La vérification d’application du panneau signale privileged: true, pid: host et devices comme 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 de catena-network de forger du trafic vers les services propres de Catena. Chaque service qui rejoint catena-network porte cap_drop: [NET_RAW]. Une application qui a besoin des paquets bruts (un analyseur de réseau, par exemple) ajoute plutôt cap_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.3 ou 1.2.3-alpine. Seules celles-là sont mises à jour automatiquement : latest, stable, 1.2 ou 1 ne sont jamais modifiées.

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.

Écrivez ces étiquettes sur le service d’entrée :

  1. vps.route.host avec l’adresse publique, comme my-app.yourdomain.com. Sans elle, l’application n’a ni route, ni tuile, ni carte sur la page d’état.
  2. vps.route.port avec le port d’écoute de l’application dans son conteneur, s’il n’est pas 80.
  3. Qui peut entrer :
    • vps.auth.mode=public pour une application ouverte à tous. La connexion propre à l’application, s’il y en a une, reste aux commandes.
    • vps.auth.groups avec les groupes Keycloak admis, pour une application privée. Une personne dans l’un d’eux entre.
    • Aucune des deux : seuls les administrateurs entrent.
  4. vps.health.path avec 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.
  5. 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"

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 :

  1. 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.
  2. Sur l’autre service, ajoutez vps.route.host avec son adresse propre, vps.route.port s’il n’est pas 80, et son accès : vps.auth.mode=public, ou vps.auth.groups avec les groupes admis. Sans l’un ni l’autre, seuls les administrateurs entrent, quoi que permette l’adresse principale.
  3. Ajoutez-y vps.health.path quand sa page d’accueil ne convient pas comme contrôle. La page d’état affiche alors une carte par adresse.
  4. 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.

  • 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 postgres est copié avec pg_dumpall, sous l’utilisateur de POSTGRES_USER;
    • un conteneur dont le nom d’image contient mariadb ou mysql est copié, et exige MARIADB_ROOT_PASSWORD ou MYSQL_ROOT_PASSWORD dans son environnement;
    • une copie qui échoue fait échouer la sauvegarde.
  • 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.

  1. 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é.
  2. Étiquetez la version <application>/<version>-<révision>, comme my-app/1.2.3-1.
  3. 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).
  4. 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).
  5. 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.

  1. Patientez quelques secondes : Catena prend le déploiement en compte d’elle-même, et revérifie chaque heure.
  2. Ouvrez l’adresse. Une application privée affiche d’abord la page de connexion; une application publique s’ouvre directement.
  3. 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.

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.

  1. Ajoutez ces étiquettes au service d’entrée :
    • vps.auth.oidc=true.
    • vps.auth.oidc.redirect_uris avec l’adresse de rappel de l’application (sa documentation la nomme), comme https://my-app.yourdomain.com/auth/callback. Séparez plusieurs adresses par des virgules.
    • vps.auth.oidc.public=true seulement 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.
  2. 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:-}.
  3. 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.

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 (alnum ou hex).
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: 900

Commencez 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.

  • quiesce est le mode de sauvegarde. L’entretien nocturne exécute les commandes pre avant la sauvegarde, par exemple pour placer l’application en mode maintenance, et les commandes post après, même quand la sauvegarde échoue. L’entretien nocturne exige Catena Pro ou Catena Business (voir Horaires). post doit réussir même si pre n’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.
  • lifecycle contient les étapes de mise à jour, chaque commande pouvant durer jusqu’à 3600 secondes :
    • before_update s’exécute dans le conteneur en marche juste avant qu’une mise à jour déploie la nouvelle image, et after_update une fois la mise à jour réglée, qu’elle soit conservée ou annulée.
    • migrate s’exécute quand une mise à jour change l’image de service, 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_volumes liste 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 change service et 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 service nomme 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.

Chaque étiquette va sous la clé labels: propre au service.

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 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.

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.

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.

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: true

Vous 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).

  • 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-data contient encore des journaux et des données applicatives : c’est donc un volume nommé. nc-html contient 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, db et cron montent des volumes : les trois sont épinglés au nœud de données. redis ne 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-starting que 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.sh pour les tâches de fond. Il partage les quatre volumes avec app, 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, OVERWRITEHOST et OVERWRITECLIURL font écrire des adresses https par Nextcloud, TRUSTED_PROXIES couvre les plages privées qu’utilise le mandataire de Catena, et NEXTCLOUD_TRUSTED_DOMAINS est 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=public laisse 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.php vé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 db contient postgres et POSTGRES_USER est défini : la base est donc copiée avant chaque sauvegarde.

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 :

Fenêtre de terminal
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=1

La 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.

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.

  1. Ouvrez Vérification d’application.
  2. 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.
  3. Collez le fichier compose dans Fichier compose et sélectionnez Vérifier.
  4. 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.
  5. 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.

Règle Niveau Ce qu’elle signale
S0 erreur Le fichier n’est pas un YAML valide, n’est pas un fichier compose, n’a aucun service, ou a un service qui n’est pas une suite de clés.
S1 erreur Une clé qui fait refuser tout le fichier par Swarm : mem_limit, memswap_limit, cpus, cpu_shares, volumes_from, profiles, scale. Les limites vont dans deploy.resources.limits et le nombre de répliques dans deploy.replicas.
S2 avertissement Une clé que Swarm ignore, comme depends_on, restart, container_name, expose, links, external_links, build, network_mode, la forme courte de tmpfs ou quelques autres sans équivalent dans Swarm.
S3 erreur Un port publié par le maillage de routage, qui remplace l’adresse de chaque visiteur par une adresse interne. Utilisez la forme longue avec mode: host.
S4 erreur Une entrée configs dont le contenu vient d’un fichier ou d’un texte en ligne. Seuls les configs external: true sont acceptés.
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.
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).
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.