DOC
Accueil/ Projets/ VPS Hostinger - Stack ENGWE/ 06 - Coolify : plateforme de déploiement (PARCOURS RECOMMANDÉ)

06 - Coolify : plateforme de déploiement (PARCOURS RECOMMANDÉ)

Coolify est un « Vercel/Heroku maison » : une interface web unique pour déployer tes applis (depuis Git ou Docker), gérer les secrets, obtenir le HTTPS et les sous-domaines automatiquement, et installer des services en 1 clic (PostgreSQL, MongoDB, n8n, NocoDB, Open WebUI, Uptime Kuma…).

⚠️ Choisis UN seul point d'entrée. Coolify embarque son propre reverse proxy (Traefik) sur les ports 80/443. Il remplace Nginx Proxy Manager. Ne lance pas en même temps la stack docker-compose.yml (docs 03–04) : ce serait un conflit de ports. Coolify OU la stack NPM, pas les deux.

Prérequis : avoir terminé 01-serveur-initial.md (utilisateur non-root, SSH, UFW, swap). L'étape Docker (doc 02) est facultative ici : l'installeur Coolify installe Docker tout seul s'il manque.

🩹 Bloqué sur un message d'erreur précis ? 08-erreurs-connues.md recense déjà les erreurs rencontrées à chaque étape de ce guide avec leur fix exact.


1. Ouvrir les ports nécessaires (UFW + hPanel)

Coolify a besoin de 80 et 443 (déjà ouverts au doc 01) et de son port d'UI 8000 le temps de l'installation. On l'ouvrira puis on le refermera (accès par sous-domaine ensuite).

sudo ufw allow 8000/tcp comment 'Coolify UI (temporaire)'

⚠️ Ne t'arrête pas à UFW. Si un pare-feu hPanel (cloud, séparé d'UFW) est attaché à ton VPS, il doit aussi autoriser le port 8000 en TCP, sinon http://IP:8000 ne répondra jamais depuis ton PC même si UFW dit ALLOW. Vérifie hPanel → VPS → Firewall (détails : 01-serveur-initial.md §1bis). C'est la cause la plus fréquente d'un Coolify « injoignable ».

2. Installer Coolify

Connecté avec ton utilisateur sudo :

curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash

L'installeur met en place Docker (si absent), Traefik, la base interne de Coolify et démarre l'UI. Compte ~3-5 min.

2bis. ⚠️ Vérifier AVANT d'ouvrir le navigateur

L'install prend 3-5 min et redémarre des services : ne teste pas trop tôt. Sur le VPS, vérifie que tout tourne :

sudo docker ps                       # doit lister des conteneurs "coolify*" avec un statut "Up"
curl -I http://localhost:8000        # doit répondre "HTTP/1.1 200" (ou 30x), PAS de "Connection refused"
  • curl échoue en local (Connection refused) → Coolify n'est pas (encore) up. Regarde les logs : sudo docker logs coolify (ou relance l'installeur).

  • curl répond bien en local mais rien depuis ton PC → ce n'est pas Coolify le problème, c'est le réseau devant. Depuis PowerShell (PC) :

    Test-NetConnection -ComputerName IP_DU_VPS -Port 8000
    

    False → vérifie dans l'ordre : (1) hPanel → VPS → Firewall (port 8000 en TCP, voir §1), (2) sudo ufw status doit montrer 8000 ALLOW, (3) pas de VPN/proxy actif sur ton PC qui bloquerait le port.

3. Créer ton compte admin

Dans le navigateur :

http://IP_DU_VPS:8000

Utilise http:// (pas https://) et l'IP brute à ce stade - c'est normal et attendu, tu n'as pas encore besoin d'un nom de domaine pour cette étape. Si la page ne charge pas, essaie une fenêtre de navigation privée (extensions/cache Firefox) avant de suspecter autre chose, puis reviens au §2bis si ça persiste.

Le premier compte créé devient administrateur. Fais-le tout de suite (avant quiconque d'autre), avec un mot de passe fort.

Ensuite, dans Settings → Configuration, renseigne :

  • Instance's Domain / FQDN : https://coolify-it.engwe-france.fr (voir DNS §4),
  • ton email pour Let's Encrypt.

Coolify obtiendra alors son propre certificat. Tu pourras refermer le port 8000 :

sudo ufw delete allow 8000/tcp

et accéder à l'admin via https://coolify-it.engwe-france.fr.

3bis. ⚠️ Valider le serveur + démarrer le proxy (obligatoire)

Après la création du compte admin, Coolify affiche son serveur "localhost" (Servers → localhost) avec le message "You can't use this server until it is validated." - normal, rien ne se déploiera avant ça.

Le serveur "localhost" (celui où tourne Coolify lui-même) doit être connecté en root, pas en utilisateur non-root. Coolify pilote /data/coolify (proxy, clés internes, volumes de ses propres conteneurs) en supposant un accès root complet ; avec engwe-seer, ça échoue en cascade avec des Permission denied. Le script de bootstrap (doc 01, à jour) installe déjà ta clé pour root et autorise PermitRootLogin prohibit-password (par clé uniquement, jamais par mot de passe) - donc si tu es parti d'un VPS fraîchement bootstrappé avec la version courante du script, l'étape suivante est immédiate :

  1. Server → General : User = root, Port = 22, IP Address/Domain = l'IP publique du VPS. Save.
  2. Validate Server → doit passer "reachable and validated" (vert).
  3. Start Proxy.

(Si ton VPS a été bootstrappé avec une ancienne version du script qui désactivait complètement root, remonte à 01-serveur-initial.md et adapte /etc/ssh/sshd_config.d/99-hardening.conf + /root/.ssh/authorized_keys à la main avant de continuer.)

Deux pièges rencontrés en pratique à cette étape

A) Start Proxy échoue avec Unable to create a directory at /var/www/html/storage/app/ssh/keys. Ce chemin est à l'intérieur du conteneur Coolify (pas sur le VPS) : l'app Coolify tourne en interne avec un utilisateur non-root (www-data, UID 9999 sur la v4.1.2 - vérifie avec docker exec coolify id si ça diffère). Si /data/coolify/ssh a été remis en root:root (par ex. après un chown -R root:root /data/coolify trop large), corrige uniquement ce dossier :

sudo chown -R 9999:9999 /data/coolify/ssh

⚠️ Ne fais pas de chown -R sur tout /data/coolify - chaque sous-dossier peut appartenir à un UID différent selon le conteneur qui l'utilise (proxy = root, app Coolify = www-data/9999, bases de données = leur propre UID). Corrige uniquement le dossier nommé dans le message d'erreur, avec l'UID du conteneur concerné.

B) Start Proxy reste bloqué sur "Waiting for the process to start..." sans jamais aboutir. Vérifie si le conteneur existe vraiment :

docker ps -a | grep -i proxy

S'il n'existe pas du tout (pas même arrêté), le bouton n'a pas déclenché la commande - démarre-le toi-même en root :

cd /data/coolify/proxy
docker compose up -d

Puis rafraîchis la page Coolify : le badge doit passer à "Running" dès que le conteneur coolify-proxy est Up (healthy).

Cette exception "root" ne concerne QUE ce serveur "localhost" géré par Coolify - toi, tu continues de te connecter en SSH avec ton utilisateur non-root (ssh engwe-vps ou ton alias) pour toutes tes opérations manuelles ; le mot de passe root reste désactivé, seule la clé fonctionne.

4. Enregistrements DNS

Comme pour l'autre parcours, crée des A records <nom>-it → IP_DU_VPS. Coolify gère le SSL de chacun automatiquement (validation HTTP).

Type Nom (hôte) Service
A coolify-it Admin Coolify
A n8n-it n8n
A chat-it Open WebUI
A data-it NocoDB
A mongo-it Mongo Express
A uptime-it Uptime Kuma
A portainer-it Portainer (optionnel)
A api-it ton API FastAPI
A <ton-appli>-it une A record par appli que tu déploies

Astuce : si ton DNS supporte le wildcard A *-it ... non standard côté Shopify. Reste sur une A record par service - c'est le plus fiable.

5. Déployer les services en 1 clic

Un seul projet pour toute cette stack. Les ressources d'un même projet + environnement Coolify partagent un réseau Docker commun et se joignent entre elles par leur nom de service (postgres, litellm, mongo...). Des ressources dans des projets différents ne se voient pas directement. Or ici PostgreSQL/MongoDB sont partagés par n8n, NocoDB, Mongo Express, Open WebUI (via LiteLLM) - crée un seul projet (ex. ENGWE Infra) et mets-y tous les services ci-dessous. Réserve un projet séparé aux applis perso (§6) qui n'ont pas besoin d'accéder à ce Postgres/Mongo partagé.

Dans Coolify : Project → Add Resource → Services, puis choisis dans le catalogue. Pour chacun, tu définis un domaine (le sous-domaine -it) et Coolify s'occupe du conteneur + SSL.

Service à ajouter Domaine à mettre Notes
PostgreSQL (interne, pas de domaine) Base partagée. Coolify gère user/mot de passe + sauvegardes planifiées dans l'UI.
MongoDB (interne) Idem, base NoSQL.
n8n n8n-it.engwe-france.fr Relie-le à la PostgreSQL créée ci-dessus (variables DB_*).
NocoDB data-it.engwe-france.fr Métadonnées dans PostgreSQL.
Open WebUI chat-it.engwe-france.fr Branché sur OpenRouter + Claude direct - voir §5bis.
Mongo Express mongo-it.engwe-france.fr Pointe vers la MongoDB. Ajoute une auth.
Uptime Kuma uptime-it.engwe-france.fr Surveillance + alertes.

Secrets : chaque service a un onglet Environment Variables dans Coolify. Les valeurs marquées « secret » sont chiffrées et masquées. C'est là que vivent tes mots de passe/API keys - pas dans le code.

Portainer (optionnel, pour l'inspection fine de Docker) : ajoute-le aussi via le catalogue, domaine portainer-it.engwe-france.fr. Coolify couvre déjà 80 % de ce que fait Portainer ; ne l'ajoute que si tu veux le détail conteneur par conteneur.

5bis. Modèles d'Open WebUI : OpenRouter + Claude en direct

Objectif : accès à Claude + tous les modèles OpenRouter, plus Claude en direct sur ton compte Anthropic. Open WebUI accepte plusieurs connexions compatibles OpenAI.

  1. Déploie LiteLLM (la passerelle Claude→OpenAI) comme resource Coolify :

    • Add Resource → Application → Docker Image : ghcr.io/berriai/litellm:main-latest
    • Command : --config /app/config.yaml --port 4000
    • Pas de domaine public (usage interne seulement).
    • Environment Variables (secrets) :
      ANTHROPIC_API_KEY=sk-ant-...
      LITELLM_MASTER_KEY=<openssl rand -base64 24>
      # OPENROUTER_API_KEY=sk-or-v1-...  # seulement si tu routes AUSSI OpenRouter
      #                                   # via LiteLLM (bloc optionnel du config.yaml).
      #                                   # Sinon, OpenRouter se branche en direct (§ ci-dessous).
      
    • Monte un fichier config.yaml (contenu fourni : docker/litellm/config.yaml) via Storages → mount vers /app/config.yaml.
  2. Configure Open WebUI (resource déjà déployée). Deux méthodes :

    Méthode simple (variables d'env) - dans Open WebUI → Environment Variables :

    OPENAI_API_BASE_URLS=https://openrouter.ai/api/v1;http://litellm:4000/v1
    OPENAI_API_KEYS=sk-or-v1-...;<LITELLM_MASTER_KEY>
    

    (les deux listes séparées par ;, dans le même ordre)

    Méthode UI - dans Open WebUI → Admin → Settings → Connections, ajoute deux connexions OpenAI :

    • https://openrouter.ai/api/v1 + ta clé OpenRouter
    • http://litellm:4000/v1 + ta LITELLM_MASTER_KEY
  3. Redéploie Open WebUI. Le sélecteur montrera les modèles OpenRouter (dont anthropic/claude-*) et les Claude directs (claude-opus-4-8, etc.).

📄 OpenRouter expose des centaines de modèles - pour limiter la liste, définir un modèle par défaut, gérer l'accès par groupe et plafonner les coûts : 07-openwebui-modeles.md.

⚠️ Pour que http://litellm:4000 soit joignable depuis Open WebUI, mets les deux resources dans le même projet/réseau Coolify (Coolify les place sur un réseau commun ; sinon utilise le nom de service exact affiché par Coolify).

6. Déployer TES applis (le déploiement que tu voulais)

C'est le cœur de Coolify. Deux sources possibles - les deux sont couvertes.

A) Depuis un dépôt Git (recommandé) - avec une ORGANISATION GitHub

Les projets vivent dans une organisation GitHub (pas un compte perso) : la connexion se fait via une GitHub App installée sur l'organisation.

  1. Coolify → Settings → Sources → Add → GitHub App.
  2. Dans l'écran de création, choisis ton organisation comme cible d'installation (menu déroulant « Organization » au moment d'installer l'app - pas ton compte perso).
  3. GitHub demande sur quels dépôts installer l'app : choisis All repositories (tout nouveau repo de l'org sera déployable) ou Only select repositories (plus strict - pense à ajouter chaque nouveau repo à l'app ensuite : GitHub → Organization → Settings → GitHub Apps).
  4. ⚠️ Selon les règles de ton organisation, l'installation d'une app peut nécessiter une approbation d'un owner de l'org (si tu n'es pas owner, la demande part en attente). Vérifie dans Organization → Settings → Third-party access.
  5. De retour dans Coolify : Project → Add Resource → Application → ta source GitHub App → choisis le repo de l'organisation.
  6. Coolify détecte automatiquement comment builder :
    • un Dockerfile s'il y en a un,
    • sinon Nixpacks (détection auto du langage : Python, Node, etc.),
    • ou un docker-compose.yml si l'appli en fournit un.
  7. Domain : <ton-appli>-it.engwe-france.fr → SSL automatique.
  8. Environment Variables : tes clés/secrets (API, DB, etc.), chiffrés.
  9. Health Check : l'URL qui doit répondre 200 (ex. /health) pour valider le déploiement. Si elle échoue, Coolify garde l'ancienne version en ligne (déploiement sans coupure).
  10. Deploy. Ensuite, chaque git push peut redéployer automatiquement (webhook créé par Coolify).

B) Depuis un Dockerfile ou une image déjà construite

Même écran, choisis Dockerfile ou Docker Image. Tu fournis l'image (registry) ou le Dockerfile, le domaine et les variables. Deploy.

Lancer les tests AVANT de déployer

Tu voulais « lancer les tests selon l'appli puis déployer ». Trois approches, de la plus simple à la plus robuste :

  1. Tests dans le build (le plus simple) : ajoute une étape de test dans ton Dockerfile (ex. RUN pytest / RUN npm test). Si les tests échouent, le build échoue → pas de déploiement. Zéro config côté Coolify.
  2. Pre-deployment command : dans l'application Coolify, champ Pre-deployment command, mets la commande de test/migration à exécuter avant la bascule.
  3. Gate CI (le plus pro) : GitHub Actions lance les tests à chaque push ; seulement s'ils passent, l'action appelle le webhook de déploiement Coolify de l'appli. Tu gardes ainsi un vrai pipeline test → deploy.

Résultat : Coolify EST ton « frontend qui déploie l'appli au bon endroit avec les clés » ; les tests conditionnent le déploiement via l'une des 3 méthodes.

Exemple concret : GitHub Actions → Coolify (méthode 3)

Comme tu déploieras principalement par GitHub, voici le pipeline recommandé. Dans l'appli Coolify : active Settings → Webhooks, copie l'URL de déploiement et le token. Mets-les dans GitHub → Secrets and variables → Actions : COOLIFY_WEBHOOK et COOLIFY_TOKEN.

Astuce organisation : définis COOLIFY_TOKEN comme secret d'organisation (Organization → Settings → Secrets and variables → Actions) - il sera partagé par tous les repos de l'org. Seul COOLIFY_WEBHOOK (propre à chaque appli) reste un secret du repo.

Puis crée .github/workflows/deploy.yml dans ton repo :

name: Test & Deploy
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.12" }
      - run: pip install -r requirements.txt
      - run: pytest # ← tes tests ; s'ils échouent, pas de deploy

  deploy:
    needs: test # ne se lance QUE si "test" est vert
    runs-on: ubuntu-latest
    steps:
      - name: Déclencher le déploiement Coolify
        run: |
          curl -fsSL -X GET "${{ secrets.COOLIFY_WEBHOOK }}" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}"

À chaque push sur main : GitHub lance les tests → s'ils passent, il appelle le webhook → Coolify build et déploie. Sinon, rien n'est déployé.

Alternative sans GitHub Actions : dans l'appli Coolify, active simplement Auto Deploy on push (Coolify crée le webhook GitHub tout seul). Dans ce cas, mets tes tests dans le Dockerfile (méthode 1) pour garder le garde-fou.

7. Sauvegardes & mises à jour

  • Bases : Coolify propose des backups planifiés par base (onglet Backups), avec destination locale ou S3.
  • Mise à jour de Coolify : Settings → Update (en 1 clic).
  • Mise à jour d'un service/appli : bouton Redeploy (récupère la dernière image / le dernier commit).

Voir aussi 05-maintenance-sauvegardes.md pour les principes généraux (copie hors-VPS des sauvegardes, surveillance RAM).


Vérifications de fin d'étape

  • https://coolify-it.engwe-france.fr s'ouvre (admin Coolify en HTTPS).
  • Un service du catalogue (ex. n8n) est accessible sur son sous-domaine en HTTPS.
  • Une appli test déployée depuis Git répond, et un git push la redéploie.

🎉 Tu as une plateforme de déploiement complète, en clics, avec HTTPS et secrets.


Dépannage - « Coolify ne répond pas du tout »

Dans l'ordre, du plus probable au moins probable :

  1. Pare-feu hPanel (le plus fréquent) - port 8000 (ou 443 une fois le domaine configuré) pas autorisé dans hPanel → VPS → Firewall. Voir §1 et 01-serveur-initial.md §1bis.
  2. Install pas terminée / échouée - sudo docker ps ne montre aucun conteneur coolify*, ou ils redémarrent en boucle. Relance : curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash puis regarde sudo docker logs coolify.
  3. UFW - sudo ufw status doit montrer 8000 ALLOW (ou 443 si tu es passé au domaine).
  4. Mauvais protocole/URL - http://IP:8000 (pas https, pas de /login collé à la fin, IP sans espace ni port en trop).
  5. Cache/extension navigateur - teste en fenêtre privée Firefox, ou un autre navigateur, avant d'aller plus loin.
  6. VPN/proxy sur ton PC - désactive-le le temps du test, certains bloquent les ports non-standard comme 8000.

Si rien ne marche et que tu veux repartir propre : c'est sans risque de réinitialiser le VPS depuis hPanel (réinstalle l'OS, supprime users/SSH/ Docker/Coolify) et de reprendre le guide depuis 01-serveur-initial.md. C'est même la méthode la plus rapide dès que l'état du serveur devient incertain - ne perds pas de temps à essayer de « réparer » un VPS à moitié configuré.

Dépannage - « Coolify répond, mais Validate Server / Start Proxy échoue »

Si l'UI charge mais que tu bloques après la création du compte admin, va directement au §3bis plus haut dans ce document : c'est presque toujours l'un de ces trois cas, dans l'ordre où ils apparaissent en pratique :

  1. Le serveur "localhost" est configuré avec ton utilisateur non-root au lieu de rootValidate Server échoue ou reste non "reachable".
  2. Start Proxy échoue avec Permission denied sur un chemin sous /data/coolify/ → mauvais UID sur ce dossier précis (ne jamais faire un chown -R global sur tout /data/coolify).
  3. Start Proxy reste bloqué sur "Waiting..." sans jamais créer de conteneur → démarre-le à la main avec docker compose up -d dans /data/coolify/proxy.