La documentation d’installation d’OpenShip indique un minimum de 2 cœurs de processeur, 2 Go de mémoire vive et 20 Go de stockage pour un serveur auto-hébergé (exigences officielles d’installation). Si votre tableau de bord affiche « déploiement terminé » mais que le domaine reste inaccessible, ne réinstallez pas immédiatement la plateforme : localisez d’abord la panne dans l’ordre construction locale, connexion SSH, démarrage du conteneur, routage du domaine, services dépendants.
Cette méthode évite de confondre un code mal configuré avec une machine trop faible, un transfert interrompu ou une base de données indisponible.
Cette page est destinée :
- aux développeurs qui utilisent OpenShip pour leur premier service ou leur première application SaaS ;
- aux techniciens qui maintiennent leur propre serveur et veulent réduire le temps passé à interpréter les journaux ;
- aux équipes qui lancent un déploiement depuis un Mac local, mais dont la machine manque de ressources ou ne peut pas rester connectée en permanence.
Commencez par établir la chronologie de l’incident
Avant toute modification, notez l’heure du lancement, le commit concerné, la version précédente encore fonctionnelle et le dernier message visible dans OpenShip. Le but n’est pas de collectionner des captures d’écran, mais de déterminer à quel moment la chaîne s’est interrompue.
Le chemin officiel décrit par OpenShip sépare notamment la connexion au dépôt ou au dossier, la construction de l’image, son transfert vers la cible par SSH, le démarrage du conteneur, puis le routage du domaine et du certificat. Cette séparation constitue votre première grille de tri.
| Symptôme observé | Couche probablement concernée | Première preuve à recueillir | Décision initiale |
|---|---|---|---|
| Le build s’arrête avant la création de l’image | Construction | Journal complet, commande, code de sortie | Corriger le projet ou vérifier les ressources locales |
| L’image est prête, mais aucun transfert n’aboutit | SSH ou réseau | Test de connexion détaillé, empreinte, port | Réparer l’accès sans élargir inutilement l’exposition |
| Le conteneur démarre puis s’arrête | Entrée, port, variables ou ressources | Journaux et état du conteneur | Corriger le processus avant de toucher au DNS |
| Le service répond localement, pas sur le domaine | DNS, certificat ou routage | Résolution publique, certificat, réponse HTTP | Modifier une seule couche de publication |
| L’application démarre, mais les fonctions métier échouent | Base de données ou autre service | État du service, réseau, connexion, volume | Sauvegarder puis distinguer code, identifiants et disponibilité |
Ne remplacez pas simultanément le domaine, le fichier d’environnement et la version du runtime. Vous perdriez la relation entre la modification et le résultat.
Isolez d’abord l’échec de construction
Un échec de build OpenShip ne se diagnostique pas à partir de la dernière ligne affichée. Demandez ou exportez le journal depuis la première commande d’installation jusqu’au code de sortie final. La documentation et le dépôt officiels montrent qu’OpenShip peut travailler à partir d’un dépôt Git ou d’un dossier local, puis produire un artefact avant l’envoi vers la cible (documentation du flux de déploiement).
Signaux à distinguer
- Dépendances : paquet introuvable, registre inaccessible, fichier de verrouillage incompatible.
- Compilation : erreur TypeScript, import absent, étape de bundling interrompue.
- Runtime : version de Node.js, Python ou autre moteur différente de celle attendue par le projet.
- Configuration : variable manquante, secret non injecté ou valeur présente uniquement sur votre Mac.
- Ressources locales : processus tué sans erreur applicative claire, mémoire saturée, disque temporaire plein ou machine qui suspend l’opération.
Votre projet doit rester la source de vérité pour les commandes de construction : package.json, Dockerfile, fichier de verrouillage, configuration de l’outil de compilation ou script de lancement. Ne remplacez pas une commande simplement parce qu’elle ressemble à celle d’un autre projet.
Prenez les preuves utiles
Utilisez des commandes qui conservent les informations sans exposer vos secrets :
git rev-parse HEAD
node --version
npm --version
df -h
env | sed 's/=.*$/=<masqué>/'
Pour un projet Python, remplacez les deux premières commandes par les vérifications adaptées à votre environnement. L’objectif est de comparer le runtime réellement utilisé avec celui déclaré par le projet, pas de supposer qu’une version récente est automatiquement compatible.
Si le journal contient un code de sortie non nul après une erreur de compilation explicite, corrigez d’abord le dépôt. Si le processus s’interrompt pendant une étape lourde sans erreur de code, examinez la mémoire, le stockage temporaire et la stabilité de la machine qui construit l’image. Cette distinction est essentielle : déplacer un projet mal configuré vers un serveur plus puissant ne le réparera pas.
Validez avant de relancer
Reproduisez la commande de build localement avec le même commit et les mêmes fichiers de configuration. Ensuite :
- confirmez que les dépendances s’installent sans interaction manuelle ;
- vérifiez que l’artefact attendu est réellement produit ;
- lancez le service avec les variables de test ;
- conservez le journal complet de cette exécution ;
- relancez OpenShip seulement après avoir identifié une différence vérifiable.
Si la construction échoue uniquement sur votre Mac, comparez la mémoire disponible, l’espace temporaire et la durée pendant laquelle la machine reste active. Si elle échoue avec le même message sur plusieurs environnements, la cause est probablement dans le projet ou sa configuration.
Séparez la connexion SSH du transfert d’image
Dans le flux OpenShip, le serveur cible peut être piloté à distance par SSH, tandis que la production de l’image reste effectuée sur la machine de contrôle ou dans l’environnement cloud choisi. Une erreur SSH ne signifie donc pas nécessairement que le projet ou le conteneur est défectueux.
| Type d’incident | Symptômes | Vérifications | Correction prudente |
|---|---|---|---|
| Première connexion impossible | Délai d’attente, refus de connexion, hôte inconnu | Adresse, port, route réseau, empreinte | Corriger la cible et documenter l’empreinte |
| Transfert interrompu | Connexion établie puis coupure pendant l’envoi | Stabilité réseau, espace disque, journal SSH | Reprendre après nettoyage contrôlé et test de capacité |
| Connexion réussie sans exécution | Authentification acceptée, commande refusée | Utilisateur, groupe Docker, shell, permissions | Accorder uniquement les droits nécessaires |
Commencez par un test détaillé avec des valeurs fictives :
ssh -vvv \
-p <PORT_SSH> \
-i <CHEMIN_CLE_PRIVEE> \
-o IdentitiesOnly=yes \
<UTILISATEUR>@<HOTE_CIBLE> \
'id && uname -a && docker version'
Le résultat doit vous donner quatre éléments : l’hôte réellement contacté, le port utilisé, l’empreinte présentée par le serveur et la commande distante qui échoue éventuellement. Les permissions de la clé privée doivent être restrictives :
chmod 600 <CHEMIN_CLE_PRIVEE>
Si la connexion interactive fonctionne mais que docker version échoue, vous avez probablement un problème d’autorisation du compte distant ou de contexte d’exécution. Si le réseau refuse le port, n’ouvrez pas plusieurs services « pour tester ». Autorisez uniquement le port SSH nécessaire, limitez les adresses sources lorsque c’est possible et gardez l’application derrière le routage prévu.
Pour un transfert interrompu, vérifiez d’abord l’espace disponible sur la cible :
df -h
docker system df
Ne supprimez pas indistinctement les images, les volumes ou les journaux. Identifiez les éléments inutilisés, confirmez qu’aucun retour arrière n’en dépend, puis nettoyez uniquement ce qui est documenté.
Stabilisez le conteneur avant de toucher au domaine
Un déploiement marqué comme réussi peut encore produire une application inutilisable. Le conteneur peut quitter immédiatement, écouter sur le mauvais port, répondre uniquement sur 127.0.0.1 ou échouer parce qu’une variable nécessaire manque.
Inspectez dans cet ordre :
docker ps -a --no-trunc
docker logs --tail=200 <NOM_CONTENEUR>
docker inspect <NOM_CONTENEUR>
La commande docker logs permet de récupérer la sortie standard et la sortie d’erreur du processus principal (documentation Docker sur les journaux des conteneurs). L’état du conteneur vous indique s’il est actif, arrêté ou redémarré. Un compteur de redémarrages élevé doit vous faire examiner le premier démarrage, non pas seulement le dernier.
Vérifiez ensuite quatre points :
- Commande d’entrée : le processus lancé existe-t-il réellement dans l’image ?
- Adresse d’écoute : l’application écoute-t-elle sur
0.0.0.0dans le conteneur plutôt que seulement sur localhost ? - Port : le port exposé et celui utilisé par l’application correspondent-ils ?
- Ressources : le processus est-il interrompu par un manque de mémoire, de disque ou de descripteurs ?
Un contrôle de santé ne remplace pas une requête réelle. Docker distingue l’état du processus et le résultat du mécanisme de santé (référence Docker sur les contrôles de santé). Une application peut donc être « en cours d’exécution » tout en renvoyant une erreur sur son endpoint principal.
Après correction, testez depuis le serveur :
curl -i http://127.0.0.1:<PORT_APPLICATION>/health
curl -i http://127.0.0.1:<PORT_APPLICATION>/
Puis testez le nom interne ou l’adresse du service depuis le réseau du conteneur. Cette étape permet de distinguer un problème d’écoute d’un problème de passerelle.
Gardez l’ancienne version ou son identifiant d’image tant que la nouvelle n’a pas répondu à une requête métier réelle. Une image qui démarre sans erreur n’est pas encore une version validée : testez une page, une route d’API et, si l’application manipule des fichiers audio, vidéo ou de design, une opération représentative de ces usages.
Traitez DNS, HTTPS et routage comme trois tests séparés
Lorsque l’application est accessible depuis le serveur mais pas depuis le domaine, ne modifiez pas immédiatement le certificat ou le conteneur. Vous devez établir une chaîne de preuves indépendante.
1. Résolution DNS
Depuis plusieurs réseaux ou résolveurs publics, vérifiez que le domaine pointe vers l’adresse attendue :
dig +short <DOMAINE_EXEMPLE>
dig @1.1.1.1 <DOMAINE_EXEMPLE> A
dig @8.8.8.8 <DOMAINE_EXEMPLE> A
Une ancienne adresse, un enregistrement AAAA non prévu ou un sous-domaine oublié peut envoyer une partie du trafic vers une machine différente. Comparez également le résultat avec l’adresse réellement associée au serveur cible.
2. Certificat
Inspectez le certificat présenté par le domaine :
openssl s_client \
-connect <DOMAINE_EXEMPLE>:443 \
-servername <DOMAINE_EXEMPLE> </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
OpenShip annonce la gestion du routage et des certificats TLS via son infrastructure de publication (installation et domaines personnalisés). Toutefois, une émission de certificat peut échouer si le DNS ne pointe pas vers la bonne cible, si le port nécessaire est filtré ou si un proxy intermédiaire modifie le parcours de validation. Les principes de validation des certificats sont détaillés dans la documentation de Let’s Encrypt sur les défis de validation.
3. Réponse HTTP
Enfin, vérifiez ce que reçoit réellement un client :
curl -I https://<DOMAINE_EXEMPLE>
curl -vk https://<DOMAINE_EXEMPLE>/
Interprétez les résultats séparément :
- aucun enregistrement DNS : problème de publication ;
- certificat pour un autre nom : problème de certificat ou de routage ;
- réponse
502ou504: la passerelle atteint mal le service ; - réponse
404: le domaine arrive probablement sur le mauvais projet ou la mauvaise route ; - réponse correcte en local mais pas publiquement : examinez l’écoute, le pare-feu et la passerelle.
Ne testez pas uniquement depuis le serveur. Un accès local réussi prouve seulement que le processus répond dans son propre environnement ; il ne prouve ni la résolution publique, ni l’ouverture du chemin entrant, ni la configuration HTTPS.
Rétablissez la base de données sans détruire les volumes
Une application peut démarrer sans parvenir à utiliser sa base. Les erreurs d’authentification, de réseau et de schéma se ressemblent parfois dans l’interface, mais leurs remèdes sont opposés.
Commencez par vérifier :
docker ps -a
docker logs --tail=200 <NOM_SERVICE_BDD>
docker volume ls
Puis contrôlez la chaîne de connexion, en masquant le mot de passe :
printf '%s\n' "$DATABASE_URL" \
| sed -E 's#(://[^:]+:)[^@]+@#\1<masqué>@#'
Classez ensuite l’incident :
- Erreur applicative : le client utilise une option ou un pilote incompatible.
- Erreur d’identifiants : l’utilisateur, le mot de passe ou la base ne correspondent pas à l’environnement.
- Service indisponible : la base est arrêtée, son réseau est isolé ou son nom d’hôte n’est pas résolu.
- Données ou schéma : la connexion fonctionne, mais une migration ou une table manque.
Avant toute restauration, sauvegardez le volume ou exportez les données selon le moteur utilisé. Docker documente le rôle des volumes persistants et leur gestion indépendante du cycle de vie d’un conteneur (documentation Docker sur les volumes). Supprimer un volume n’est donc pas une procédure de dépannage générale : c’est une opération potentiellement destructive.
Après correction, ne vous contentez pas d’un test de connexion. Exécutez une lecture puis une écriture de test dans un environnement approprié, vérifiez la persistance après redémarrage du conteneur et confirmez que l’application utilise bien la base de l’environnement attendu.
Si la base répond depuis son conteneur mais pas depuis l’application, vérifiez le réseau partagé, le nom de service et le port interne. Si la connexion atteint le serveur mais renvoie une erreur d’authentification, ne modifiez pas le pare-feu : corrigez les identifiants ou la variable injectée. Si le schéma est incomplet, appliquez la migration après sauvegarde et consignez son résultat.
Terminez par une recette d’acceptation et une décision de migration
La remise en ligne doit laisser une trace réutilisable par l’équipe. Une validation minimale doit contenir :
- le commit déployé et le journal complet du build ;
- le code de sortie et l’artefact produit ;
- l’état du conteneur après démarrage ;
- le résultat du contrôle de santé ;
- une réponse HTTP locale et une réponse via le domaine ;
- l’état du certificat HTTPS ;
- une lecture et une écriture de test dans la base ;
- l’identifiant de l’ancienne version ;
- un test de retour arrière, au moins sur un environnement de préproduction.
Continuez à corriger l’environnement actuel lorsque le journal montre une erreur déterministe du code, du port, d’une variable ou des identifiants. Envisagez un autre nœud de construction ou un environnement distant lorsque le build est interrompu par les ressources locales, lorsque votre Mac ne peut pas rester en ligne pendant tout le transfert ou lorsque plusieurs membres doivent reprendre le même processus avec des journaux persistants.
Ce choix ne signifie pas qu’OpenShip est en cause. Il faut corriger la couche qui échoue avant de changer d’architecture. Une migration précipitée peut déplacer le problème sans produire de meilleure preuve.
Modèle de preuve à réutiliser
Projet :
Commit :
Date et heure :
Couche concernée :
Symptôme :
Commande exécutée :
Première erreur reproductible :
Code de sortie :
Preuve réseau ou HTTP :
Correction appliquée :
Résultat après correction :
Version conservée pour retour arrière :
Responsable de la validation :
Si vos échecs proviennent du Mac local plutôt que du code, comparez honnêtement les deux options. Un poste local peut manquer de mémoire pendant un build, suspendre le transfert, changer de réseau ou disparaître lorsque son utilisateur ferme sa session. Un serveur classique peut, de son côté, imposer une administration système supplémentaire et ne pas correspondre à vos besoins pour l’audio, la vidéo ou les outils de design Apple. Dans ce cas précis, un Mac distant maintenu accessible offre un environnement plus constant pour construire, conserver les journaux et reprendre une livraison ; consultez les possibilités de location de Mac mini aux États-Unis avant de déplacer toute votre production. Ce n’est toutefois pas le meilleur choix pour une charge lourde permanente ou pour un projet qui exige des interfaces physiques locales.
Pour cadrer les conditions d’accès, les responsabilités et les limites d’un environnement distant, vous pouvez également consulter la présentation de Kvmkit et de ses services. L’objectif n’est pas de remplacer OpenShip par réflexe, mais de retirer le poste local de l’équation lorsque les preuves montrent qu’il est devenu le maillon instable.
FAQ
Quelle partie des journaux faut-il consulter en premier après un échec de build OpenShip ?
Commencez par le journal complet du build, depuis l’installation des dépendances jusqu’au code de sortie final. Relevez la commande réellement exécutée, la version du runtime, le premier message d’erreur et les variables attendues. Une ligne isolée peut être une conséquence ; le premier échec reproductible est généralement plus utile pour choisir entre correction du projet et changement de nœud de construction.
Que vérifier quand OpenShip ne parvient pas à se connecter au serveur en SSH ?
Séparez la panne en trois tests : résolution de l’adresse, négociation SSH et exécution distante. Vérifiez l’hôte, le port, la clé privée, ses permissions locales, l’empreinte du serveur et les droits du compte distant. Si la connexion interactive fonctionne mais qu’une commande échoue, le problème concerne probablement le shell non interactif, Docker ou les permissions du compte.
Pourquoi le domaine reste-t-il inaccessible alors qu’OpenShip indique que le déploiement est terminé ?
Un déploiement terminé confirme seulement qu’une version a été construite et lancée selon le flux prévu. Le domaine peut encore pointer vers une mauvaise adresse, attendre une propagation DNS, échouer lors de l’émission du certificat ou atteindre un mauvais routage. Testez séparément DNS public, certificat, réponse HTTP et accès local afin de ne modifier qu’une variable à la fois.
Comment arrêter les redémarrages répétés d’une application OpenShip ?
Comparez le journal de démarrage, l’état du conteneur et le résultat du contrôle de santé. Les causes fréquentes sont une commande d’entrée incorrecte, une application qui écoute uniquement sur localhost, un port différent de celui déclaré ou une variable absente. Conservez l’ancienne version, corrigez un seul paramètre, puis vérifiez une requête réelle avant de supprimer l’ancienne instance.
Comment récupérer une application OpenShip qui ne se connecte plus à sa base de données ?
Sauvegardez d’abord les données et inspectez l’état du service de base, le réseau privé, le nom d’hôte, le port et la chaîne de connexion. Distinguez une erreur d’authentification d’une indisponibilité du service ou d’un schéma incompatible. Ne supprimez pas le volume pour « réinitialiser » le problème : cette action peut détruire les données sans corriger la cause.
CI/CD sur Mac mini M4 — le plus simple
Xcode, Fastlane, CocoaPods, and SPM are first-class on macOS. Mac mini M4 unified memory keeps signing and archiving smooth; ~4W standby power suits 24/7 build nodes.