Aller au contenu
Sylvain Joffraud l4w
Retour

Migrer Plausible vers Coolify v4 : 5 pièges en 30 min

Mis à jour le:

Mise à jour (2026-10-04) : ajout de la requête SQL qui vérifie la validation d’un serveur, de celle qui montre la clé SSH réellement associée, et du test de port à lancer depuis le conteneur coolify.

J’intègre srv-b (VPS prod) à Coolify (sur srv-a) pour tout piloter depuis une UI. Premier candidat : Plausible Analytics, jusqu’ici en docker-compose à la main dans /opt/plausible/ derrière Caddy. Sur le papier, 6 phases. En vrai, Coolify v4 m’attrape 5 fois en 30 min.

Piège 1 — Le user par défaut, c’est coolify

L’UI demande IP + port SSH + clé. Validate → Permission denied (publickey,password). Tu revérifies ta clé dans /root/.ssh/authorized_keys. Sauf que SELECT user FROM servers WHERE name='srv-b' renvoie coolify : le user suggéré par défaut, c’est coolify, pas root. La base répond plus vite que l’UI.

Piège 2 — La mauvaise clé SSH

Coolify nomme ses clés avec un slug aléatoire (dull-dotterel-t27..., yellowed-yacare-mxpw...). Tu génères une clé, la poses sur le serveur, puis dans le dropdown tu prends la mauvaise — les noms se ressemblent. Renomme tes clés coolify-to-<server> dès création. Pour voir ce qui est vraiment associé au serveur :

SELECT s.name, s.user, pk.name AS key_name
FROM servers s
LEFT JOIN private_keys pk ON pk.id = s.private_key_id
WHERE s.name = 'srv-b';

⚠️ C’est le conteneur coolify qui ouvre la connexion SSH, pas l’hôte. Un nc -zv lancé depuis srv-a ne prouve rien ; le test se fait depuis le conteneur :

sudo docker exec coolify nc -zv 10.8.0.10 2222

Piège 3 — Proxy: None n’existe pas vraiment

Je choisis Proxy: None pour valider le serveur sans que Coolify installe Traefik (Caddy occupe encore 80/443). Validate → erreur 500 : Proxy should not run. You selected the Custom Proxy. (CheckProxy.php:36).

validateDockerVersion() cascade sur CheckProxy::run() qui throw quand proxy.type=NONE. Mais en base, is_reachable et is_usable sont à t : l’event ServerValidated passe juste avant le throw, le serveur est validé. Cosmétique, on continue.

La requête qui tranche, une ligne par serveur :

sudo docker exec coolify-db psql -U coolify -d coolify -c \
  "SELECT s.name, s.ip, s.port, s.user, ss.is_reachable, ss.is_usable, s.proxy->>'type' AS proxy
   FROM servers s JOIN server_settings ss ON ss.server_id = s.id;"

is_reachable et is_usable à t, plus le type de proxy voulu : le serveur est prêt à recevoir des ressources, erreur 500 ou pas.

Piège 4 — Pas d’onglet « Domains » pour un Docker Compose

Tu colles ton compose, tu cherches où mettre le FQDN pour Traefik. Pas d’onglet Domains, pas de champ. La réponse planquée dans la doc : une magic env var, format SERVICE_FQDN_<SERVICE_UPPERCASE>_<PORT> :

SERVICE_FQDN_PLAUSIBLE_8000=https://analytics.example.com

Coolify la détecte et auto-génère les labels Traefik (rule=Host(...), tls.certresolver=letsencrypt). Sans elle, le service tourne mais n’est routé vers rien : déploiement vert qui ne sert rien.

Piège 5 — coolify.serviceName ≠ com.docker.compose.service

Service compose plausible_db (underscore). Ton script filtre sur label=coolify.serviceName=plausible_db → introuvable. Inspect :

com.docker.compose.service: plausible_db   # underscore, comme le YAML
coolify.serviceName:        plausible-db   # tiret, mis par Coolify

Coolify substitue _ → - dans coolify.serviceName. Pour retrouver un container, filtre sur com.docker.compose.service — le label standard Compose qui matche le YAML.

TL;DR

Le fil rouge des 5 : l’UI Coolify ment plus que la base Postgres. User par défaut, validation serveur, labels réels — un SELECT ou un docker inspect te sort du doute plus vite que l’UI.

Questions fréquentes

Pourquoi Coolify renvoie Permission denied (publickey,password) alors que ma clé SSH est bien sur le serveur ?
Parce que Coolify v4 propose coolify comme utilisateur SSH par défaut, pas root. Même si votre clé est dans /root/.ssh/authorized_keys, la connexion échoue si le champ user est resté sur coolify. Vérifiez l’utilisateur configuré (en base : SELECT user FROM servers WHERE name=…) et mettez celui qui possède réellement la clé.
Mon service Docker Compose se déploie en vert dans Coolify mais le domaine ne répond pas, pourquoi ?
Pour un Docker Compose, Coolify n’affiche pas d’onglet Domains : le routage Traefik se déclare via une magic env var au format SERVICE_FQDN__, par exemple SERVICE_FQDN_PLAUSIBLE_8000=https://analytics.example.com. Sans elle, Coolify ne génère pas les labels Traefik (rule=Host(...), tls.certresolver=letsencrypt) et le conteneur tourne sans être routé.
Coolify lève une erreur 500 « Proxy should not run » quand je valide un serveur en Proxy None, est-ce bloquant ?
Non, c’est cosmétique. validateDockerVersion() appelle CheckProxy::run() qui throw quand proxy.type=NONE (CheckProxy.php:36), mais l’event ServerValidated passe juste avant le throw. En base, is_reachable et is_usable sont déjà à t : le serveur est bel et bien validé, vous pouvez continuer.
Pourquoi mon filtre Docker sur label coolify.serviceName ne trouve pas mon conteneur Plausible ?
Parce que Coolify substitue les underscores par des tirets dans coolify.serviceName : un service compose plausible_db devient plausible-db. Pour retrouver le conteneur de façon fiable, filtrez plutôt sur com.docker.compose.service, le label standard de Compose qui correspond exactement au nom du YAML.
Comment vérifier dans la base qu’un serveur Coolify est vraiment validé ?
Interroger la base PostgreSQL de Coolify avec docker exec coolify-db psql -U coolify -d coolify, puis joindre servers et server_settings sur server_id. Le serveur est prêt quand is_reachable et is_usable valent t et que proxy->>'type' correspond au proxy choisi, même si l’interface a affiché une erreur à la validation.

Partager cet article :

Article précédent
Survente : verrouiller la jauge avec SELECT … FOR UPDATE
Article suivant
Deux VPN sur le même /24 : le full-tunnel éclipse ton mesh